diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-07-24 00:29:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:29 -0400 |
commit | be61a86d7237dd80510615f38ae21d6e1e98660c (patch) | |
tree | 3dfe6c8275c724533f88525970a4065ae795f6e3 | |
parent | 6b1ef0e60d42f2fdaec26baee8327eb156347b4f (diff) |
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>
-rw-r--r-- | fs/pipe.c | 14 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | kernel/kmod.c | 4 |
3 files changed, 11 insertions, 11 deletions
@@ -950,7 +950,7 @@ fail_inode: | |||
950 | return NULL; | 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 | int err; | 955 | int err; |
956 | struct inode *inode; | 956 | struct inode *inode; |
@@ -983,7 +983,7 @@ struct file *create_write_pipe(void) | |||
983 | goto err_dentry; | 983 | goto err_dentry; |
984 | f->f_mapping = inode->i_mapping; | 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 | f->f_version = 0; | 987 | f->f_version = 0; |
988 | 988 | ||
989 | return f; | 989 | return f; |
@@ -1007,7 +1007,7 @@ void free_write_pipe(struct file *f) | |||
1007 | put_filp(f); | 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 | struct file *f = get_empty_filp(); | 1012 | struct file *f = get_empty_filp(); |
1013 | if (!f) | 1013 | if (!f) |
@@ -1019,7 +1019,7 @@ struct file *create_read_pipe(struct file *wrf) | |||
1019 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; | 1019 | f->f_mapping = wrf->f_path.dentry->d_inode->i_mapping; |
1020 | 1020 | ||
1021 | f->f_pos = 0; | 1021 | f->f_pos = 0; |
1022 | f->f_flags = O_RDONLY; | 1022 | f->f_flags = O_RDONLY | (flags & O_NONBLOCK); |
1023 | f->f_op = &read_pipe_fops; | 1023 | f->f_op = &read_pipe_fops; |
1024 | f->f_mode = FMODE_READ; | 1024 | f->f_mode = FMODE_READ; |
1025 | f->f_version = 0; | 1025 | f->f_version = 0; |
@@ -1033,13 +1033,13 @@ int do_pipe_flags(int *fd, int flags) | |||
1033 | int error; | 1033 | int error; |
1034 | int fdw, fdr; | 1034 | int fdw, fdr; |
1035 | 1035 | ||
1036 | if (flags & ~O_CLOEXEC) | 1036 | if (flags & ~(O_CLOEXEC | O_NONBLOCK)) |
1037 | return -EINVAL; | 1037 | return -EINVAL; |
1038 | 1038 | ||
1039 | fw = create_write_pipe(); | 1039 | fw = create_write_pipe(flags); |
1040 | if (IS_ERR(fw)) | 1040 | if (IS_ERR(fw)) |
1041 | return PTR_ERR(fw); | 1041 | return PTR_ERR(fw); |
1042 | fr = create_read_pipe(fw); | 1042 | fr = create_read_pipe(fw, flags); |
1043 | error = PTR_ERR(fr); | 1043 | error = PTR_ERR(fr); |
1044 | if (IS_ERR(fr)) | 1044 | if (IS_ERR(fr)) |
1045 | goto err_write_pipe; | 1045 | goto err_write_pipe; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 0e80cd717d32..4b86f806014c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1778,8 +1778,8 @@ static inline void allow_write_access(struct file *file) | |||
1778 | } | 1778 | } |
1779 | extern int do_pipe(int *); | 1779 | extern int do_pipe(int *); |
1780 | extern int do_pipe_flags(int *, int); | 1780 | extern int do_pipe_flags(int *, int); |
1781 | extern struct file *create_read_pipe(struct file *f); | 1781 | extern struct file *create_read_pipe(struct file *f, int flags); |
1782 | extern struct file *create_write_pipe(void); | 1782 | extern struct file *create_write_pipe(int flags); |
1783 | extern void free_write_pipe(struct file *); | 1783 | extern void free_write_pipe(struct file *); |
1784 | 1784 | ||
1785 | extern struct file *do_filp_open(int dfd, const char *pathname, | 1785 | extern struct file *do_filp_open(int dfd, const char *pathname, |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 90d7af1c1655..2989f67c4446 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -417,12 +417,12 @@ int call_usermodehelper_stdinpipe(struct subprocess_info *sub_info, | |||
417 | { | 417 | { |
418 | struct file *f; | 418 | struct file *f; |
419 | 419 | ||
420 | f = create_write_pipe(); | 420 | f = create_write_pipe(0); |
421 | if (IS_ERR(f)) | 421 | if (IS_ERR(f)) |
422 | return PTR_ERR(f); | 422 | return PTR_ERR(f); |
423 | *filp = f; | 423 | *filp = f; |
424 | 424 | ||
425 | f = create_read_pipe(f); | 425 | f = create_read_pipe(f, 0); |
426 | if (IS_ERR(f)) { | 426 | if (IS_ERR(f)) { |
427 | free_write_pipe(*filp); | 427 | free_write_pipe(*filp); |
428 | return PTR_ERR(f); | 428 | return PTR_ERR(f); |