1: #
   2: /*
   3:  */
   4: 
   5: #include "../param.h"
   6: #include "../systm.h"
   7: #include "../user.h"
   8: #include "../inode.h"
   9: #include "../file.h"
  10: #include "../reg.h"
  11: 
  12: /*
  13:  * Max allowable buffering per pipe.
  14:  * This is also the max size of the
  15:  * file created to implement the pipe.
  16:  * If this size is bigger than 4096,
  17:  * pipes will be implemented in LARG
  18:  * files, which is probably not good.
  19:  */
  20: #define PIPSIZ  4096
  21: 
  22: /*
  23:  * The sys-pipe entry.
  24:  * Allocate an inode on the root device.
  25:  * Allocate 2 file structures.
  26:  * Put it all together with flags.
  27:  */
  28: pipe()
  29: {
  30:     register *ip, *rf, *wf;
  31:     int r;
  32: 
  33:     ip = ialloc(rootdev);
  34:     if(ip == NULL)
  35:         return;
  36:     rf = falloc();
  37:     if(rf == NULL) {
  38:         iput(ip);
  39:         return;
  40:     }
  41:     r = u.u_ar0[R0];
  42:     wf = falloc();
  43:     if(wf == NULL) {
  44:         rf->f_count = 0;
  45:         u.u_ofile[r] = NULL;
  46:         iput(ip);
  47:         return;
  48:     }
  49:     u.u_ar0[R1] = u.u_ar0[R0];
  50:     u.u_ar0[R0] = r;
  51:     wf->f_flag = FWRITE|FPIPE;
  52:     wf->f_inode = ip;
  53:     rf->f_flag = FREAD|FPIPE;
  54:     rf->f_inode = ip;
  55:     ip->i_count = 2;
  56:     ip->i_flag = IACC|IUPD;
  57:     ip->i_mode = IALLOC;
  58: }
  59: 
  60: /*
  61:  * Read call directed to a pipe.
  62:  */
  63: readp(fp)
  64: int *fp;
  65: {
  66:     register *rp, *ip;
  67: 
  68:     rp = fp;
  69:     ip = rp->f_inode;
  70: 
  71: loop:
  72:     /*
  73: 	 * Very conservative locking.
  74: 	 */
  75: 
  76:     plock(ip);
  77: 
  78:     /*
  79: 	 * If the head (read) has caught up with
  80: 	 * the tail (write), reset both to 0.
  81: 	 */
  82: 
  83:     if(rp->f_offset[1] == ip->i_size1) {
  84:         if(rp->f_offset[1] != 0) {
  85:             rp->f_offset[1] = 0;
  86:             ip->i_size1 = 0;
  87:             if(ip->i_mode&IWRITE) {
  88:                 ip->i_mode =& ~IWRITE;
  89:                 wakeup(ip+1);
  90:             }
  91:         }
  92: 
  93:         /*
  94: 		 * If there are not both reader and
  95: 		 * writer active, return without
  96: 		 * satisfying read.
  97: 		 */
  98: 
  99:         prele(ip);
 100:         if(ip->i_count < 2)
 101:             return;
 102:         ip->i_mode =| IREAD;
 103:         sleep(ip+2, PPIPE);
 104:         goto loop;
 105:     }
 106: 
 107:     /*
 108: 	 * Read and return
 109: 	 */
 110: 
 111:     u.u_offset[0] = 0;
 112:     u.u_offset[1] = rp->f_offset[1];
 113:     readi(ip);
 114:     rp->f_offset[1] = u.u_offset[1];
 115:     prele(ip);
 116: }
 117: 
 118: /*
 119:  * Write call directed to a pipe.
 120:  */
 121: writep(fp)
 122: {
 123:     register *rp, *ip, c;
 124: 
 125:     rp = fp;
 126:     ip = rp->f_inode;
 127:     c = u.u_count;
 128: 
 129: loop:
 130: 
 131:     /*
 132: 	 * If all done, return.
 133: 	 */
 134: 
 135:     plock(ip);
 136:     if(c == 0) {
 137:         prele(ip);
 138:         u.u_count = 0;
 139:         return;
 140:     }
 141: 
 142:     /*
 143: 	 * If there are not both read and
 144: 	 * write sides of the pipe active,
 145: 	 * return error and signal too.
 146: 	 */
 147: 
 148:     if(ip->i_count < 2) {
 149:         prele(ip);
 150:         u.u_error = EPIPE;
 151:         psignal(u.u_procp, SIGPIPE);
 152:         return;
 153:     }
 154: 
 155:     /*
 156: 	 * If the pipe is full,
 157: 	 * wait for reads to deplete
 158: 	 * and truncate it.
 159: 	 */
 160: 
 161:     if(ip->i_size1 == PIPSIZ) {
 162:         ip->i_mode =| IWRITE;
 163:         prele(ip);
 164:         sleep(ip+1, PPIPE);
 165:         goto loop;
 166:     }
 167: 
 168:     /*
 169: 	 * Write what is possible and
 170: 	 * loop back.
 171: 	 */
 172: 
 173:     u.u_offset[0] = 0;
 174:     u.u_offset[1] = ip->i_size1;
 175:     u.u_count = min(c, PIPSIZ-u.u_offset[1]);
 176:     c =- u.u_count;
 177:     writei(ip);
 178:     prele(ip);
 179:     if(ip->i_mode&IREAD) {
 180:         ip->i_mode =& ~IREAD;
 181:         wakeup(ip+2);
 182:     }
 183:     goto loop;
 184: }
 185: 
 186: /*
 187:  * Lock a pipe.
 188:  * If its already locked,
 189:  * set the WANT bit and sleep.
 190:  */
 191: plock(ip)
 192: int *ip;
 193: {
 194:     register *rp;
 195: 
 196:     rp = ip;
 197:     while(rp->i_flag&ILOCK) {
 198:         rp->i_flag =| IWANT;
 199:         sleep(rp, PPIPE);
 200:     }
 201:     rp->i_flag =| ILOCK;
 202: }
 203: 
 204: /*
 205:  * Unlock a pipe.
 206:  * If WANT bit is on,
 207:  * wakeup.
 208:  * This routine is also used
 209:  * to unlock inodes in general.
 210:  */
 211: prele(ip)
 212: int *ip;
 213: {
 214:     register *rp;
 215: 
 216:     rp = ip;
 217:     rp->i_flag =& ~ILOCK;
 218:     if(rp->i_flag&IWANT) {
 219:         rp->i_flag =& ~IWANT;
 220:         wakeup(rp);
 221:     }
 222: }

Defined functions

pipe defined in line 28; never used
plock defined in line 191; used 2 times
prele defined in line 211; used 13 times
readp defined in line 63; used 1 times
writep defined in line 121; used 1 times

Defined macros

PIPSIZ defined in line 20; used 2 times
Last modified: 1975-07-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1042
Valid CSS Valid XHTML 1.0 Strict