diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2009-11-27 19:43:56 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2009-11-27 19:43:56 +0000 |
commit | e3f7d63389bbfad1413bfd08d7127f0af07be069 (patch) | |
tree | 19644065275d0fa2476b93675b67395ee08e92b7 /sys | |
parent | c84c43b4dd4a0b4fd392f5b5171ce683234649e4 (diff) |
Convert thrsigdivert to (almost) be sigtimedwait by adding siginfo_t
and struct timespec * argument. sigtimedwait is just a one line
wrapper after this.
"get it in" deraadt@, tedu@, cheers by others
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kern/kern_sig.c | 32 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 5 |
2 files changed, 32 insertions, 5 deletions
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 |