1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)sys_pipe.c	1.5 (2.11BSD GTE) 1997/2/7
   7:  */
   8: 
   9: #include "param.h"
  10: #include "systm.h"
  11: #include "user.h"
  12: #include "proc.h"
  13: #include "inode.h"
  14: #include "file.h"
  15: #include "fs.h"
  16: #include "mount.h"
  17: #include "uio.h"
  18: 
  19: extern  int ino_ioctl();
  20:     int pipe_rw(), pipe_select(), pipe_close();
  21:     struct  fileops pipeops =
  22:         { pipe_rw, ino_ioctl, pipe_select, pipe_close };
  23: 
  24: /*
  25:  * The sys-pipe entry.
  26:  * Allocate an inode on the root device.  Allocate 2
  27:  * file structures.  Put it all together with flags.
  28:  */
  29: pipe()
  30: {
  31:     register struct inode *ip;
  32:     register struct file *rf, *wf;
  33:     static struct mount *mp;
  34:     struct inode itmp;
  35:     int r;
  36: 
  37:     /*
  38: 	 * if pipedev not yet found, or not available, get it; if can't
  39: 	 * find it, use rootdev.  It would be cleaner to wander around
  40: 	 * and fix it so that this and getfs() only check m_dev OR
  41: 	 * m_inodp, but hopefully the mount table isn't scanned enough
  42: 	 * to make it a problem.  Besides, 4.3's is just as bad.  Basic
  43: 	 * fantasy is that if m_inodp is set, m_dev *will* be okay.
  44: 	 */
  45:     if (!mp || !mp->m_inodp || mp->m_dev != pipedev) {
  46:         for (mp = &mount[0];;++mp) {
  47:             if (mp == &mount[NMOUNT]) {
  48:                 mp = &mount[0];     /* use root */
  49:                 break;
  50:             }
  51:             if (mp->m_inodp == NULL || mp->m_dev != pipedev)
  52:                 continue;
  53:             break;
  54:         }
  55:         if (mp->m_filsys.fs_ronly) {
  56:             u.u_error = EROFS;
  57:             return;
  58:         }
  59:     }
  60:     itmp.i_fs = &mp->m_filsys;
  61:     itmp.i_dev = mp->m_dev;
  62:     ip = ialloc(&itmp);
  63:     if (ip == NULL)
  64:         return;
  65:     rf = falloc();
  66:     if (rf == NULL) {
  67:         iput(ip);
  68:         return;
  69:     }
  70:     r = u.u_r.r_val1;
  71:     wf = falloc();
  72:     if (wf == NULL) {
  73:         rf->f_count = 0;
  74:         u.u_ofile[r] = NULL;
  75:         iput(ip);
  76:         return;
  77:     }
  78:     u.u_r.r_val2 = u.u_r.r_val1;
  79:     u.u_r.r_val1 = r;
  80:     wf->f_flag = FWRITE;
  81:     rf->f_flag = FREAD;
  82:     rf->f_type = wf->f_type = DTYPE_PIPE;
  83:     rf->f_data = wf->f_data = (caddr_t)ip;
  84:     ip->i_count = 2;
  85:     ip->i_mode = IFREG;
  86:     ip->i_flag = IACC|IUPD|ICHG|IPIPE;
  87: }
  88: 
  89: pipe_rw(fp, uio, flag)
  90:     register struct file *fp;
  91:     register struct uio *uio;
  92:     int flag;
  93: {
  94: 
  95:     if (uio->uio_rw == UIO_READ)
  96:         return (readp(fp, uio, flag));
  97:     return (writep(fp, uio, flag));
  98: }
  99: 
 100: readp(fp, uio, flag)
 101:     register struct file *fp;
 102:     register struct uio *uio;
 103:     int flag;
 104: {
 105:     register struct inode *ip;
 106:     int error;
 107: 
 108:     ip = (struct inode *)fp->f_data;
 109: loop:
 110:     /* Very conservative locking. */
 111:     ILOCK(ip);
 112: 
 113:     /* If nothing in the pipe, wait (unless FNONBLOCK is set). */
 114:     if (ip->i_size == 0) {
 115:         /*
 116: 		 * If there are not both reader and writer active,
 117: 		 * return without satisfying read.
 118: 		 */
 119:         IUNLOCK(ip);
 120:         if (ip->i_count != 2)
 121:             return (0);
 122:         if (fp->f_flag & FNONBLOCK)
 123:             return (EWOULDBLOCK);
 124:         ip->i_mode |= IREAD;
 125:         sleep((caddr_t)ip+4, PPIPE);
 126:         goto loop;
 127:     }
 128: 
 129:     uio->uio_offset = fp->f_offset;
 130:     error = rwip(ip, uio, flag);
 131:     fp->f_offset = uio->uio_offset;
 132: 
 133:     /*
 134: 	 * If reader has caught up with writer, reset
 135: 	 * offset and size to 0.
 136: 	 */
 137:     if (fp->f_offset == ip->i_size) {
 138:         fp->f_offset = 0;
 139:         ip->i_size = 0;
 140:         if (ip->i_mode & IWRITE) {
 141:             ip->i_mode &= ~IWRITE;
 142:             wakeup((caddr_t)ip+2);
 143:         }
 144:         if (ip->i_wsel) {
 145:             selwakeup(ip->i_wsel, (long)(ip->i_flag & IWCOLL));
 146:             ip->i_wsel = 0;
 147:             ip->i_flag &= ~IWCOLL;
 148:         }
 149:     }
 150:     IUNLOCK(ip);
 151:     return (error);
 152: }
 153: 
 154: writep(fp, uio, flag)
 155:     struct file *fp;
 156:     register struct uio *uio;
 157:     int flag;
 158: {
 159:     register struct inode *ip;
 160:     register int c;
 161:     int error = 0;
 162: 
 163:     ip = (struct inode *)fp->f_data;
 164:     c = uio->uio_resid;
 165:     ILOCK(ip);
 166:     if ((fp->f_flag & FNONBLOCK) && ip->i_size + c >= MAXPIPSIZ) {
 167:         error = EWOULDBLOCK;
 168:         goto done;
 169:     }
 170: loop:
 171:     /* If all done, return. */
 172:     if (c == 0) {
 173:         uio->uio_resid = 0;
 174:         goto done;
 175:     }
 176: 
 177:     /*
 178: 	 * If there are not both read and write sides of the pipe active,
 179: 	 * return error and signal too.
 180: 	 */
 181:     if (ip->i_count != 2) {
 182:         psignal(u.u_procp, SIGPIPE);
 183:         error = EPIPE;
 184: done:       IUNLOCK(ip);
 185:         return (error);
 186:     }
 187: 
 188:     /*
 189: 	 * If the pipe is full, wait for reads to deplete
 190: 	 * and truncate it.
 191: 	 */
 192:     if (ip->i_size >= MAXPIPSIZ) {
 193:         ip->i_mode |= IWRITE;
 194:         IUNLOCK(ip);
 195:         sleep((caddr_t)ip+2, PPIPE);
 196:         ILOCK(ip);
 197:         goto loop;
 198:     }
 199: 
 200:     /*
 201: 	 * Write what is possible and loop back.
 202: 	 * If writing less than MAXPIPSIZ, it always goes.
 203: 	 * One can therefore get a file > MAXPIPSIZ if write
 204: 	 * sizes do not divide MAXPIPSIZ.
 205: 	 */
 206:     uio->uio_offset = ip->i_size;
 207:     uio->uio_resid = MIN((u_int)c, (u_int)MAXPIPSIZ);
 208:     c -= uio->uio_resid;
 209:     error = rwip(ip, uio, flag);
 210:     if (ip->i_mode&IREAD) {
 211:         ip->i_mode &= ~IREAD;
 212:         wakeup((caddr_t)ip+4);
 213:     }
 214:     if (ip->i_rsel) {
 215:         selwakeup(ip->i_rsel, (long)(ip->i_flag & IRCOLL));
 216:         ip->i_rsel = 0;
 217:         ip->i_flag &= ~IRCOLL;
 218:     }
 219:     goto loop;
 220: }
 221: 
 222: pipe_select(fp, which)
 223:     struct file *fp;
 224:     int which;
 225: {
 226:     register struct inode *ip = (struct inode *)fp->f_data;
 227:     register struct proc *p;
 228:     register int retval = 0;
 229:     extern int selwait;
 230: 
 231:     ILOCK(ip);
 232:     if (ip->i_count != 2)
 233:         retval = 1;
 234: 
 235:     else switch (which) {
 236:     case FREAD:
 237:         if (ip->i_size) {
 238:             retval = 1;
 239:             break;
 240:         }
 241:         if ((p = ip->i_rsel) && p->p_wchan == (caddr_t)&selwait)
 242:             ip->i_flag |= IRCOLL;
 243:         else
 244:             ip->i_rsel = u.u_procp;
 245:         break;
 246: 
 247:     case FWRITE:
 248:         if (ip->i_size < MAXPIPSIZ) {
 249:             retval = 1;
 250:             break;
 251:         }
 252:         if ((p = ip->i_wsel) && p->p_wchan == (caddr_t)&selwait)
 253:             ip->i_flag |= IWCOLL;
 254:         else
 255:             ip->i_wsel = u.u_procp;
 256:         break;
 257:     }
 258:     IUNLOCK(ip);
 259:     return(retval);
 260: }
 261: 
 262: /*
 263:  * This routine was pulled out of what used to be called 'ino_close'.  Doing
 264:  * so saved a test of the inode belonging to a pipe.   We know this is a pipe
 265:  * because the inode type was DTYPE_PIPE.  The dispatch in closef() can come
 266:  * directly here instead of the general inode close routine.
 267:  *
 268:  * This routine frees the inode by calling 'iput'.  The inode must be
 269:  * unlocked prior to calling this routine because an 'ilock' is done prior
 270:  * to the select wakeup processing.
 271: */
 272: 
 273: pipe_close(fp)
 274:     struct  file *fp;
 275:     {
 276:     register struct inode *ip = (struct inode *)fp->f_data;
 277: 
 278:     ilock(ip);
 279: #ifdef  DIAGNOSTIC
 280:     if  ((ip->i_flag & IPIPE) == 0)
 281:         panic("pipe_close !IPIPE");
 282: #endif
 283:     if  (ip->i_rsel)
 284:         {
 285:         selwakeup(ip->i_rsel, (long)(ip->i_flag & IRCOLL));
 286:         ip->i_rsel = 0;
 287:         ip->i_flag &= ~IRCOLL;
 288:         }
 289:     if  (ip->i_wsel)
 290:         {
 291:         selwakeup(ip->i_wsel, (long)(ip->i_flag & IWCOLL));
 292:         ip->i_wsel = 0;
 293:         ip->i_flag &= ~IWCOLL;
 294:         }
 295:     ip->i_mode &= ~(IREAD|IWRITE);
 296:     wakeup((caddr_t)ip+2);
 297:     wakeup((caddr_t)ip+4);
 298: 
 299: /*
 300:  * And finally decrement the reference count and (likely) release the inode.
 301:  */
 302:     iput(ip);
 303:     return(0);
 304:     }

Defined functions

pipe defined in line 29; used 2 times
pipe_close defined in line 273; used 2 times
pipe_rw defined in line 89; used 2 times
pipe_select defined in line 222; used 2 times
readp defined in line 100; used 1 times
  • in line 96
writep defined in line 154; used 1 times
  • in line 97

Defined variables

pipeops defined in line 21; used 1 times
Last modified: 1997-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3550
Valid CSS Valid XHTML 1.0 Strict