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 int arg)
112 {
113 switch (cmd) {
114 case FIONREAD:
115 verify_area((void *) arg,4);
116 put_fs_long(PIPE_SIZE(*pino),(unsigned long *) arg);
117 return 0;
118 default:
119 return -EINVAL;
120 }
121 }
122
123 static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
124 {
125 switch (sel_type) {
126 case SEL_IN:
127 if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
128 return 1;
129 select_wait(&PIPE_READ_WAIT(*inode), wait);
130 return 0;
131 case SEL_OUT:
132 if (!PIPE_FULL(*inode) || !PIPE_WRITERS(*inode))
133 return 1;
134 select_wait(&PIPE_WRITE_WAIT(*inode), wait);
135 return 0;
136 case SEL_EX:
137 if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
138 return 1;
139 select_wait(&inode->i_wait,wait);
140 return 0;
141 }
142 return 0;
143 }
144
145
146
147
148
149 static void pipe_read_release(struct inode * inode, struct file * filp)
150 {
151 PIPE_READERS(*inode)--;
152 wake_up(&PIPE_WRITE_WAIT(*inode));
153 }
154
155 static void pipe_write_release(struct inode * inode, struct file * filp)
156 {
157 PIPE_WRITERS(*inode)--;
158 wake_up(&PIPE_READ_WAIT(*inode));
159 }
160
161 static void pipe_rdwr_release(struct inode * inode, struct file * filp)
162 {
163 PIPE_READERS(*inode)--;
164 PIPE_WRITERS(*inode)--;
165 wake_up(&PIPE_READ_WAIT(*inode));
166 wake_up(&PIPE_WRITE_WAIT(*inode));
167 }
168
169
170
171
172
173 struct file_operations read_pipe_fops = {
174 pipe_lseek,
175 pipe_read,
176 bad_pipe_rw,
177 pipe_readdir,
178 pipe_select,
179 pipe_ioctl,
180 NULL,
181 NULL,
182 pipe_read_release,
183 NULL
184 };
185
186 struct file_operations write_pipe_fops = {
187 pipe_lseek,
188 bad_pipe_rw,
189 pipe_write,
190 pipe_readdir,
191 pipe_select,
192 pipe_ioctl,
193 NULL,
194 NULL,
195 pipe_write_release,
196 NULL
197 };
198
199 struct file_operations rdwr_pipe_fops = {
200 pipe_lseek,
201 pipe_read,
202 pipe_write,
203 pipe_readdir,
204 pipe_select,
205 pipe_ioctl,
206 NULL,
207 NULL,
208 pipe_rdwr_release,
209 NULL
210 };
211
212 int sys_pipe(unsigned long * fildes)
213 {
214 struct inode * inode;
215 struct file * f[2];
216 int fd[2];
217 int i,j;
218
219 verify_area(fildes,8);
220 for(j=0 ; j<2 ; j++)
221 if (!(f[j] = get_empty_filp()))
222 break;
223 if (j==1)
224 f[0]->f_count--;
225 if (j<2)
226 return -ENFILE;
227 j=0;
228 for(i=0;j<2 && i<NR_OPEN;i++)
229 if (!current->filp[i]) {
230 current->filp[ fd[j]=i ] = f[j];
231 j++;
232 }
233 if (j==1)
234 current->filp[fd[0]]=NULL;
235 if (j<2) {
236 f[0]->f_count--;
237 f[1]->f_count--;
238 return -EMFILE;
239 }
240 if (!(inode=get_pipe_inode())) {
241 current->filp[fd[0]] = NULL;
242 current->filp[fd[1]] = NULL;
243 f[0]->f_count--;
244 f[1]->f_count--;
245 return -ENFILE;
246 }
247 f[0]->f_inode = f[1]->f_inode = inode;
248 f[0]->f_pos = f[1]->f_pos = 0;
249 f[0]->f_flags = f[1]->f_flags = 0;
250 f[0]->f_op = &read_pipe_fops;
251 f[0]->f_mode = 1;
252 f[1]->f_op = &write_pipe_fops;
253 f[1]->f_mode = 2;
254 put_fs_long(fd[0],0+fildes);
255 put_fs_long(fd[1],1+fildes);
256 return 0;
257 }