summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/librthread/rthread.h4
-rw-r--r--lib/librthread/rthread_sig.c5
-rw-r--r--sys/kern/kern_sig.c32
-rw-r--r--sys/kern/syscalls.master5
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