|
|
1.1 ! root 1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/pipe.c,v 1.4 91/07/24 07:51:27 bin Exp Locker: bin $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * Pipes. ! 18: * ! 19: * $Log: pipe.c,v $ ! 20: * Revision 1.4 91/07/24 07:51:27 bin ! 21: * update prov by hal ! 22: * ! 23: * ! 24: * Revision 1.1 88/03/24 16:14:07 src ! 25: * Initial revision ! 26: * ! 27: * 86/11/19 Allan Cornish /usr/src/sys/coh/pipe.c ! 28: * Added check for non-blocking read and write if (io_flag & IPNDLY) set. ! 29: * Eliminated use of i_a inode field since now included in inode macros. ! 30: */ ! 31: #include <sys/coherent.h> ! 32: #include <errno.h> ! 33: #include <sys/filsys.h> ! 34: #include <sys/ino.h> ! 35: #include <sys/inode.h> ! 36: #include <sys/io.h> ! 37: #include <sys/proc.h> ! 38: #include <sys/sched.h> ! 39: #include <signal.h> ! 40: #include <sys/uproc.h> ! 41: ! 42: /* ! 43: * Create and return a locked pipe inode. This is called from the ! 44: * pipe system call. ! 45: */ ! 46: INODE * ! 47: pmake(mode) ! 48: { ! 49: register INODE *ip; ! 50: ! 51: if ((ip=ialloc(pipedev, IFPIPE|mode)) != NULL) { ! 52: iclear(ip); ! 53: ip->i_pnc = 0; ! 54: ip->i_prx = 0; ! 55: ip->i_pwx = 0; ! 56: } ! 57: return (ip); ! 58: } ! 59: ! 60: /* ! 61: * Open a pipe given the inode pointer. ! 62: */ ! 63: popen(ip, mode) ! 64: { ! 65: } ! 66: ! 67: /* ! 68: * Close a pipe inode. ! 69: */ ! 70: pclose(ip) ! 71: register INODE *ip; ! 72: { ! 73: if (ip->i_refc == 2) { ! 74: pevent(ip); ! 75: ip->i_flag |= IFEOF; ! 76: } ! 77: } ! 78: ! 79: /* ! 80: * Only one end of the pipe is going to be left. ! 81: */ ! 82: pevent(ip) ! 83: register INODE *ip; ! 84: { ! 85: if ((ip->i_flag&IFWFR) != 0) { ! 86: ip->i_flag &= ~IFWFR; ! 87: wakeup((char *)&ip->i_pwx); ! 88: } ! 89: if ((ip->i_flag&IFWFW) != 0) { ! 90: ip->i_flag &= ~IFWFW; ! 91: wakeup((char *)&ip->i_prx); ! 92: } ! 93: } ! 94: ! 95: /* ! 96: * Read from a pipe. The given inode is locked. ! 97: */ ! 98: pread(ip, iop) ! 99: register INODE *ip; ! 100: register IO *iop; ! 101: { ! 102: register unsigned n; ! 103: register unsigned ioc; ! 104: ! 105: while (ip->i_pnc == 0) { ! 106: ! 107: /* ! 108: * Logical End of File. ! 109: */ ! 110: if ((ip->i_flag&IFEOF) != 0) { ! 111: ip->i_flag &= ~IFEOF; ! 112: break; ! 113: } ! 114: ! 115: /* ! 116: * Nobody left to write. ! 117: */ ! 118: if (ip->i_nlink==0 && ip->i_refc<2) ! 119: break; ! 120: ! 121: /* ! 122: * Non-blocking read. ! 123: */ ! 124: if ( iop->io_flag & IONDLY ) { ! 125: u.u_error = EAGAIN; ! 126: return; ! 127: } ! 128: ! 129: /* ! 130: * Wait for pipe data. ! 131: */ ! 132: ip->i_flag |= IFWFW; ! 133: iunlock(ip); ! 134: sleep((char *)&ip->i_prx, CVPIPE, IVPIPE, SVPIPE); ! 135: ilock(ip); ! 136: } ! 137: ! 138: /* ! 139: * Clear EOF flag. ! 140: */ ! 141: if ((ip->i_flag&IFEOF)!=0 && ip->i_pnc==0) ! 142: ip->i_flag &= ~IFEOF; ! 143: ! 144: ioc = iop->io_ioc; ! 145: while (u.u_error==0 && ioc>0 && ip->i_pnc>0) { ! 146: ! 147: /* ! 148: * Calculate length of data to be read. ! 149: */ ! 150: if ((n=PIPSIZE-ip->i_prx) > ioc) ! 151: n = ioc; ! 152: if (n > ip->i_pnc) ! 153: n = ip->i_pnc; ! 154: ! 155: /* ! 156: * Read data. ! 157: */ ! 158: iop->io_ioc = n; ! 159: iop->io_seek = ip->i_prx; ! 160: fread(ip, iop); ! 161: n -= iop->io_ioc; ! 162: if ((ip->i_prx+=n) == PIPSIZE) ! 163: ip->i_prx = 0; ! 164: ip->i_pnc -= n; ! 165: ioc -= n; ! 166: } ! 167: iop->io_ioc = ioc; ! 168: ! 169: /* ! 170: * Wake processes waiting to write. ! 171: */ ! 172: if ((ip->i_flag&IFWFR)!=0 && ip->i_pnc<PIPSIZE) { ! 173: ip->i_flag &= ~IFWFR; ! 174: wakeup((char *)&ip->i_pwx); ! 175: } ! 176: } ! 177: ! 178: /* ! 179: * Write to a pipe. The given inode is locked. ! 180: */ ! 181: pwrite(ip, iop) ! 182: register INODE *ip; ! 183: register IO *iop; ! 184: { ! 185: register unsigned n; ! 186: register unsigned ioc; ! 187: ! 188: ioc = iop->io_ioc; ! 189: while (u.u_error==0 && ioc>0) { ! 190: ! 191: /* ! 192: * Nobody left to read. ! 193: */ ! 194: if ( (ip->i_refc < 2) && (ip->i_nlink == 0) ) { ! 195: u.u_error = EPIPE; ! 196: sendsig(SIGPIPE, SELF); ! 197: return; ! 198: } ! 199: ! 200: /* ! 201: * Calculate free space in pipe. ! 202: */ ! 203: if ( (n=PIPSIZE-ip->i_pwx) > ioc ) ! 204: n = ioc; ! 205: if (n > PIPSIZE-ip->i_pnc) ! 206: n = PIPSIZE - ip->i_pnc; ! 207: ! 208: /* ! 209: * Non-blocking write. ! 210: */ ! 211: if ( iop->io_flag & IONDLY ) { ! 212: if ( (n != ioc) || (ip->i_flag & IFEOF) ) { ! 213: u.u_error = EAGAIN; ! 214: return; ! 215: } ! 216: } ! 217: ! 218: /* ! 219: * Insufficent space or EOF still pending. ! 220: */ ! 221: if (n==0 || (ip->i_flag&IFEOF)!=0) { ! 222: ip->i_flag |= IFWFR; ! 223: iunlock(ip); ! 224: sleep((char *)&ip->i_pwx, CVPIPE, IVPIPE, SVPIPE); ! 225: ilock(ip); ! 226: continue; ! 227: } ! 228: iop->io_ioc = n; ! 229: iop->io_seek = ip->i_pwx; ! 230: fwrite(ip, iop); ! 231: n -= iop->io_ioc; ! 232: if ((ip->i_pwx+=n) == PIPSIZE) ! 233: ip->i_pwx = 0; ! 234: ip->i_pnc += n; ! 235: ioc -= n; ! 236: ! 237: /* ! 238: * Wait processes waiting to read. ! 239: */ ! 240: if ((ip->i_flag&IFWFW) && ip->i_pnc>0) { ! 241: ip->i_flag &= ~IFWFW; ! 242: wakeup((char *)&ip->i_prx); ! 243: } ! 244: } ! 245: iop->io_ioc = ioc; ! 246: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.