aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
authorDavide Libenzi <davidel@xmailserver.org>2007-05-11 01:23:13 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-11 11:29:36 -0400
commitfba2afaaec790dc5ab4ae8827972f342211bbb86 (patch)
tree2694d4cd8c6b7d69a5569b92151d61a3d4af39b7 /kernel/signal.c
parent5dc8bf8132d59c03fe2562bce165c2f03f021687 (diff)
signal/timer/event: signalfd core
This patch series implements the new signalfd() system call. I took part of the original Linus code (and you know how badly it can be broken :), and I added even more breakage ;) Signals are fetched from the same signal queue used by the process, so signalfd will compete with standard kernel delivery in dequeue_signal(). If you want to reliably fetch signals on the signalfd file, you need to block them with sigprocmask(SIG_BLOCK). This seems to be working fine on my Dual Opteron machine. I made a quick test program for it: http://www.xmailserver.org/signafd-test.c The signalfd() system call implements signal delivery into a file descriptor receiver. The signalfd file descriptor if created with the following API: int signalfd(int ufd, const sigset_t *mask, size_t masksize); The "ufd" parameter allows to change an existing signalfd sigmask, w/out going to close/create cycle (Linus idea). Use "ufd" == -1 if you want a brand new signalfd file. The "mask" allows to specify the signal mask of signals that we are interested in. The "masksize" parameter is the size of "mask". The signalfd fd supports the poll(2) and read(2) system calls. The poll(2) will return POLLIN when signals are available to be dequeued. As a direct consequence of supporting the Linux poll subsystem, the signalfd fd can use used together with epoll(2) too. The read(2) system call will return a "struct signalfd_siginfo" structure in the userspace supplied buffer. The return value is the number of bytes copied in the supplied buffer, or -1 in case of error. The read(2) call can also return 0, in case the sighand structure to which the signalfd was attached, has been orphaned. The O_NONBLOCK flag is also supported, and read(2) will return -EAGAIN in case no signal is available. If the size of the buffer passed to read(2) is lower than sizeof(struct signalfd_siginfo), -EINVAL is returned. A read from the signalfd can also return -ERESTARTSYS in case a signal hits the process. The format of the struct signalfd_siginfo is, and the valid fields depends of the (->code & __SI_MASK) value, in the same way a struct siginfo would: struct signalfd_siginfo { __u32 signo; /* si_signo */ __s32 err; /* si_errno */ __s32 code; /* si_code */ __u32 pid; /* si_pid */ __u32 uid; /* si_uid */ __s32 fd; /* si_fd */ __u32 tid; /* si_fd */ __u32 band; /* si_band */ __u32 overrun; /* si_overrun */ __u32 trapno; /* si_trapno */ __s32 status; /* si_status */ __s32 svint; /* si_int */ __u64 svptr; /* si_ptr */ __u64 utime; /* si_utime */ __u64 stime; /* si_stime */ __u64 addr; /* si_addr */ }; [akpm@linux-foundation.org: fix signalfd_copyinfo() on i386] Signed-off-by: Davide Libenzi <davidel@xmailserver.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 2ac3a668d9dd..34b7d6abce8f 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -21,6 +21,7 @@
21#include <linux/syscalls.h> 21#include <linux/syscalls.h>
22#include <linux/ptrace.h> 22#include <linux/ptrace.h>
23#include <linux/signal.h> 23#include <linux/signal.h>
24#include <linux/signalfd.h>
24#include <linux/capability.h> 25#include <linux/capability.h>
25#include <linux/freezer.h> 26#include <linux/freezer.h>
26#include <linux/pid_namespace.h> 27#include <linux/pid_namespace.h>
@@ -113,8 +114,7 @@ void recalc_sigpending(void)
113 114
114/* Given the mask, find the first available signal that should be serviced. */ 115/* Given the mask, find the first available signal that should be serviced. */
115 116
116static int 117int next_signal(struct sigpending *pending, sigset_t *mask)
117next_signal(struct sigpending *pending, sigset_t *mask)
118{ 118{
119 unsigned long i, *s, *m, x; 119 unsigned long i, *s, *m, x;
120 int sig = 0; 120 int sig = 0;
@@ -630,6 +630,12 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
630 int ret = 0; 630 int ret = 0;
631 631
632 /* 632 /*
633 * Deliver the signal to listening signalfds. This must be called
634 * with the sighand lock held.
635 */
636 signalfd_notify(t, sig);
637
638 /*
633 * fast-pathed signals for kernel-internal things like SIGSTOP 639 * fast-pathed signals for kernel-internal things like SIGSTOP
634 * or SIGKILL. 640 * or SIGKILL.
635 */ 641 */
@@ -1280,6 +1286,11 @@ int send_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1280 ret = 1; 1286 ret = 1;
1281 goto out; 1287 goto out;
1282 } 1288 }
1289 /*
1290 * Deliver the signal to listening signalfds. This must be called
1291 * with the sighand lock held.
1292 */
1293 signalfd_notify(p, sig);
1283 1294
1284 list_add_tail(&q->list, &p->pending.list); 1295 list_add_tail(&q->list, &p->pending.list);
1285 sigaddset(&p->pending.signal, sig); 1296 sigaddset(&p->pending.signal, sig);
@@ -1323,6 +1334,11 @@ send_group_sigqueue(int sig, struct sigqueue *q, struct task_struct *p)
1323 q->info.si_overrun++; 1334 q->info.si_overrun++;
1324 goto out; 1335 goto out;
1325 } 1336 }
1337 /*
1338 * Deliver the signal to listening signalfds. This must be called
1339 * with the sighand lock held.
1340 */
1341 signalfd_notify(p, sig);
1326 1342
1327 /* 1343 /*
1328 * Put this signal on the shared-pending queue. 1344 * Put this signal on the shared-pending queue.
@@ -1983,6 +1999,8 @@ int copy_siginfo_to_user(siginfo_t __user *to, siginfo_t *from)
1983 /* 1999 /*
1984 * If you change siginfo_t structure, please be sure 2000 * If you change siginfo_t structure, please be sure
1985 * this code is fixed accordingly. 2001 * this code is fixed accordingly.
2002 * Please remember to update the signalfd_copyinfo() function
2003 * inside fs/signalfd.c too, in case siginfo_t changes.
1986 * It should never copy any pad contained in the structure 2004 * It should never copy any pad contained in the structure
1987 * to avoid security leaks, but must copy the generic 2005 * to avoid security leaks, but must copy the generic
1988 * 3 ints plus the relevant union member. 2006 * 3 ints plus the relevant union member.