code:writep - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

7802

7803 /* Write call directed to a pipe.

7804  */

7805 writep(fp)

7806 {

7807     register *rp, *ip, c;

7808

7809     rp = fp;

7810     ip = rp->f_inode;

7811     c = u.u_count;
  • c ← 需要写的剩余字节数
7812 loop:

7813     /* If all done, return.

7814      */

7815     plock(ip);

  • ip 置锁
7816     if(c == 0) {

7817          prele(ip);

7818          u.u_count = 0;

7819          return;

7820     }

  • 若 写任务已经完成 (c == 0)
7821     /* If there are not both read and

7822      * write sides of the pipe active,

7823      * return error and signal too.

7824      */

7825     if(ip->i_count < 2) {

7826          prele(ip);

7827          u.u_error = EPIPE;

7828          psignal(u.u_procp, SIGPIPE);

7829          return;

7830     }

  • 若 读管道/写管道 不存在
7831     /* If the pipe is full,

7832      * wait for reads to delete

7833      * and truncate it.

7834      */

7835     if(ip->i_size1 == PIPSIZ) {

7836          ip->i_mode =| IWRITE;

7837          prele(ip);

7838          sleep(ip+1, PPIPE);

7839          goto loop;

7840     }

  • 若已写满(写足4096字节)
7841     /* Write what is possible and

7842      * loop back.

7843      */

7844     u.u_offset[0] = 0;

7845     u.u_offset[1] = ip->i_size1;

7846     u.u_count = min(c, PIPSIZ-u.u_offset[1]);

7847     c =- u.u_count;

7848     writei(ip);

7849     prele(ip);
  • 解锁ip
7850     if(ip->i_mode&IREAD) {

7851          ip->i_mode =& ~IREAD;

7852          wakeup(ip+2);

7853     }

  • 若有进程在等待 读管道,则唤醒该进程
7854     goto loop;

7855 }

7856 /* ------------------------- */

Ref

Caller

⚠️ **GitHub.com Fallback** ⚠️