1: #include "param.h"
2: #include <sys/systm.h>
3: #include <sys/dir.h>
4: #include <sys/user.h>
5: #include <sys/inode.h>
6: #include <sys/file.h>
7: #include <sys/reg.h>
8: #include <sys/inline.h>
9:
10: /*
11: * SCCS id @(#)pipe.c 2.1 (Berkeley) 8/5/83
12: */
13:
14: /*
15: * Max allowable buffering per write on a pipe.
16: * This is also roughly the max size of the
17: * file created to implement the pipe.
18: * If this size is bigger than 4096
19: * (5120 without UCB_NKB),
20: * pipes will be implemented with large
21: * files, which is probably not good.
22: */
23: #define PIPSIZ 4096
24:
25: /*
26: * The sys-pipe entry.
27: * Allocate an inode on the root device.
28: * Allocate 2 file structures.
29: * Put it all together with flags.
30: */
31: pipe()
32: {
33: register struct inode *ip;
34: register struct file *rf, *wf;
35: register int r;
36:
37: ip = ialloc(pipedev);
38: if(ip == NULL) {
39: /*
40: * Someone may not have mounted pipedev so we
41: * try to get an inode from rootdev.
42: * Getfs() will have already printed a message
43: * about its inability to find pipedev in the
44: * mount table, so don't complain.
45: */
46: ip = ialloc(rootdev);
47: if (ip == NULL)
48: return;
49: /*
50: * This is necessary because the ialloc(pipedev) above
51: * set u.u_error to ENOSPC.
52: */
53: else
54: u.u_error = 0;
55: }
56: rf = falloc();
57: if(rf == NULL) {
58: iput(ip);
59: return;
60: }
61: r = u.u_r.r_val1;
62: wf = falloc();
63: if(wf == NULL) {
64: rf->f_count = 0;
65: u.u_ofile[r] = NULL;
66: iput(ip);
67: return;
68: }
69: u.u_r.r_val2 = u.u_r.r_val1;
70: u.u_r.r_val1 = r;
71: wf->f_flag = FWRITE|FPIPE;
72: wf->f_inode = ip;
73: rf->f_flag = FREAD|FPIPE;
74: rf->f_inode = ip;
75: ip->i_count = 2;
76: ip->i_mode = IFREG;
77: ip->i_flag = IACC|IUPD|ICHG|IPIPE;
78: }
79:
80: /*
81: * Read call directed to a pipe.
82: */
83: readp(fp)
84: register struct file *fp;
85: {
86: register struct inode *ip;
87:
88: ip = fp->f_inode;
89:
90: loop:
91: /*
92: * Very conservative locking.
93: */
94:
95: plock(ip);
96: /*
97: * If nothing in the pipe, wait.
98: */
99: if (ip->i_size == 0) {
100: /*
101: * If there are not both reader and
102: * writer active, return without
103: * satisfying read.
104: */
105: prele(ip);
106: if(ip->i_count < 2)
107: return;
108: ip->i_mode |= IREAD;
109: sleep((caddr_t)ip+2, PPIPE);
110: goto loop;
111: }
112:
113: /*
114: * Read and return
115: */
116:
117: u.u_offset = fp->f_un.f_offset;
118: readi(ip);
119: fp->f_un.f_offset = u.u_offset;
120: /*
121: * If reader has caught up with writer, reset
122: * offset and size to 0.
123: */
124: if (fp->f_un.f_offset == ip->i_size) {
125: fp->f_un.f_offset = 0;
126: ip->i_size = 0;
127: if(ip->i_mode & IWRITE) {
128: ip->i_mode &= ~IWRITE;
129: wakeup((caddr_t)ip+1);
130: }
131: }
132: prele(ip);
133: }
134:
135: /*
136: * Write call directed to a pipe.
137: */
138: writep(fp)
139: register struct file *fp;
140: {
141: register c;
142: register struct inode *ip;
143:
144: ip = fp->f_inode;
145: c = u.u_count;
146:
147: loop:
148:
149: /*
150: * If all done, return.
151: */
152:
153: plock(ip);
154: if(c == 0) {
155: prele(ip);
156: u.u_count = 0;
157: return;
158: }
159:
160: /*
161: * If there are not both read and
162: * write sides of the pipe active,
163: * return error and signal too.
164: */
165:
166: if(ip->i_count < 2) {
167: prele(ip);
168: u.u_error = EPIPE;
169: psignal(u.u_procp, SIGPIPE);
170: return;
171: }
172:
173: /*
174: * If the pipe is full,
175: * wait for reads to deplete
176: * and truncate it.
177: */
178:
179: if(ip->i_size >= PIPSIZ) {
180: ip->i_mode |= IWRITE;
181: prele(ip);
182: sleep((caddr_t)ip+1, PPIPE);
183: goto loop;
184: }
185:
186: /*
187: * Write what is possible and
188: * loop back.
189: * If writing less than PIPSIZ, it always goes.
190: * One can therefore get a file > PIPSIZ if write
191: * sizes do not divide PIPSIZ.
192: */
193:
194: u.u_offset = ip->i_size;
195: u.u_count = MIN((unsigned)c, (unsigned)PIPSIZ);
196: c -= u.u_count;
197: writei(ip);
198: prele(ip);
199: if(ip->i_mode&IREAD) {
200: ip->i_mode &= ~IREAD;
201: wakeup((caddr_t)ip+2);
202: }
203: goto loop;
204: }
205:
206: #ifdef plock
207: #undef plock
208: #endif
209: #ifdef prele
210: #undef prele
211: #endif
212: /*
213: * Lock a pipe.
214: * If its already locked,
215: * set the WANT bit and sleep.
216: */
217: plock(ip)
218: register struct inode *ip;
219: {
220:
221: while(ip->i_flag&ILOCK) {
222: ip->i_flag |= IWANT;
223: sleep((caddr_t)ip, PINOD);
224: }
225: ip->i_flag |= ILOCK;
226: }
227:
228: /*
229: * Unlock a pipe.
230: * If WANT bit is on,
231: * wakeup.
232: * This routine is also used
233: * to unlock inodes in general.
234: */
235: prele(ip)
236: register struct inode *ip;
237: {
238:
239: ip->i_flag &= ~ILOCK;
240: if(ip->i_flag&IWANT) {
241: ip->i_flag &= ~IWANT;
242: wakeup((caddr_t)ip);
243: }
244: }
Defined functions
pipe
defined in line
31; used 2 times
plock
defined in line
217; used 12 times
prele
defined in line
235; used 10 times
readp
defined in line
83; used 1 times
Defined macros