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); } _______________________________________________ svn-src-all@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-all To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"