svn commit: r276126 - stable/9/sys/kern
Konstantin Belousov
kib at FreeBSD.org
Tue Dec 23 10:07:25 UTC 2014
Author: kib
Date: Tue Dec 23 10:07:23 2014
New Revision: 276126
URL: https://svnweb.freebsd.org/changeset/base/276126
Log:
MFC r275120:
Fix SA_SIGINFO | SA_RESETHAND handling.
Modified:
stable/9/sys/kern/kern_sig.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/kern/kern_sig.c
==============================================================================
--- stable/9/sys/kern/kern_sig.c Tue Dec 23 09:46:23 2014 (r276125)
+++ stable/9/sys/kern/kern_sig.c Tue Dec 23 10:07:23 2014 (r276126)
@@ -1847,6 +1847,34 @@ pgsignal(struct pgrp *pgrp, int sig, int
}
}
+
+/*
+ * Recalculate the signal mask and reset the signal disposition after
+ * usermode frame for delivery is formed. Should be called after
+ * mach-specific routine, because sysent->sv_sendsig() needs correct
+ * ps_siginfo and signal mask.
+ */
+static void
+postsig_done(int sig, struct thread *td, struct sigacts *ps)
+{
+ sigset_t mask;
+
+ mtx_assert(&ps->ps_mtx, MA_OWNED);
+ td->td_ru.ru_nsignals++;
+ mask = ps->ps_catchmask[_SIG_IDX(sig)];
+ if (!SIGISMEMBER(ps->ps_signodefer, sig))
+ SIGADDSET(mask, sig);
+ kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
+ SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
+ if (SIGISMEMBER(ps->ps_sigreset, sig)) {
+ SIGDELSET(ps->ps_sigcatch, sig);
+ if (sig != SIGCONT &&
+ sigprop(sig) & SA_IGNORE)
+ SIGADDSET(ps->ps_sigignore, sig);
+ ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
+ }
+}
+
/*
* Send a signal caused by a trap to the current thread. If it will be
* caught immediately, deliver it with correct code. Otherwise, post it
@@ -1856,7 +1884,6 @@ void
trapsignal(struct thread *td, ksiginfo_t *ksi)
{
struct sigacts *ps;
- sigset_t mask;
struct proc *p;
int sig;
int code;
@@ -1871,7 +1898,6 @@ trapsignal(struct thread *td, ksiginfo_t
mtx_lock(&ps->ps_mtx);
if ((p->p_flag & P_TRACED) == 0 && SIGISMEMBER(ps->ps_sigcatch, sig) &&
!SIGISMEMBER(td->td_sigmask, sig)) {
- td->td_ru.ru_nsignals++;
#ifdef KTRACE
if (KTRPOINT(curthread, KTR_PSIG))
ktrpsig(sig, ps->ps_sigact[_SIG_IDX(sig)],
@@ -1879,21 +1905,7 @@ trapsignal(struct thread *td, ksiginfo_t
#endif
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[_SIG_IDX(sig)],
ksi, &td->td_sigmask);
- mask = ps->ps_catchmask[_SIG_IDX(sig)];
- if (!SIGISMEMBER(ps->ps_signodefer, sig))
- SIGADDSET(mask, sig);
- kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
- SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
- if (SIGISMEMBER(ps->ps_sigreset, sig)) {
- /*
- * See kern_sigaction() for origin of this code.
- */
- SIGDELSET(ps->ps_sigcatch, sig);
- if (sig != SIGCONT &&
- sigprop(sig) & SA_IGNORE)
- SIGADDSET(ps->ps_sigignore, sig);
- ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
- }
+ postsig_done(sig, td, ps);
mtx_unlock(&ps->ps_mtx);
} else {
/*
@@ -2779,7 +2791,7 @@ postsig(sig)
struct sigacts *ps;
sig_t action;
ksiginfo_t ksi;
- sigset_t returnmask, mask;
+ sigset_t returnmask;
KASSERT(sig != 0, ("postsig"));
@@ -2834,28 +2846,12 @@ postsig(sig)
} else
returnmask = td->td_sigmask;
- mask = ps->ps_catchmask[_SIG_IDX(sig)];
- if (!SIGISMEMBER(ps->ps_signodefer, sig))
- SIGADDSET(mask, sig);
- kern_sigprocmask(td, SIG_BLOCK, &mask, NULL,
- SIGPROCMASK_PROC_LOCKED | SIGPROCMASK_PS_LOCKED);
-
- if (SIGISMEMBER(ps->ps_sigreset, sig)) {
- /*
- * See kern_sigaction() for origin of this code.
- */
- SIGDELSET(ps->ps_sigcatch, sig);
- if (sig != SIGCONT &&
- sigprop(sig) & SA_IGNORE)
- SIGADDSET(ps->ps_sigignore, sig);
- ps->ps_sigact[_SIG_IDX(sig)] = SIG_DFL;
- }
- td->td_ru.ru_nsignals++;
if (p->p_sig == sig) {
p->p_code = 0;
p->p_sig = 0;
}
(*p->p_sysent->sv_sendsig)(action, &ksi, &returnmask);
+ postsig_done(sig, td, ps);
}
return (1);
}
More information about the svn-src-stable-9
mailing list