This source file includes following definitions.
- pipe_read
- pipe_write
- pipe_lseek
- pipe_readdir
- bad_pipe_rw
- pipe_ioctl
- pipe_select
- pipe_read_release
- pipe_write_release
- pipe_rdwr_release
- sys_pipe
1
2
3
4
5
6
7 #include <asm/segment.h>
8
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/signal.h>
13 #include <linux/fcntl.h>
14 #include <linux/termios.h>
15
16 static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
17 {
18 int chars, size, read = 0;
19
20 if (!(filp->f_flags & O_NONBLOCK))
21 while (!PIPE_SIZE(*inode)) {
22 wake_up(& PIPE_WRITE_WAIT(*inode));
23 if (!PIPE_WRITERS(*inode))
24 return 0;
25 if (current->signal & ~current->blocked)
26 return -ERESTARTSYS;
27 interruptible_sleep_on(& PIPE_READ_WAIT(*inode));
28 }
29 while (count>0 && (size = PIPE_SIZE(*inode))) {
30 chars = PAGE_SIZE-PIPE_TAIL(*inode);
31 if (chars > count)
32 chars = count;
33 if (chars > size)
34 chars = size;
35 memcpy_tofs(buf, PIPE_BASE(*inode)+PIPE_TAIL(*inode), chars );
36 read += chars;
37 PIPE_TAIL(*inode) += chars;
38 PIPE_TAIL(*inode) &= (PAGE_SIZE-1);
39 count -= chars;
40 buf += chars;
41 }
42 wake_up(& PIPE_WRITE_WAIT(*inode));
43 if (read)
44 return read;
45 if (PIPE_WRITERS(*inode))
46 return -EAGAIN;
47 return 0;
48 }
49
50 static int pipe_write(struct inode * inode, struct file * filp, char * buf, int count)
51 {
52 int chars, size, written = 0;
53
54 if (!PIPE_READERS(*inode)) {
55 send_sig(SIGPIPE,current,0);
56 return -EPIPE;
57 }
58
59 if (count < PAGE_SIZE)
60 size = PAGE_SIZE-count;
61 else
62 size = PAGE_SIZE-1;
63 while (count>0) {
64 while (PIPE_SIZE(*inode) >= size) {
65 if (!PIPE_READERS(*inode)) {
66 send_sig(SIGPIPE,current,0);
67 return written?written:-EPIPE;
68 }
69 if (current->signal & ~current->blocked)
70 return written?written:-ERESTARTSYS;
71 if (filp->f_flags & O_NONBLOCK)
72 return -EAGAIN;
73 else
74 interruptible_sleep_on(&PIPE_WRITE_WAIT(*inode));
75 }
76 while (count>0 && (size = (PAGE_SIZE-1)-PIPE_SIZE(*inode))) {
77 chars = PAGE_SIZE-PIPE_HEAD(*inode);
78 if (chars > count)
79 chars = count;
80 if (chars > size)
81 chars = size;
82 memcpy_fromfs(PIPE_BASE(*inode)+PIPE_HEAD(*inode), buf, chars );
83 written += chars;
84 PIPE_HEAD(*inode) += chars;
85 PIPE_HEAD(*inode) &= (PAGE_SIZE-1);
86 count -= chars;
87 buf += chars;
88 }
89 wake_up(& PIPE_READ_WAIT(*inode));
90 size = PAGE_SIZE-1;
91 }
92 return written;
93 }
94
95 static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
96 {
97 return -ESPIPE;
98 }
99
100 static int pipe_readdir(struct inode * inode, struct file * file, struct dirent * de, int count)
101 {
102 return -ENOTDIR;
103 }
104
105 static int bad_pipe_rw(struct inode * inode, struct file * filp, char * buf, int count)
106 {
107 return -EBADF;
108 }
109
110 static int pipe_ioctl(struct inode *pino, struct file * filp,
111 unsigned int cmd, unsigned long arg)
112 {
113 int error;
114
115 switch (cmd) {
116 case FIONREAD:
117 error = verify_area(VERIFY_WRITE, (void *) arg,4);
118 if (!error)
119 put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
120 return error;
121 default:
122 return -EINVAL;
123 }
124 }
125
126 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
127 {
128 switch (sel_type) {
129 case SEL_IN:
130 if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
131 return 1;
132 select_wait(&PIPE_READ_WAIT(*inode), wait);
133 return 0;
134 case SEL_OUT:
135 if (!PIPE_FULL(*inode) || !PIPE_WRITERS(*inode))
136 return 1;
137 select_wait(&PIPE_WRITE_WAIT(*inode), wait);
138 return 0;
139 case SEL_EX:
140 if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
141 return 1;
142 select_wait(&inode->i_wait,wait);
143 return 0;
144 }
145 return 0;
146 }
147
148
149
150
151
152 static void pipe_read_release(struct inode * inode, struct file * filp)
153 {
154 PIPE_READERS(*inode)--;
155 wake_up(&PIPE_WRITE_WAIT(*inode));
156 }
157
158 static void pipe_write_release(struct inode * inode, struct file * filp)
159 {
160 PIPE_WRITERS(*inode)--;
161 wake_up(&PIPE_READ_WAIT(*inode));
162 }
163
164 static void pipe_rdwr_release(struct inode * inode, struct file * filp)
165 {
166 PIPE_READERS(*inode)--;
167 PIPE_WRITERS(*inode)--;
168 wake_up(&PIPE_READ_WAIT(*inode));
169 wake_up(&PIPE_WRITE_WAIT(*inode));
170 }
171
172
173
174
175
176 struct file_operations read_pipe_fops = {
177 pipe_lseek,
178 pipe_read,
179 bad_pipe_rw,
180 pipe_readdir,
181 pipe_select,
182 pipe_ioctl,
183 NULL,
184 NULL,
185 pipe_read_release,
186 NULL
187 };
188
189 struct file_operations write_pipe_fops = {
190 pipe_lseek,
191 bad_pipe_rw,
192 pipe_write,
193 pipe_readdir,
194 pipe_select,
195 pipe_ioctl,
196 NULL,
197 NULL,
198 pipe_write_release,
199 NULL
200 };
201
202 struct file_operations rdwr_pipe_fops = {
203 pipe_lseek,
204 pipe_read,
205 pipe_write,
206 pipe_readdir,
207 pipe_select,
208 pipe_ioctl,
209 NULL,
210 NULL,
211 pipe_rdwr_release,
212 NULL
213 };
214
215 int sys_pipe(unsigned long * fildes)
216 {
217 struct inode * inode;
218 struct file * f[2];
219 int fd[2];
220 int i,j;
221
222 j = verify_area(VERIFY_WRITE,fildes,8);
223 if (j)
224 return j;
225 for(j=0 ; j<2 ; j++)
226 if (!(f[j] = get_empty_filp()))
227 break;
228 if (j==1)
229 f[0]->f_count--;
230 if (j<2)
231 return -ENFILE;
232 j=0;
233 for(i=0;j<2 && i<NR_OPEN;i++)
234 if (!current->filp[i]) {
235 current->filp[ fd[j]=i ] = f[j];
236 j++;
237 }
238 if (j==1)
239 current->filp[fd[0]]=NULL;
240 if (j<2) {
241 f[0]->f_count--;
242 f[1]->f_count--;
243 return -EMFILE;
244 }
245 if (!(inode=get_pipe_inode())) {
246 current->filp[fd[0]] = NULL;
247 current->filp[fd[1]] = NULL;
248 f[0]->f_count--;
249 f[1]->f_count--;
250 return -ENFILE;
251 }
252 f[0]->f_inode = f[1]->f_inode = inode;
253 f[0]->f_pos = f[1]->f_pos = 0;
254 f[0]->f_flags = O_RDONLY;
255 f[0]->f_op = &read_pipe_fops;
256 f[0]->f_mode = 1;
257 f[1]->f_flags = O_WRONLY;
258 f[1]->f_op = &write_pipe_fops;
259 f[1]->f_mode = 2;
260 put_fs_long(fd[0],0+fildes);
261 put_fs_long(fd[1],1+fildes);
262 return 0;
263 }