summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_sig.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/kern_sig.c')
-rw-r--r--sys/kern/kern_sig.c34
1 files changed, 23 insertions, 11 deletions
diff --git a/sys/kern/kern_sig.c b/sys/kern/kern_sig.c
index fc3ab29..6677d69 100644
--- a/sys/kern/kern_sig.c
+++ b/sys/kern/kern_sig.c
@@ -1862,33 +1862,43 @@ struct sigqueue_args {
int
sys_sigqueue(struct thread *td, struct sigqueue_args *uap)
{
+ union sigval sv;
+
+ sv.sival_ptr = uap->value;
+
+ return (kern_sigqueue(td, uap->pid, uap->signum, &sv));
+}
+
+int
+kern_sigqueue(struct thread *td, pid_t pid, int signum, union sigval *value)
+{
ksiginfo_t ksi;
struct proc *p;
int error;
- if ((u_int)uap->signum > _SIG_MAXSIG)
+ if ((u_int)signum > _SIG_MAXSIG)
return (EINVAL);
/*
* Specification says sigqueue can only send signal to
* single process.
*/
- if (uap->pid <= 0)
+ if (pid <= 0)
return (EINVAL);
- if ((p = pfind(uap->pid)) == NULL) {
- if ((p = zpfind(uap->pid)) == NULL)
+ if ((p = pfind(pid)) == NULL) {
+ if ((p = zpfind(pid)) == NULL)
return (ESRCH);
}
- error = p_cansignal(td, p, uap->signum);
- if (error == 0 && uap->signum != 0) {
+ error = p_cansignal(td, p, signum);
+ if (error == 0 && signum != 0) {
ksiginfo_init(&ksi);
ksi.ksi_flags = KSI_SIGQ;
- ksi.ksi_signo = uap->signum;
+ ksi.ksi_signo = signum;
ksi.ksi_code = SI_QUEUE;
ksi.ksi_pid = td->td_proc->p_pid;
ksi.ksi_uid = td->td_ucred->cr_ruid;
- ksi.ksi_value.sival_ptr = uap->value;
+ ksi.ksi_value = *value;
error = pksignal(p, ksi.ksi_signo, &ksi);
}
PROC_UNLOCK(p);
@@ -2485,6 +2495,7 @@ sig_suspend_threads(struct thread *td, struct proc *p, int sending)
PROC_LOCK_ASSERT(p, MA_OWNED);
PROC_SLOCK_ASSERT(p, MA_OWNED);
+ MPASS(sending || td == curthread);
wakeup_swapper = 0;
FOREACH_THREAD_IN_PROC(p, td2) {
@@ -2501,10 +2512,9 @@ sig_suspend_threads(struct thread *td, struct proc *p, int sending)
*/
KASSERT(!TD_IS_SUSPENDED(td2),
("thread with deferred stops suspended"));
- if (TD_SBDRY_INTR(td2) && sending) {
+ if (TD_SBDRY_INTR(td2))
wakeup_swapper |= sleepq_abort(td2,
TD_SBDRY_ERRNO(td2));
- }
} else if (!TD_IS_SUSPENDED(td2)) {
thread_suspend_one(td2);
}
@@ -2654,7 +2664,9 @@ reschedule_signals(struct proc *p, sigset_t block, int flags)
signotify(td);
if (!(flags & SIGPROCMASK_PS_LOCKED))
mtx_lock(&ps->ps_mtx);
- if (p->p_flag & P_TRACED || SIGISMEMBER(ps->ps_sigcatch, sig))
+ if (p->p_flag & P_TRACED ||
+ (SIGISMEMBER(ps->ps_sigcatch, sig) &&
+ !SIGISMEMBER(td->td_sigmask, sig)))
tdsigwakeup(td, sig, SIG_CATCH,
(SIGISMEMBER(ps->ps_sigintr, sig) ? EINTR :
ERESTART));
OpenPOWER on IntegriCloud