Skip to content

Commit

Permalink
flag parameters: eventfd
Browse files Browse the repository at this point in the history
This patch adds the new eventfd2 syscall.  It extends the old eventfd
syscall by one parameter which is meant to hold a flag value.  In this
patch the only flag support is EFD_CLOEXEC which causes the close-on-exec
flag for the returned file descriptor to be set.

A new name EFD_CLOEXEC is introduced which in this implementation must
have the same value as O_CLOEXEC.

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_CLOEXEC O_CLOEXEC

int
main (void)
{
  int fd = syscall (__NR_eventfd2, 1, 0);
  if (fd == -1)
    {
      puts ("eventfd2(0) failed");
      return 1;
    }
  int coe = fcntl (fd, F_GETFD);
  if (coe == -1)
    {
      puts ("fcntl failed");
      return 1;
    }
  if (coe & FD_CLOEXEC)
    {
      puts ("eventfd2(0) sets close-on-exec flag");
      return 1;
    }
  close (fd);

  fd = syscall (__NR_eventfd2, 1, EFD_CLOEXEC);
  if (fd == -1)
    {
      puts ("eventfd2(EFD_CLOEXEC) failed");
      return 1;
    }
  coe = fcntl (fd, F_GETFD);
  if (coe == -1)
    {
      puts ("fcntl failed");
      return 1;
    }
  if ((coe & FD_CLOEXEC) == 0)
    {
      puts ("eventfd2(EFD_CLOEXEC) does not set close-on-exec flag");
      return 1;
    }
  close (fd);

  puts ("OK");

  return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

[akpm@linux-foundation.org: add sys_ni stub]
Signed-off-by: Ulrich Drepper <drepper@redhat.com>
Acked-by: Davide Libenzi <davidel@xmailserver.org>
Cc: Michael Kerrisk <mtk.manpages@googlemail.com>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ulrich Drepper authored and torvalds committed Jul 24, 2008
1 parent 9deb27b commit b087498
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions arch/x86/ia32/ia32entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -827,4 +827,5 @@ ia32_sys_call_table:
.quad compat_sys_timerfd_settime /* 325 */
.quad compat_sys_timerfd_gettime
.quad compat_sys_signalfd4
.quad sys_eventfd2
ia32_syscall_end:
1 change: 1 addition & 0 deletions arch/x86/kernel/syscall_table_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,4 @@ ENTRY(sys_call_table)
.long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime
.long sys_signalfd4
.long sys_eventfd2
13 changes: 11 additions & 2 deletions fs/eventfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,14 @@ struct file *eventfd_fget(int fd)
return file;
}

asmlinkage long sys_eventfd(unsigned int count)
asmlinkage long sys_eventfd2(unsigned int count, int flags)
{
int fd;
struct eventfd_ctx *ctx;

if (flags & ~EFD_CLOEXEC)
return -EINVAL;

ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
Expand All @@ -214,9 +217,15 @@ asmlinkage long sys_eventfd(unsigned int count)
* When we call this, the initialization must be complete, since
* anon_inode_getfd() will install the fd.
*/
fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx, 0);
fd = anon_inode_getfd("[eventfd]", &eventfd_fops, ctx,
flags & O_CLOEXEC);
if (fd < 0)
kfree(ctx);
return fd;
}

asmlinkage long sys_eventfd(unsigned int count)
{
return sys_eventfd2(count, 0);
}

1 change: 1 addition & 0 deletions include/asm-x86/unistd_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@
#define __NR_timerfd_settime 325
#define __NR_timerfd_gettime 326
#define __NR_signalfd4 327
#define __NR_eventfd2 328

#ifdef __KERNEL__

Expand Down
2 changes: 2 additions & 0 deletions include/asm-x86/unistd_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,8 @@ __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
__SYSCALL(__NR_paccept, sys_paccept)
#define __NR_signalfd4 289
__SYSCALL(__NR_signalfd4, sys_signalfd4)
#define __NR_eventfd2 290
__SYSCALL(__NR_eventfd2, sys_eventfd2)


#ifndef __NO_STUBS
Expand Down
6 changes: 6 additions & 0 deletions include/linux/eventfd.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

#ifdef CONFIG_EVENTFD

/* For O_CLOEXEC */
#include <linux/fcntl.h>

/* Flags for eventfd2. */
#define EFD_CLOEXEC O_CLOEXEC

struct file *eventfd_fget(int fd);
int eventfd_signal(struct file *file, int n);

Expand Down
1 change: 1 addition & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,7 @@ asmlinkage long sys_timerfd_settime(int ufd, int flags,
struct itimerspec __user *otmr);
asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr);
asmlinkage long sys_eventfd(unsigned int count);
asmlinkage long sys_eventfd2(unsigned int count, int flags);
asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);

int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
Expand Down
1 change: 1 addition & 0 deletions kernel/sys_ni.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,4 @@ cond_syscall(sys_timerfd_gettime);
cond_syscall(compat_sys_timerfd_settime);
cond_syscall(compat_sys_timerfd_gettime);
cond_syscall(sys_eventfd);
cond_syscall(sys_eventfd2);

0 comments on commit b087498

Please sign in to comment.