diff options
-rw-r--r-- | lib/librthread/rthread.h | 4 | ||||
-rw-r--r-- | lib/librthread/rthread_sig.c | 5 | ||||
-rw-r--r-- | sys/kern/kern_sig.c | 32 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 5 |
4 files changed, 37 insertions, 9 deletions
diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h index 29102eb6ce7..21a8c165365 100644 --- a/lib/librthread/rthread.h +++ b/lib/librthread/rthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.h,v 1.23 2009/11/27 19:42:24 guenther Exp $ */ +/* $OpenBSD: rthread.h,v 1.24 2009/11/27 19:43:55 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -169,4 +169,4 @@ void threxit(pid_t *); int thrsleep(void *, int, void *); int thrwakeup(void *, int n); int sched_yield(void); -int thrsigdivert(sigset_t); +int thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); diff --git a/lib/librthread/rthread_sig.c b/lib/librthread/rthread_sig.c index 1437e2a0c97..392e20c43e9 100644 --- a/lib/librthread/rthread_sig.c +++ b/lib/librthread/rthread_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_sig.c,v 1.7 2009/02/20 02:38:57 guenther Exp $ */ +/* $OpenBSD: rthread_sig.c,v 1.8 2009/11/27 19:43:55 guenther Exp $ */ /* * Copyright (c) 2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -47,9 +47,10 @@ sigwait(const sigset_t *set, int *sig) { int ret; - ret = thrsigdivert(*set); + ret = thrsigdivert(*set, NULL, NULL); if (ret == -1) return errno; *sig = ret; return 0; } + diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c index 29d7d4344ba..440e922c18c 100644 --- a/sys/kern/kern_sig.c +++ b/sys/kern/kern_sig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sig.c,v 1.106 2009/11/04 19:14:10 kettenis Exp $ */ +/* $OpenBSD: kern_sig.c,v 1.107 2009/11/27 19:43:55 guenther Exp $ */ /* $NetBSD: kern_sig.c,v 1.54 1996/04/22 01:38:32 christos Exp $ */ /* @@ -1557,9 +1557,12 @@ sys_thrsigdivert(struct proc *p, void *v, register_t *retval) { struct sys_thrsigdivert_args /* { syscallarg(sigset_t) sigmask; + syscallarg(siginfo_t *) info; + syscallarg(const struct timespec *) timeout; } */ *uap = v; sigset_t mask; sigset_t *m; + long long to_ticks = 0; int error; m = NULL; @@ -1577,21 +1580,44 @@ sys_thrsigdivert(struct proc *p, void *v, register_t *retval) return (0); } + if (SCARG(uap, timeout) != NULL) { + struct timespec ts; + if ((error = copyin(SCARG(uap, timeout), &ts, sizeof(ts))) != 0) + return (error); + to_ticks = (long long)hz * ts.tv_sec + + ts.tv_nsec / (tick * 1000); + if (to_ticks > INT_MAX) + to_ticks = INT_MAX; + } + p->p_sigwait = 0; atomic_setbits_int(&p->p_sigdivert, mask); - error = tsleep(&p->p_sigdivert, PPAUSE|PCATCH, "sigwait", 0); + error = tsleep(&p->p_sigdivert, PPAUSE|PCATCH, "sigwait", + (int)to_ticks); if (p->p_sigdivert) { /* interrupted */ KASSERT(error != 0); atomic_clearbits_int(&p->p_sigdivert, ~0); if (error == EINTR) error = ERESTART; + else if (error == ETIMEDOUT) + error = EAGAIN; return (error); } KASSERT(p->p_sigwait != 0); *retval = p->p_sigwait; - return (0); + + if (SCARG(uap, info) == NULL) { + error = 0; + } else { + siginfo_t si; + + bzero(&si, sizeof si); + si.si_signo = p->p_sigwait; + error = copyout(&si, SCARG(uap, info), sizeof(si)); + } + return (error); } #endif diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index a4d507d5f0e..7692a85edce 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.94 2009/11/27 19:42:24 guenther Exp $ +; $OpenBSD: syscalls.master,v 1.95 2009/11/27 19:43:55 guenther Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -600,7 +600,8 @@ 300 STD { int sys_thrsleep(void *ident, int timeout, void *lock); } 301 STD { int sys_thrwakeup(void *ident, int n); } 302 STD { void sys_threxit(pid_t *notdead); } -303 STD { int sys_thrsigdivert(sigset_t sigmask); } +303 STD { int sys_thrsigdivert(sigset_t sigmask, \ + siginfo_t *info, const struct timespec *timeout); } #else 299 UNIMPL 300 UNIMPL |