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