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 };
184
185 struct file_operations write_pipe_fops = {
186 pipe_lseek,
187 bad_pipe_rw,
188 pipe_write,
189 pipe_readdir,
190 pipe_select,
191 pipe_ioctl,
192 NULL,
193 NULL,
194 pipe_write_release
195 };
196
197 struct file_operations rdwr_pipe_fops = {
198 pipe_lseek,
199 pipe_read,
200 pipe_write,
201 pipe_readdir,
202 pipe_select,
203 pipe_ioctl,
204 NULL,
205 NULL,
206 pipe_rdwr_release
207 };
208
209 int sys_pipe(unsigned long * fildes)
210 {
211 struct inode * inode;
212 struct file * f[2];
213 int fd[2];
214 int i,j;
215
216 verify_area(fildes,8);
217 for(j=0 ; j<2 ; j++)
218 if (!(f[j] = get_empty_filp()))
219 break;
220 if (j==1)
221 f[0]->f_count--;
222 if (j<2)
223 return -ENFILE;
224 j=0;
225 for(i=0;j<2 && i<NR_OPEN;i++)
226 if (!current->filp[i]) {
227 current->filp[ fd[j]=i ] = f[j];
228 j++;
229 }
230 if (j==1)
231 current->filp[fd[0]]=NULL;
232 if (j<2) {
233 f[0]->f_count--;
234 f[1]->f_count--;
235 return -EMFILE;
236 }
237 if (!(inode=get_pipe_inode())) {
238 current->filp[fd[0]] = NULL;
239 current->filp[fd[1]] = NULL;
240 f[0]->f_count--;
241 f[1]->f_count--;
242 return -ENFILE;
243 }
244 f[0]->f_inode = f[1]->f_inode = inode;
245 f[0]->f_pos = f[1]->f_pos = 0;
246 f[0]->f_flags = f[1]->f_flags = 0;
247 f[0]->f_op = &read_pipe_fops;
248 f[0]->f_mode = 1;
249 f[1]->f_op = &write_pipe_fops;
250 f[1]->f_mode = 2;
251 put_fs_long(fd[0],0+fildes);
252 put_fs_long(fd[1],1+fildes);
253 return 0;
254 }