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

Defined functions

pipe defined in line 31; used 2 times
readp defined in line 83; used 1 times
writep defined in line 138; used 1 times

Defined macros

PIPSIZ defined in line 23; used 2 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 930
Valid CSS Valid XHTML 1.0 Strict