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