diff options
author | davidxu <davidxu@FreeBSD.org> | 2003-06-28 08:03:28 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2003-06-28 08:03:28 +0000 |
commit | c6c7b174d12ff38291e766e66f3e7e7b39ea08f8 (patch) | |
tree | d88022741941bbca185be8cf1dad306057200428 /sys/kern | |
parent | 85b26b35b8202afb5818cf6e82cd33ff981328e6 (diff) | |
download | FreeBSD-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.c | 15 |
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); |