Commit be61a86d7237dd80510615f38ae21d6e1e98660c
Committed by
Linus Torvalds
1 parent
6b1ef0e60d
Exists in
master
and in
4 other branches
flag parameters: NONBLOCK in pipe
This patch adds O_NONBLOCK support to pipe2. It is minimally more involved than the patches for eventfd et.al but still trivial. The interfaces of the create_write_pipe and create_read_pipe helper functions were changed and the one other caller as well. The following test must be adjusted for architectures other than x86 and x86-64 and in case the syscall numbers changed. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #include <fcntl.h> #include <stdio.h> #include <unistd.h> #include <sys/syscall.h> #ifndef __NR_pipe2 # ifdef __x86_64__ # define __NR_pipe2 293 # elif defined __i386__ # define __NR_pipe2 331 # else # error "need __NR_pipe2" # endif #endif int main (void) { int fds[2]; if (syscall (__NR_pipe2, fds, 0) == -1) { puts ("pipe2(0) failed"); return 1; } for (int i = 0; i < 2; ++i) { int fl = fcntl (fds[i], F_GETFL); if (fl == -1) { puts ("fcntl failed"); return 1; } if (fl & O_NONBLOCK) { printf ("pipe2(0) set non-blocking mode for fds[%d]\n", i); return 1; } close (fds[i]); } if (syscall (__NR_pipe2, fds, O_NONBLOCK) == -1) { puts ("pipe2(O_NONBLOCK) failed"); return 1; } for (int i = 0; i < 2; ++i) { int fl = fcntl (fds[i], F_GETFL); if (fl == -1) { puts ("fcntl failed"); return 1; } if ((fl & O_NONBLOCK) == 0) { printf ("pipe2(O_NONBLOCK) does not set non-blocking mode for fds[%d]\n", i); return 1; } close (fds[i]); } puts ("OK"); return 0; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Signed-off-by: Ulrich Drepper <drepper@redhat.com> Acked-by: Davide Libenzi <davidel@xmailserver.org> Cc: Michael Kerrisk <mtk.manpages@googlemail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 11 additions and 11 deletions Side-by-side Diff
fs/pipe.c
... | ... | @@ -950,7 +950,7 @@ |
950 | 950 | return NULL; |
951 | 951 | } |
952 | 952 | |
953 | -struct file *create_write_pipe(void) | |
953 | +struct file *create_write_pipe(int flags) | |
954 | 954 | { |
955 | 955 | int err; |
956 | 956 | struct inode *inode; |
... | ... | @@ -983,7 +983,7 @@ |
983 | 983 | goto err_dentry; |
984 | 984 | f->f_mapping = inode->i_mapping; |
985 | 985 | |
986 | - f->f_flags = O_WRONLY; | |
986 | + f->f_flags = O_WRONLY | (flags & O_NONBLOCK); | |
987 | 987 | f->f_version = 0; |
988 | 988 | |
989 | 989 | return f; |
... | ... | @@ -1007,7 +1007,7 @@ |
1007 | 1007 | put_filp(f); |
1008 | 1008 | } |
1009 | 1009 | |
1010 | -struct file *create_read_pipe(struct file *wrf) | |
1010 | +struct file *create_read_pipe(struct file *wrf, int flags) | |
1011 | 1011 | { |
1012 | 1012 | struct file *f = get_empty_filp(); |
1013 | 1013 | if (!f) |
... | ... | @@ -1019,7 +1019,7 @@ |
1019 | 1019 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; |
1020 | 1020 | |
1021 | 1021 | f->f_pos = 0; |
1022 | - f->f_flags = O_RDONLY; | |
1022 | + f->f_flags = O_RDONLY | (flags & O_NONBLOCK); | |
1023 | 1023 | f->f_op = &read_pipe_fops; |
1024 | 1024 | f->f_mode = FMODE_READ; |
1025 | 1025 | f->f_version = 0; |
1026 | 1026 | |
1027 | 1027 | |
... | ... | @@ -1033,13 +1033,13 @@ |
1033 | 1033 | int error; |
1034 | 1034 | int fdw, fdr; |
1035 | 1035 | |
1036 | - if (flags & ~O_CLOEXEC) | |
1036 | + if (flags & ~(O_CLOEXEC | O_NONBLOCK)) | |
1037 | 1037 | return -EINVAL; |
1038 | 1038 | |
1039 | - fw = create_write_pipe(); | |
1039 | + fw = create_write_pipe(flags); | |
1040 | 1040 | if (IS_ERR(fw)) |
1041 | 1041 | return PTR_ERR(fw); |
1042 | - fr = create_read_pipe(fw); | |
1042 | + fr = create_read_pipe(fw, flags); | |
1043 | 1043 | error = PTR_ERR(fr); |
1044 | 1044 | if (IS_ERR(fr)) |
1045 | 1045 | goto err_write_pipe; |
include/linux/fs.h
... | ... | @@ -1778,8 +1778,8 @@ |
1778 | 1778 | } |
1779 | 1779 | extern int do_pipe(int *); |
1780 | 1780 | extern int do_pipe_flags(int *, int); |
1781 | -extern struct file *create_read_pipe(struct file *f); | |
1782 | -extern struct file *create_write_pipe(void); | |
1781 | +extern struct file *create_read_pipe(struct file *f, int flags); | |
1782 | +extern struct file *create_write_pipe(int flags); | |
1783 | 1783 | extern void free_write_pipe(struct file *); |
1784 | 1784 | |
1785 | 1785 | extern struct file *do_filp_open(int dfd, const char *pathname, |
kernel/kmod.c
... | ... | @@ -417,12 +417,12 @@ |
417 | 417 | { |
418 | 418 | struct file *f; |
419 | 419 | |
420 | - f = create_write_pipe(); | |
420 | + f = create_write_pipe(0); | |
421 | 421 | if (IS_ERR(f)) |
422 | 422 | return PTR_ERR(f); |
423 | 423 | *filp = f; |
424 | 424 | |
425 | - f = create_read_pipe(f); | |
425 | + f = create_read_pipe(f, 0); | |
426 | 426 | if (IS_ERR(f)) { |
427 | 427 | free_write_pipe(*filp); |
428 | 428 | return PTR_ERR(f); |