diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-07-24 00:29:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-24 13:47:29 -0400 |
commit | e7d476dfdf0bcfed478a207aecfdc84f81efecaf (patch) | |
tree | 8adc7f4cf562cd0e283d4abdaa0633686a59d8b2 | |
parent | 5fb5e04926a54bc1c22bba7ca166840f4476196f (diff) |
flag parameters: NONBLOCK in eventfd
This patch adds support for the EFD_NONBLOCK flag to eventfd2. The
additional changes needed are minimal.
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_eventfd2
# ifdef __x86_64__
# define __NR_eventfd2 290
# elif defined __i386__
# define __NR_eventfd2 328
# else
# error "need __NR_eventfd2"
# endif
#endif
#define EFD_NONBLOCK O_NONBLOCK
int
main (void)
{
int fd = syscall (__NR_eventfd2, 1, 0);
if (fd == -1)
{
puts ("eventfd2(0) failed");
return 1;
}
int fl = fcntl (fd, F_GETFL);
if (fl == -1)
{
puts ("fcntl failed");
return 1;
}
if (fl & O_NONBLOCK)
{
puts ("eventfd2(0) sets non-blocking mode");
return 1;
}
close (fd);
fd = syscall (__NR_eventfd2, 1, EFD_NONBLOCK);
if (fd == -1)
{
puts ("eventfd2(EFD_NONBLOCK) failed");
return 1;
}
fl = fcntl (fd, F_GETFL);
if (fl == -1)
{
puts ("fcntl failed");
return 1;
}
if ((fl & O_NONBLOCK) == 0)
{
puts ("eventfd2(EFD_NONBLOCK) does not set non-blocking mode");
return 1;
}
close (fd);
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/eventfd.c | 4 | ||||
-rw-r--r-- | include/linux/eventfd.h | 3 |
2 files changed, 4 insertions, 3 deletions
diff --git a/fs/eventfd.c b/fs/eventfd.c index bd420e6478ad..3ed4466177a7 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c | |||
@@ -203,7 +203,7 @@ asmlinkage long sys_eventfd2(unsigned int count, int flags) | |||
203 | int fd; | 203 | int fd; |
204 | struct eventfd_ctx *ctx; | 204 | struct eventfd_ctx *ctx; |
205 | 205 | ||
206 | if (flags & ~EFD_CLOEXEC) | 206 | if (flags & ~(EFD_CLOEXEC | EFD_NONBLOCK)) |
207 | return -EINVAL; | 207 | return -EINVAL; |
208 | 208 | ||
209 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); | 209 | ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); |
@@ -218,7 +218,7 @@ asmlinkage long sys_eventfd2(unsigned int count, int flags) | |||
218 | * anon_inode_getfd() will install the fd. | 218 | * anon_inode_getfd() will install the fd. |
219 | */ | 219 | */ |
220 | fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx, | 220 | fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx, |
221 | flags & O_CLOEXEC); | 221 | flags & (O_CLOEXEC | O_NONBLOCK)); |
222 | if (fd < 0) | 222 | if (fd < 0) |
223 | kfree(ctx); | 223 | kfree(ctx); |
224 | return fd; | 224 | return fd; |
diff --git a/include/linux/eventfd.h b/include/linux/eventfd.h index a6c0eaedb1b0..a667637b54e3 100644 --- a/include/linux/eventfd.h +++ b/include/linux/eventfd.h | |||
@@ -10,11 +10,12 @@ | |||
10 | 10 | ||
11 | #ifdef CONFIG_EVENTFD | 11 | #ifdef CONFIG_EVENTFD |
12 | 12 | ||
13 | /* For O_CLOEXEC */ | 13 | /* For O_CLOEXEC and O_NONBLOCK */ |
14 | #include <linux/fcntl.h> | 14 | #include <linux/fcntl.h> |
15 | 15 | ||
16 | /* Flags for eventfd2. */ | 16 | /* Flags for eventfd2. */ |
17 | #define EFD_CLOEXEC O_CLOEXEC | 17 | #define EFD_CLOEXEC O_CLOEXEC |
18 | #define EFD_NONBLOCK O_NONBLOCK | ||
18 | 19 | ||
19 | struct file *eventfd_fget(int fd); | 20 | struct file *eventfd_fget(int fd); |
20 | int eventfd_signal(struct file *file, int n); | 21 | int eventfd_signal(struct file *file, int n); |