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