Skip to content

Commit

Permalink
flag parameters: dup2
Browse files Browse the repository at this point in the history
This patch adds the new dup3 syscall.  It extends the old dup2 syscall by one
parameter which is meant to hold a flag value.  Support for the O_CLOEXEC flag
is added in this patch.

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 <time.h>
#include <unistd.h>
#include <sys/syscall.h>

#ifndef __NR_dup3
# ifdef __x86_64__
#  define __NR_dup3 292
# elif defined __i386__
#  define __NR_dup3 330
# else
#  error "need __NR_dup3"
# endif
#endif

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

  fd = syscall (__NR_dup3, 1, 4, O_CLOEXEC);
  if (fd == -1)
    {
      puts ("dup3(O_CLOEXEC) failed");
      return 1;
    }
  coe = fcntl (fd, F_GETFD);
  if (coe == -1)
    {
      puts ("fcntl failed");
      return 1;
    }
  if ((coe & FD_CLOEXEC) == 0)
    {
      puts ("dup3(O_CLOEXEC) set close-on-exec flag");
      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>
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 Linus Torvalds committed Jul 24, 2008
1 parent a0998b5 commit 336dd1f
Show file tree
Hide file tree
Showing 6 changed files with 19 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 @@ -829,4 +829,5 @@ ia32_sys_call_table:
.quad compat_sys_signalfd4
.quad sys_eventfd2
.quad sys_epoll_create2
.quad sys_dup3 /* 330 */
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 @@ -329,3 +329,4 @@ ENTRY(sys_call_table)
.long sys_signalfd4
.long sys_eventfd2
.long sys_epoll_create2
.long sys_dup3 /* 330 */
15 changes: 13 additions & 2 deletions fs/fcntl.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,16 @@ static int dupfd(struct file *file, unsigned int start, int cloexec)
return fd;
}

asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
{
int err = -EBADF;
struct file * file, *tofree;
struct files_struct * files = current->files;
struct fdtable *fdt;

if ((flags & ~O_CLOEXEC) != 0)
return -EINVAL;

spin_lock(&files->file_lock);
if (!(file = fcheck(oldfd)))
goto out_unlock;
Expand Down Expand Up @@ -163,7 +166,10 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)

rcu_assign_pointer(fdt->fd[newfd], file);
FD_SET(newfd, fdt->open_fds);
FD_CLR(newfd, fdt->close_on_exec);
if (flags & O_CLOEXEC)
FD_SET(newfd, fdt->close_on_exec);
else
FD_CLR(newfd, fdt->close_on_exec);
spin_unlock(&files->file_lock);

if (tofree)
Expand All @@ -181,6 +187,11 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
goto out;
}

asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
{
return sys_dup3(oldfd, newfd, 0);
}

asmlinkage long sys_dup(unsigned int fildes)
{
int ret = -EBADF;
Expand Down
1 change: 1 addition & 0 deletions include/asm-x86/unistd_32.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@
#define __NR_signalfd4 327
#define __NR_eventfd2 328
#define __NR_epoll_create2 329
#define __NR_dup3 330

#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 @@ -647,6 +647,8 @@ __SYSCALL(__NR_signalfd4, sys_signalfd4)
__SYSCALL(__NR_eventfd2, sys_eventfd2)
#define __NR_epoll_create2 291
__SYSCALL(__NR_epoll_create2, sys_epoll_create2)
#define __NR_dup3 292
__SYSCALL(__NR_dup3, sys_dup3)


#ifndef __NO_STUBS
Expand Down
1 change: 1 addition & 0 deletions include/linux/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ asmlinkage long sys_fcntl64(unsigned int fd,
#endif
asmlinkage long sys_dup(unsigned int fildes);
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);
asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags);
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int on);
asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd,
unsigned long arg);
Expand Down

0 comments on commit 336dd1f

Please sign in to comment.