|
|
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.