summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2009-11-27 19:43:56 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2009-11-27 19:43:56 +0000
commite3f7d63389bbfad1413bfd08d7127f0af07be069 (patch)
tree19644065275d0fa2476b93675b67395ee08e92b7 /sys
parentc84c43b4dd4a0b4fd392f5b5171ce683234649e4 (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.c32
-rw-r--r--sys/kern/syscalls.master5
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