summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2003-06-28 08:03:28 +0000
committerdavidxu <davidxu@FreeBSD.org>2003-06-28 08:03:28 +0000
commitc6c7b174d12ff38291e766e66f3e7e7b39ea08f8 (patch)
treed88022741941bbca185be8cf1dad306057200428 /sys/kern
parent85b26b35b8202afb5818cf6e82cd33ff981328e6 (diff)
downloadFreeBSD-src-c6c7b174d12ff38291e766e66f3e7e7b39ea08f8.zip
FreeBSD-src-c6c7b174d12ff38291e766e66f3e7e7b39ea08f8.tar.gz
Fix POSIX compatible bug for sigwaitinfo and sigtimedwait.
POSIX says siginfo pointer parameter can be NULL and if the function success, it should return signal number but not zero. The waitset it past should be negatived before it can be used as thread signal mask.
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/kern_sig.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index ec176a2..b2ce6a8 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -776,13 +776,15 @@ sigtimedwait(struct thread *td, struct sigtimedwait_args *uap)
error = kern_sigtimedwait(td, set, &info, timeout);
if (error)
return (error);
-
- error = copyout(&info, uap->info, sizeof(info));
+ if (uap->info)
+ error = copyout(&info, uap->info, sizeof(info));
/* Repost if we got an error. */
if (error && info.si_signo) {
PROC_LOCK(td->td_proc);
tdsignal(td, info.si_signo);
PROC_UNLOCK(td->td_proc);
+ } else {
+ td->td_retval[0] = info.si_signo;
}
return (error);
}
@@ -805,12 +807,15 @@ sigwaitinfo(struct thread *td, struct sigwaitinfo_args *uap)
if (error)
return (error);
- error = copyout(&info, uap->info, sizeof(info));
+ if (uap->info)
+ error = copyout(&info, uap->info, sizeof(info));
/* Repost if we got an error. */
if (error && info.si_signo) {
PROC_LOCK(td->td_proc);
tdsignal(td, info.si_signo);
PROC_UNLOCK(td->td_proc);
+ } else {
+ td->td_retval[0] = info.si_signo;
}
return (error);
}
@@ -834,7 +839,9 @@ kern_sigtimedwait(struct thread *td, sigset_t set, siginfo_t *info,
PROC_LOCK(p);
ps = p->p_sigacts;
oldmask = td->td_sigmask;
- td->td_sigmask = set;
+ SIGFILLSET(td->td_sigmask);
+ SIG_CANTMASK(td->td_sigmask);
+ SIGSETNAND(td->td_sigmask, set);
signotify(td);
mtx_lock(&ps->ps_mtx);
OpenPOWER on IntegriCloud