OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [pipe.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1627 jcastillo
/*
2
 *  linux/fs/pipe.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
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
#include <linux/mm.h>
16
 
17
/*
18
 * Define this if you want SunOS compatibility wrt braindead
19
 * select behaviour on FIFO's.
20
 */
21
#undef FIFO_SUNOS_BRAINDAMAGE
22
 
23
/* We don't use the head/tail construction any more. Now we use the start/len*/
24
/* construction providing full use of PIPE_BUF (multiple of PAGE_SIZE) */
25
/* Florian Coosmann (FGC)                                ^ current = 1       */
26
/* Additionally, we now use locking technique. This prevents race condition  */
27
/* in case of paging and multiple read/write on the same pipe. (FGC)         */
28
 
29
 
30
static int pipe_read(struct inode * inode, struct file * filp, char * buf, int count)
31
{
32
        int chars = 0, size = 0, read = 0;
33
        char *pipebuf;
34
 
35
        if (filp->f_flags & O_NONBLOCK) {
36
                if (PIPE_LOCK(*inode))
37
                        return -EAGAIN;
38
                if (PIPE_EMPTY(*inode))
39
                        if (PIPE_WRITERS(*inode))
40
                                return -EAGAIN;
41
                        else
42
                                return 0;
43
        } else while (PIPE_EMPTY(*inode) || PIPE_LOCK(*inode)) {
44
                if (PIPE_EMPTY(*inode)) {
45
                        if (!PIPE_WRITERS(*inode))
46
                                return 0;
47
                }
48
                if (current->signal & ~current->blocked)
49
                        return -ERESTARTSYS;
50
                interruptible_sleep_on(&PIPE_WAIT(*inode));
51
        }
52
        PIPE_LOCK(*inode)++;
53
        while (count>0 && (size = PIPE_SIZE(*inode))) {
54
                chars = PIPE_MAX_RCHUNK(*inode);
55
                if (chars > count)
56
                        chars = count;
57
                if (chars > size)
58
                        chars = size;
59
                read += chars;
60
                pipebuf = PIPE_BASE(*inode)+PIPE_START(*inode);
61
                PIPE_START(*inode) += chars;
62
                PIPE_START(*inode) &= (PIPE_BUF-1);
63
                PIPE_LEN(*inode) -= chars;
64
                count -= chars;
65
                memcpy_tofs(buf, pipebuf, chars );
66
                buf += chars;
67
        }
68
        PIPE_LOCK(*inode)--;
69
        wake_up_interruptible(&PIPE_WAIT(*inode));
70
        if (read) {
71
                UPDATE_ATIME(inode);
72
                return read;
73
        }
74
        if (PIPE_WRITERS(*inode))
75
                return -EAGAIN;
76
        return 0;
77
}
78
 
79
static int pipe_write(struct inode * inode, struct file * filp, const char * buf, int count)
80
{
81
        int chars = 0, free = 0, written = 0;
82
        char *pipebuf;
83
 
84
        if (!PIPE_READERS(*inode)) { /* no readers */
85
                send_sig(SIGPIPE,current,0);
86
                return -EPIPE;
87
        }
88
/* if count <= PIPE_BUF, we have to make it atomic */
89
        if (count <= PIPE_BUF)
90
                free = count;
91
        else
92
                free = 1; /* can't do it atomically, wait for any free space */
93
        while (count>0) {
94
                while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) {
95
                        if (!PIPE_READERS(*inode)) { /* no readers */
96
                                send_sig(SIGPIPE,current,0);
97
                                return written? :-EPIPE;
98
                        }
99
                        if (current->signal & ~current->blocked)
100
                                return written? :-ERESTARTSYS;
101
                        if (filp->f_flags & O_NONBLOCK)
102
                                return written? :-EAGAIN;
103
                        interruptible_sleep_on(&PIPE_WAIT(*inode));
104
                }
105
                PIPE_LOCK(*inode)++;
106
                while (count>0 && (free = PIPE_FREE(*inode))) {
107
                        chars = PIPE_MAX_WCHUNK(*inode);
108
                        if (chars > count)
109
                                chars = count;
110
                        if (chars > free)
111
                                chars = free;
112
                        pipebuf = PIPE_BASE(*inode)+PIPE_END(*inode);
113
                        written += chars;
114
                        PIPE_LEN(*inode) += chars;
115
                        count -= chars;
116
                        memcpy_fromfs(pipebuf, buf, chars );
117
                        buf += chars;
118
                }
119
                PIPE_LOCK(*inode)--;
120
                wake_up_interruptible(&PIPE_WAIT(*inode));
121
                free = 1;
122
        }
123
        inode->i_ctime = inode->i_mtime = CURRENT_TIME;
124
        return written;
125
}
126
 
127
static int pipe_lseek(struct inode * inode, struct file * file, off_t offset, int orig)
128
{
129
        return -ESPIPE;
130
}
131
 
132
static int bad_pipe_r(struct inode * inode, struct file * filp, char * buf, int count)
133
{
134
        return -EBADF;
135
}
136
 
137
static int bad_pipe_w(struct inode * inode, struct file * filp, const char * buf, int count)
138
{
139
        return -EBADF;
140
}
141
 
142
static int pipe_ioctl(struct inode *pino, struct file * filp,
143
        unsigned int cmd, unsigned long arg)
144
{
145
        int error;
146
 
147
        switch (cmd) {
148
                case FIONREAD:
149
                        error = verify_area(VERIFY_WRITE, (void *) arg, sizeof(int));
150
                        if (!error)
151
                                put_user(PIPE_SIZE(*pino),(int *) arg);
152
                        return error;
153
                default:
154
                        return -EINVAL;
155
        }
156
}
157
 
158
static int pipe_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
159
{
160
        switch (sel_type) {
161
                case SEL_IN:
162
                        if (!PIPE_EMPTY(*inode) || !PIPE_WRITERS(*inode))
163
                                return 1;
164
                        select_wait(&PIPE_WAIT(*inode), wait);
165
                        return 0;
166
                case SEL_OUT:
167
                        if (PIPE_EMPTY(*inode) || !PIPE_READERS(*inode))
168
                                return 1;
169
                        select_wait(&PIPE_WAIT(*inode), wait);
170
                        return 0;
171
                case SEL_EX:
172
                        if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
173
                                return 1;
174
                        select_wait(&inode->i_wait,wait);
175
                        return 0;
176
        }
177
        return 0;
178
}
179
 
180
#ifdef FIFO_SUNOS_BRAINDAMAGE
181
/*
182
 * Arggh. Why does SunOS have to have different select() behaviour
183
 * for pipes and fifos? Hate-Hate-Hate. See difference in SEL_IN..
184
 */
185
static int fifo_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
186
{
187
        switch (sel_type) {
188
                case SEL_IN:
189
                        if (!PIPE_EMPTY(*inode))
190
                                return 1;
191
                        select_wait(&PIPE_WAIT(*inode), wait);
192
                        return 0;
193
                case SEL_OUT:
194
                        if (!PIPE_FULL(*inode) || !PIPE_READERS(*inode))
195
                                return 1;
196
                        select_wait(&PIPE_WAIT(*inode), wait);
197
                        return 0;
198
                case SEL_EX:
199
                        if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
200
                                return 1;
201
                        select_wait(&inode->i_wait,wait);
202
                        return 0;
203
        }
204
        return 0;
205
}
206
#else
207
 
208
#define fifo_select pipe_select
209
 
210
#endif /* FIFO_SUNOS_BRAINDAMAGE */
211
 
212
/*
213
 * The 'connect_xxx()' functions are needed for named pipes when
214
 * the open() code hasn't guaranteed a connection (O_NONBLOCK),
215
 * and we need to act differently until we do get a writer..
216
 */
217
static int connect_read(struct inode * inode, struct file * filp, char * buf, int count)
218
{
219
        if (PIPE_EMPTY(*inode) && !PIPE_WRITERS(*inode))
220
                return 0;
221
        filp->f_op = &read_fifo_fops;
222
        return pipe_read(inode,filp,buf,count);
223
}
224
 
225
static int connect_select(struct inode * inode, struct file * filp, int sel_type, select_table * wait)
226
{
227
        switch (sel_type) {
228
                case SEL_IN:
229
                        if (!PIPE_EMPTY(*inode)) {
230
                                filp->f_op = &read_fifo_fops;
231
                                return 1;
232
                        }
233
                        if (PIPE_WRITERS(*inode)) {
234
                                filp->f_op = &read_fifo_fops;
235
                        }
236
                        select_wait(&PIPE_WAIT(*inode), wait);
237
                        return 0;
238
                case SEL_OUT:
239
                        if (!PIPE_FULL(*inode))
240
                                return 1;
241
                        select_wait(&PIPE_WAIT(*inode), wait);
242
                        return 0;
243
                case SEL_EX:
244
                        if (!PIPE_READERS(*inode) || !PIPE_WRITERS(*inode))
245
                                return 1;
246
                        select_wait(&inode->i_wait,wait);
247
                        return 0;
248
        }
249
        return 0;
250
}
251
 
252
static void pipe_read_release(struct inode * inode, struct file * filp)
253
{
254
        PIPE_READERS(*inode)--;
255
        wake_up_interruptible(&PIPE_WAIT(*inode));
256
}
257
 
258
static void pipe_write_release(struct inode * inode, struct file * filp)
259
{
260
        PIPE_WRITERS(*inode)--;
261
        wake_up_interruptible(&PIPE_WAIT(*inode));
262
}
263
 
264
static void pipe_rdwr_release(struct inode * inode, struct file * filp)
265
{
266
        if (filp->f_mode & FMODE_READ)
267
                PIPE_READERS(*inode)--;
268
        if (filp->f_mode & FMODE_WRITE)
269
                PIPE_WRITERS(*inode)--;
270
        wake_up_interruptible(&PIPE_WAIT(*inode));
271
}
272
 
273
static int pipe_read_open(struct inode * inode, struct file * filp)
274
{
275
        PIPE_READERS(*inode)++;
276
        return 0;
277
}
278
 
279
static int pipe_write_open(struct inode * inode, struct file * filp)
280
{
281
        PIPE_WRITERS(*inode)++;
282
        return 0;
283
}
284
 
285
static int pipe_rdwr_open(struct inode * inode, struct file * filp)
286
{
287
        if (filp->f_mode & FMODE_READ)
288
                PIPE_READERS(*inode)++;
289
        if (filp->f_mode & FMODE_WRITE)
290
                PIPE_WRITERS(*inode)++;
291
        return 0;
292
}
293
 
294
/*
295
 * The file_operations structs are not static because they
296
 * are also used in linux/fs/fifo.c to do operations on fifo's.
297
 */
298
struct file_operations connecting_fifo_fops = {
299
        pipe_lseek,
300
        connect_read,
301
        bad_pipe_w,
302
        NULL,           /* no readdir */
303
        connect_select,
304
        pipe_ioctl,
305
        NULL,           /* no mmap on pipes.. surprise */
306
        pipe_read_open,
307
        pipe_read_release,
308
        NULL
309
};
310
 
311
struct file_operations read_fifo_fops = {
312
        pipe_lseek,
313
        pipe_read,
314
        bad_pipe_w,
315
        NULL,           /* no readdir */
316
        fifo_select,
317
        pipe_ioctl,
318
        NULL,           /* no mmap on pipes.. surprise */
319
        pipe_read_open,
320
        pipe_read_release,
321
        NULL
322
};
323
 
324
struct file_operations write_fifo_fops = {
325
        pipe_lseek,
326
        bad_pipe_r,
327
        pipe_write,
328
        NULL,           /* no readdir */
329
        fifo_select,
330
        pipe_ioctl,
331
        NULL,           /* mmap */
332
        pipe_write_open,
333
        pipe_write_release,
334
        NULL
335
};
336
 
337
struct file_operations rdwr_fifo_fops = {
338
        pipe_lseek,
339
        pipe_read,
340
        pipe_write,
341
        NULL,           /* no readdir */
342
        fifo_select,
343
        pipe_ioctl,
344
        NULL,           /* mmap */
345
        pipe_rdwr_open,
346
        pipe_rdwr_release,
347
        NULL
348
};
349
 
350
struct file_operations read_pipe_fops = {
351
        pipe_lseek,
352
        pipe_read,
353
        bad_pipe_w,
354
        NULL,           /* no readdir */
355
        pipe_select,
356
        pipe_ioctl,
357
        NULL,           /* no mmap on pipes.. surprise */
358
        pipe_read_open,
359
        pipe_read_release,
360
        NULL
361
};
362
 
363
struct file_operations write_pipe_fops = {
364
        pipe_lseek,
365
        bad_pipe_r,
366
        pipe_write,
367
        NULL,           /* no readdir */
368
        pipe_select,
369
        pipe_ioctl,
370
        NULL,           /* mmap */
371
        pipe_write_open,
372
        pipe_write_release,
373
        NULL
374
};
375
 
376
struct file_operations rdwr_pipe_fops = {
377
        pipe_lseek,
378
        pipe_read,
379
        pipe_write,
380
        NULL,           /* no readdir */
381
        pipe_select,
382
        pipe_ioctl,
383
        NULL,           /* mmap */
384
        pipe_rdwr_open,
385
        pipe_rdwr_release,
386
        NULL
387
};
388
 
389
struct inode_operations pipe_inode_operations = {
390
        &rdwr_pipe_fops,
391
        NULL,                   /* create */
392
        NULL,                   /* lookup */
393
        NULL,                   /* link */
394
        NULL,                   /* unlink */
395
        NULL,                   /* symlink */
396
        NULL,                   /* mkdir */
397
        NULL,                   /* rmdir */
398
        NULL,                   /* mknod */
399
        NULL,                   /* rename */
400
        NULL,                   /* readlink */
401
        NULL,                   /* follow_link */
402
        NULL,                   /* readpage */
403
        NULL,                   /* writepage */
404
        NULL,                   /* bmap */
405
        NULL,                   /* truncate */
406
        NULL                    /* permission */
407
};
408
 
409
int do_pipe(int *fd)
410
{
411
        struct inode * inode;
412
        struct file *f1, *f2;
413
        int error;
414
        int i,j;
415
 
416
        error = -ENFILE;
417
        f1 = get_empty_filp();
418
        if (!f1)
419
                goto no_files;
420
 
421
        f2 = get_empty_filp();
422
        if (!f2)
423
                goto close_f1;
424
 
425
        inode = get_pipe_inode();
426
        if (!inode)
427
                goto close_f12;
428
 
429
        error = get_unused_fd();
430
        if (error < 0)
431
                goto close_f12_inode;
432
        i = error;
433
 
434
        error = get_unused_fd();
435
        if (error < 0)
436
                goto close_f12_inode_i;
437
        j = error;
438
 
439
        f1->f_inode = f2->f_inode = inode;
440
        /* read file */
441
        f1->f_pos = f2->f_pos = 0;
442
        f1->f_flags = O_RDONLY;
443
        f1->f_op = &read_pipe_fops;
444
        f1->f_mode = 1;
445
        /* write file */
446
        f2->f_flags = O_WRONLY;
447
        f2->f_op = &write_pipe_fops;
448
        f2->f_mode = 2;
449
        current->files->fd[i] = f1;
450
        current->files->fd[j] = f2;
451
        fd[0] = i;
452
        fd[1] = j;
453
        return 0;
454
 
455
close_f12_inode_i:
456
        put_unused_fd(i);
457
close_f12_inode:
458
        inode->i_count--;
459
        iput(inode);
460
close_f12:
461
        f2->f_count--;
462
close_f1:
463
        f1->f_count--;
464
no_files:
465
        return error;
466
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.