# 2.11BSD#431 - /usr/src/sys/sys/sys_pipe.c

##### Functions

    pipe              X
    pipe_close        X
    pipe_rw           X
    pipe_select       X
    readp             X
    writep            X

##### Variables

    pipeops           X

       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

- in /usr/src/sys/sys/init_sysent.c line 69, 152

pipe_close defined in line 273; used 2 times

- in line 20-22(2)

pipe_rw defined in line 89; used 2 times

- in line 20-22(2)

pipe_select defined in line 222; used 2 times

- in line 20-22(2)

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

- in /usr/src/sys/sys/sys_generic.c line 34

Last modified: 1997-02-08 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1057 |