flag parameters: signalfd
Subsystems (5)
PATCH 4/18 flag parameters: signalfd
This patch adds the new signalfd4 syscall. It extends the old signalfd syscall by one parameter which is meant to hold a flag value. In this patch the only flag support is SFD_CLOEXEC which causes the close-on-exec flag for the returned file descriptor to be set.
A new name SFD_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 <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#ifndef __NR_signalfd4
# ifdef __x86_64__ # define __NR_signalfd4 289 # elif defined __i386__ # define __NR_signalfd4 327 # else # error "need __NR_signalfd4" # endif #endif
#define SFD_CLOEXEC O_CLOEXEC
int
main (void)
{
sigset_t ss;
sigemptyset (&ss);
sigaddset (&ss, SIGUSR1);
int fd = syscall (__NR_signalfd4, -1, &ss, 8, 0); if (fd == -1)
{
puts ("signalfd4(0) failed");
return 1;
}
int coe = fcntl (fd, F_GETFD);
if (coe == -1)
{
puts ("fcntl failed");
return 1;
}
if (coe & FD_CLOEXEC)
{
puts ("signalfd4(0) set close-on-exec flag");
return 1;
}close (fd);
fd = syscall (__NR_signalfd4, -1, &ss, 8, SFD_CLOEXEC);
if (fd == -1)
{
puts ("signalfd4(SFD_CLOEXEC) failed");
return 1;
}
coe = fcntl (fd, F_GETFD);
if (coe == -1)
{
puts ("fcntl failed");
return 1;
}
if ((coe & FD_CLOEXEC) == 0)
{
puts ("signalfd4(SFD_CLOEXEC) does not set close-on-exec flag");
return 1;
}
close (fd);
puts ("OK"); return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/x86/ia32/ia32entry.S | 1 + arch/x86/kernel/syscall_table_32.S | 1 + fs/compat.c | 14 ++++++++++---- fs/signalfd.c | 14 ++++++++++++-- include/asm-x86/unistd_32.h | 1 + include/asm-x86/unistd_64.h | 2 ++ include/linux/signalfd.h | 5 +++++ include/linux/syscalls.h | 1 + 8 files changed, 33 insertions(+), 6 deletions(-)
arch/x86/ia32/ia32entry.S +1 -0
@@ -731,4 +731,5 @@ ia32_sys_call_table: .quad sys32_fallocate .quad compat_sys_timerfd_settime /* 325 */ .quad compat_sys_timerfd_gettime + .quad compat_sys_signalfd4 ia32_syscall_end:
arch/x86/kernel/syscall_table_32.S +1 -0
@@ -326,3 +326,4 @@ ENTRY(sys_call_table) .long sys_fallocate .long sys_timerfd_settime /* 325 */ .long sys_timerfd_gettime + .long sys_signalfd4
fs/compat.c +10 -4
@@ -2131,9 +2131,9 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,#ifdef CONFIG_SIGNALFD -asmlinkage long compat_sys_signalfd (int ufd, -const compat_sigset_t __user *sigmask, -compat_size_t sigsetsize) +asmlinkage long compat_sys_signalfd4 (int ufd, +const compat_sigset_t __user *sigmask, +compat_size_t sigsetsize,int flags) {compat_sigset_t ss32;sigset_t tmp;
@@ -2148,9 +2148,15 @@ asmlinkage long compat_sys_signalfd(int ufd,if (copy_to_user (ksigmask, &tmp,sizeof (sigset_t)))return -EFAULT ; - return sys_signalfd(ufd, ksigmask, sizeof(sigset_t)); + return sys_signalfd4(ufd, ksigmask, sizeof(sigset_t), flags); } +asmlinkage long compat_sys_signalfd (int ufd, +const compat_sigset_t __user *sigmask, +compat_size_t sigsetsize) +{ +return compat_sys_signalfd4 (ufd, sigmask, sigsetsize,0 ); +}#endif /* CONFIG_SIGNALFD */ #ifdef CONFIG_TIMERFD
fs/signalfd.c +12 -2
@@ -205,11 +205,15 @@ static const struct file_operations signalfd_fops = { .read = signalfd_read, }; -asmlinkage long sys_signalfd (int ufd,sigset_t __user *user_mask,size_t sizemask) +asmlinkage long sys_signalfd4 (int ufd,sigset_t __user *user_mask, +size_t sizemask,int flags) {sigset_t sigmask;struct signalfd_ctx *ctx; +if (flags & ~SFD_CLOEXEC ) +return -EINVAL ; +if (sizemask !=sizeof (sigset_t) ||copy_from_user (&sigmask, user_mask,sizeof (sigmask)))return -EINVAL ;
@@ -228,7 +232,7 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas* anon_inode_getfd() will install the fd. */ ufd =anon_inode_getfd ("[signalfd]" , &signalfd_fops, ctx, -0 ); + flags &O_CLOEXEC );if (ufd <0 )kfree (ctx); }else {
@@ -250,3 +254,9 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemasreturn ufd; } + +asmlinkage long sys_signalfd (int ufd,sigset_t __user *user_mask, +size_t sizemask) +{ +return sys_signalfd4 (ufd, user_mask, sizemask,0 ); +}
include/asm-x86/unistd_32.h +1 -0
@@ -332,6 +332,7 @@#define __NR_fallocate 324#define __NR_timerfd_settime 325#define __NR_timerfd_gettime 326 +#define __NR_signalfd4 327#ifdef __KERNEL__
include/asm-x86/unistd_64.h +2 -0
@@ -641,6 +641,8 @@ __SYSCALL(__NR_timerfd_settime, sys_timerfd_settime) __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)#define __NR_paccept 288 __SYSCALL(__NR_paccept, sys_paccept) +#define __NR_signalfd4 289 +__SYSCALL(__NR_signalfd4, sys_signalfd4)#ifndef __NO_STUBS
include/linux/signalfd.h +5 -0
@@ -8,6 +8,11 @@ #ifndef _LINUX_SIGNALFD_H #define _LINUX_SIGNALFD_H +/* For O_CLOEXEC */ +#include <linux/fcntl.h> + +/* Flags for signalfd4. */ +#define SFD_CLOEXEC O_CLOEXEC struct signalfd_siginfo { __u32 ssi_signo;
include/linux/syscalls.h +1 -0
@@ -610,6 +610,7 @@ asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, size_t len);asmlinkage long sys_getcpu (unsigned __user *cpu,unsigned __user *node,struct getcpu_cache __user *cache);asmlinkage long sys_signalfd (int ufd,sigset_t __user *user_mask,size_t sizemask); +asmlinkage long sys_signalfd4 (int ufd,sigset_t __user *user_mask,size_t sizemask,int flags);asmlinkage long sys_timerfd_create (int clockid,int flags); asmlinkage long sys_timerfd_settime(int ufd, int flags, const struct itimerspec __user *utmr,
PATCH 1/1 signalfd: fix undefined reference to `compat_sys_signalfd4'
Quoted 4 lines · Ulrich Drepper
This patch adds the new signalfd4 syscall. It extends the old signalfd syscall by one parameter which is meant to hold a flag value. In this patch the only flag support is
SFD_CLOEXECwhich causes the close-on-exec flag for the returned file descriptor to be set.
this patch causes the following build failure on !CONFIG_SIGNALFD:
arch/x86/ia32/built-in.o: In function `ia32_sys_call_table':
(.rodata+0xa38): undefined reference to `compat_sys_signalfd4'
make: *** [.tmp_vmlinux1] Error 1
tested fix below.
Ingo
-------------->
Quoted 1 line
From
72dc5d608422e80ad5e1aac2d7b9bd16b7dbc6e0Mon Sep 17 00:00:00 2001
From: Ingo Molnar <[email protected]>
Date: Fri, 25 Jul 2008 13:02:37 +0200
Subject: [PATCH] signalfd: fix undefined reference to `compat_sys_signalfd4'
fix:
arch/x86/ia32/built-in.o: In function `ia32_sys_call_table':
(.rodata+0xa38): undefined reference to `compat_sys_signalfd4'
on !CONFIG_SIGNALFD.
--- kernel/sys_ni.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
kernel/sys_ni.c +1 -0
@@ -160,6 +160,7 @@ cond_syscall(sys_ioprio_get);cond_syscall (sys_signalfd);cond_syscall (sys_signalfd4);cond_syscall (compat_sys_signalfd); +cond_syscall (compat_sys_signalfd4);cond_syscall (sys_timerfd_create);cond_syscall (sys_timerfd_settime);cond_syscall (sys_timerfd_gettime);