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