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