1: /*
2: * Copyright (c) 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)sys_pipe.c 1.5 (2.11BSD GTE) 1997/2/7
7: */
8:
9: #include "param.h"
10: #include "systm.h"
11: #include "user.h"
12: #include "proc.h"
13: #include "inode.h"
14: #include "file.h"
15: #include "fs.h"
16: #include "mount.h"
17: #include "uio.h"
18:
19: extern int ino_ioctl();
20: int pipe_rw(), pipe_select(), pipe_close();
21: struct fileops pipeops =
22: { pipe_rw, ino_ioctl, pipe_select, pipe_close };
23:
24: /*
25: * The sys-pipe entry.
26: * Allocate an inode on the root device. Allocate 2
27: * file structures. Put it all together with flags.
28: */
29: pipe()
30: {
31: register struct inode *ip;
32: register struct file *rf, *wf;
33: static struct mount *mp;
34: struct inode itmp;
35: int r;
36:
37: /*
38: * if pipedev not yet found, or not available, get it; if can't
39: * find it, use rootdev. It would be cleaner to wander around
40: * and fix it so that this and getfs() only check m_dev OR
41: * m_inodp, but hopefully the mount table isn't scanned enough
42: * to make it a problem. Besides, 4.3's is just as bad. Basic
43: * fantasy is that if m_inodp is set, m_dev *will* be okay.
44: */
45: if (!mp || !mp->m_inodp || mp->m_dev != pipedev) {
46: for (mp = &mount[0];;++mp) {
47: if (mp == &mount[NMOUNT]) {
48: mp = &mount[0]; /* use root */
49: break;
50: }
51: if (mp->m_inodp == NULL || mp->m_dev != pipedev)
52: continue;
53: break;
54: }
55: if (mp->m_filsys.fs_ronly) {
56: u.u_error = EROFS;
57: return;
58: }
59: }
60: itmp.i_fs = &mp->m_filsys;
61: itmp.i_dev = mp->m_dev;
62: ip = ialloc(&itmp);
63: if (ip == NULL)
64: return;
65: rf = falloc();
66: if (rf == NULL) {
67: iput(ip);
68: return;
69: }
70: r = u.u_r.r_val1;
71: wf = falloc();
72: if (wf == NULL) {
73: rf->f_count = 0;
74: u.u_ofile[r] = NULL;
75: iput(ip);
76: return;
77: }
78: u.u_r.r_val2 = u.u_r.r_val1;
79: u.u_r.r_val1 = r;
80: wf->f_flag = FWRITE;
81: rf->f_flag = FREAD;
82: rf->f_type = wf->f_type = DTYPE_PIPE;
83: rf->f_data = wf->f_data = (caddr_t)ip;
84: ip->i_count = 2;
85: ip->i_mode = IFREG;
86: ip->i_flag = IACC|IUPD|ICHG|IPIPE;
87: }
88:
89: pipe_rw(fp, uio, flag)
90: register struct file *fp;
91: register struct uio *uio;
92: int flag;
93: {
94:
95: if (uio->uio_rw == UIO_READ)
96: return (readp(fp, uio, flag));
97: return (writep(fp, uio, flag));
98: }
99:
100: readp(fp, uio, flag)
101: register struct file *fp;
102: register struct uio *uio;
103: int flag;
104: {
105: register struct inode *ip;
106: int error;
107:
108: ip = (struct inode *)fp->f_data;
109: loop:
110: /* Very conservative locking. */
111: ILOCK(ip);
112:
113: /* If nothing in the pipe, wait (unless FNONBLOCK is set). */
114: if (ip->i_size == 0) {
115: /*
116: * If there are not both reader and writer active,
117: * return without satisfying read.
118: */
119: IUNLOCK(ip);
120: if (ip->i_count != 2)
121: return (0);
122: if (fp->f_flag & FNONBLOCK)
123: return (EWOULDBLOCK);
124: ip->i_mode |= IREAD;
125: sleep((caddr_t)ip+4, PPIPE);
126: goto loop;
127: }
128:
129: uio->uio_offset = fp->f_offset;
130: error = rwip(ip, uio, flag);
131: fp->f_offset = uio->uio_offset;
132:
133: /*
134: * If reader has caught up with writer, reset
135: * offset and size to 0.
136: */
137: if (fp->f_offset == ip->i_size) {
138: fp->f_offset = 0;
139: ip->i_size = 0;
140: if (ip->i_mode & IWRITE) {
141: ip->i_mode &= ~IWRITE;
142: wakeup((caddr_t)ip+2);
143: }
144: if (ip->i_wsel) {
145: selwakeup(ip->i_wsel, (long)(ip->i_flag & IWCOLL));
146: ip->i_wsel = 0;
147: ip->i_flag &= ~IWCOLL;
148: }
149: }
150: IUNLOCK(ip);
151: return (error);
152: }
153:
154: writep(fp, uio, flag)
155: struct file *fp;
156: register struct uio *uio;
157: int flag;
158: {
159: register struct inode *ip;
160: register int c;
161: int error = 0;
162:
163: ip = (struct inode *)fp->f_data;
164: c = uio->uio_resid;
165: ILOCK(ip);
166: if ((fp->f_flag & FNONBLOCK) && ip->i_size + c >= MAXPIPSIZ) {
167: error = EWOULDBLOCK;
168: goto done;
169: }
170: loop:
171: /* If all done, return. */
172: if (c == 0) {
173: uio->uio_resid = 0;
174: goto done;
175: }
176:
177: /*
178: * If there are not both read and write sides of the pipe active,
179: * return error and signal too.
180: */
181: if (ip->i_count != 2) {
182: psignal(u.u_procp, SIGPIPE);
183: error = EPIPE;
184: done: IUNLOCK(ip);
185: return (error);
186: }
187:
188: /*
189: * If the pipe is full, wait for reads to deplete
190: * and truncate it.
191: */
192: if (ip->i_size >= MAXPIPSIZ) {
193: ip->i_mode |= IWRITE;
194: IUNLOCK(ip);
195: sleep((caddr_t)ip+2, PPIPE);
196: ILOCK(ip);
197: goto loop;
198: }
199:
200: /*
201: * Write what is possible and loop back.
202: * If writing less than MAXPIPSIZ, it always goes.
203: * One can therefore get a file > MAXPIPSIZ if write
204: * sizes do not divide MAXPIPSIZ.
205: */
206: uio->uio_offset = ip->i_size;
207: uio->uio_resid = MIN((u_int)c, (u_int)MAXPIPSIZ);
208: c -= uio->uio_resid;
209: error = rwip(ip, uio, flag);
210: if (ip->i_mode&IREAD) {
211: ip->i_mode &= ~IREAD;
212: wakeup((caddr_t)ip+4);
213: }
214: if (ip->i_rsel) {
215: selwakeup(ip->i_rsel, (long)(ip->i_flag & IRCOLL));
216: ip->i_rsel = 0;
217: ip->i_flag &= ~IRCOLL;
218: }
219: goto loop;
220: }
221:
222: pipe_select(fp, which)
223: struct file *fp;
224: int which;
225: {
226: register struct inode *ip = (struct inode *)fp->f_data;
227: register struct proc *p;
228: register int retval = 0;
229: extern int selwait;
230:
231: ILOCK(ip);
232: if (ip->i_count != 2)
233: retval = 1;
234:
235: else switch (which) {
236: case FREAD:
237: if (ip->i_size) {
238: retval = 1;
239: break;
240: }
241: if ((p = ip->i_rsel) && p->p_wchan == (caddr_t)&selwait)
242: ip->i_flag |= IRCOLL;
243: else
244: ip->i_rsel = u.u_procp;
245: break;
246:
247: case FWRITE:
248: if (ip->i_size < MAXPIPSIZ) {
249: retval = 1;
250: break;
251: }
252: if ((p = ip->i_wsel) && p->p_wchan == (caddr_t)&selwait)
253: ip->i_flag |= IWCOLL;
254: else
255: ip->i_wsel = u.u_procp;
256: break;
257: }
258: IUNLOCK(ip);
259: return(retval);
260: }
261:
262: /*
263: * This routine was pulled out of what used to be called 'ino_close'. Doing
264: * so saved a test of the inode belonging to a pipe. We know this is a pipe
265: * because the inode type was DTYPE_PIPE. The dispatch in closef() can come
266: * directly here instead of the general inode close routine.
267: *
268: * This routine frees the inode by calling 'iput'. The inode must be
269: * unlocked prior to calling this routine because an 'ilock' is done prior
270: * to the select wakeup processing.
271: */
272:
273: pipe_close(fp)
274: struct file *fp;
275: {
276: register struct inode *ip = (struct inode *)fp->f_data;
277:
278: ilock(ip);
279: #ifdef DIAGNOSTIC
280: if ((ip->i_flag & IPIPE) == 0)
281: panic("pipe_close !IPIPE");
282: #endif
283: if (ip->i_rsel)
284: {
285: selwakeup(ip->i_rsel, (long)(ip->i_flag & IRCOLL));
286: ip->i_rsel = 0;
287: ip->i_flag &= ~IRCOLL;
288: }
289: if (ip->i_wsel)
290: {
291: selwakeup(ip->i_wsel, (long)(ip->i_flag & IWCOLL));
292: ip->i_wsel = 0;
293: ip->i_flag &= ~IWCOLL;
294: }
295: ip->i_mode &= ~(IREAD|IWRITE);
296: wakeup((caddr_t)ip+2);
297: wakeup((caddr_t)ip+4);
298:
299: /*
300: * And finally decrement the reference count and (likely) release the inode.
301: */
302: iput(ip);
303: return(0);
304: }
Defined functions
pipe
defined in line
29; used 2 times
Defined variables