Actually implement SA_RESETHAND - some of the sigaction code recognised it

but didn't actually do anything with it (*blush*).

This should fix bde's test case where the test program set SA_RESETHAND
and when reading it back, it was gone.

Tweak/optimize SA_NODEFER so that the implementation is a little simpler
and does not incur (slight) overhead for every signal at delivery time.
This commit is contained in:
Peter Wemm 1996-03-15 08:01:33 +00:00
parent b6de784e2f
commit dedc04fe95
2 changed files with 29 additions and 14 deletions

View File

@ -36,7 +36,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)kern_sig.c 8.7 (Berkeley) 4/18/94 * @(#)kern_sig.c 8.7 (Berkeley) 4/18/94
* $Id: kern_sig.c,v 1.20 1996/03/11 02:22:02 hsu Exp $ * $Id: kern_sig.c,v 1.21 1996/03/11 06:03:26 hsu Exp $
*/ */
#include "opt_ktrace.h" #include "opt_ktrace.h"
@ -122,10 +122,14 @@ sigaction(p, uap, retval)
sa->sa_flags |= SA_ONSTACK; sa->sa_flags |= SA_ONSTACK;
if ((ps->ps_sigintr & bit) == 0) if ((ps->ps_sigintr & bit) == 0)
sa->sa_flags |= SA_RESTART; sa->sa_flags |= SA_RESTART;
if ((ps->ps_nodefer & bit) != 0) if ((ps->ps_sigreset & bit) != 0)
sa->sa_flags |= SA_RESETHAND;
if (signum == SIGCHLD) {
if (p->p_flag & P_NOCLDSTOP)
sa->sa_flags |= SA_NOCLDSTOP;
}
if ((sa->sa_mask & bit) == 0)
sa->sa_flags |= SA_NODEFER; sa->sa_flags |= SA_NODEFER;
if (p->p_flag & P_NOCLDSTOP)
sa->sa_flags |= SA_NOCLDSTOP;
if ((error = copyout((caddr_t)sa, (caddr_t)uap->osa, if ((error = copyout((caddr_t)sa, (caddr_t)uap->osa,
sizeof (vec)))) sizeof (vec))))
return (error); return (error);
@ -154,6 +158,8 @@ setsigvec(p, signum, sa)
*/ */
(void) splhigh(); (void) splhigh();
ps->ps_sigact[signum] = sa->sa_handler; ps->ps_sigact[signum] = sa->sa_handler;
if ((sa->sa_flags & SA_NODEFER) == 0)
sa->sa_mask |= sigmask(signum);
ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask; ps->ps_catchmask[signum] = sa->sa_mask &~ sigcantmask;
if ((sa->sa_flags & SA_RESTART) == 0) if ((sa->sa_flags & SA_RESTART) == 0)
ps->ps_sigintr |= bit; ps->ps_sigintr |= bit;
@ -163,10 +169,10 @@ setsigvec(p, signum, sa)
ps->ps_sigonstack |= bit; ps->ps_sigonstack |= bit;
else else
ps->ps_sigonstack &= ~bit; ps->ps_sigonstack &= ~bit;
if (sa->sa_flags & SA_NODEFER) if (sa->sa_flags & SA_RESETHAND)
ps->ps_nodefer |= bit; ps->ps_sigreset |= bit;
else else
ps->ps_nodefer &= ~bit; ps->ps_sigreset &= ~bit;
#ifdef COMPAT_SUNOS #ifdef COMPAT_SUNOS
if (sa->sa_flags & SA_USERTRAMP) if (sa->sa_flags & SA_USERTRAMP)
ps->ps_usertramp |= bit; ps->ps_usertramp |= bit;
@ -689,8 +695,13 @@ trapsignal(p, signum, code)
#endif #endif
(*p->p_sysent->sv_sendsig)(ps->ps_sigact[signum], signum, (*p->p_sysent->sv_sendsig)(ps->ps_sigact[signum], signum,
p->p_sigmask, code); p->p_sigmask, code);
p->p_sigmask |= ps->ps_catchmask[signum] | p->p_sigmask |= ps->ps_catchmask[signum];
(mask & ~ps->ps_nodefer); if ((ps->ps_sigreset & mask) != 0) {
p->p_sigcatch &= ~mask;
if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
p->p_sigignore |= mask;
ps->ps_sigact[signum] = SIG_DFL;
}
} else { } else {
ps->ps_code = code; /* XXX for core dump/debugger */ ps->ps_code = code; /* XXX for core dump/debugger */
ps->ps_sig = signum; /* XXX to verify code */ ps->ps_sig = signum; /* XXX to verify code */
@ -1125,8 +1136,13 @@ postsig(signum)
ps->ps_flags &= ~SAS_OLDMASK; ps->ps_flags &= ~SAS_OLDMASK;
} else } else
returnmask = p->p_sigmask; returnmask = p->p_sigmask;
p->p_sigmask |= ps->ps_catchmask[signum] | p->p_sigmask |= ps->ps_catchmask[signum];
(mask & ~ps->ps_nodefer); if ((ps->ps_sigreset & mask) != 0) {
p->p_sigcatch &= ~mask;
if (signum != SIGCONT && sigprop[signum] & SA_IGNORE)
p->p_sigignore |= mask;
ps->ps_sigact[signum] = SIG_DFL;
}
(void) spl0(); (void) spl0();
p->p_stats->p_ru.ru_nsignals++; p->p_stats->p_ru.ru_nsignals++;
if (ps->ps_sig != signum) { if (ps->ps_sig != signum) {

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
* *
* @(#)signalvar.h 8.6 (Berkeley) 2/19/95 * @(#)signalvar.h 8.6 (Berkeley) 2/19/95
* $Id: signalvar.h,v 1.10 1996/03/02 19:38:16 peter Exp $ * $Id: signalvar.h,v 1.11 1996/03/11 02:21:04 hsu Exp $
*/ */
#ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */ #ifndef _SYS_SIGNALVAR_H_ /* tmp for user.h */
@ -51,14 +51,13 @@ struct sigacts {
sigset_t ps_catchmask[NSIG]; /* signals to be blocked */ sigset_t ps_catchmask[NSIG]; /* signals to be blocked */
sigset_t ps_sigonstack; /* signals to take on sigstack */ sigset_t ps_sigonstack; /* signals to take on sigstack */
sigset_t ps_sigintr; /* signals that interrupt syscalls */ sigset_t ps_sigintr; /* signals that interrupt syscalls */
sigset_t ps_sigreset; /* signals that reset when caught */
sigset_t ps_oldmask; /* saved mask from before sigpause */ sigset_t ps_oldmask; /* saved mask from before sigpause */
int ps_flags; /* signal flags, below */ int ps_flags; /* signal flags, below */
struct sigaltstack ps_sigstk; /* sp & on stack state variable */ struct sigaltstack ps_sigstk; /* sp & on stack state variable */
int ps_sig; /* for core dump/debugger XXX */ int ps_sig; /* for core dump/debugger XXX */
u_long ps_code; /* for core dump/debugger XXX */ u_long ps_code; /* for core dump/debugger XXX */
sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */ sigset_t ps_usertramp; /* SunOS compat; libc sigtramp XXX */
sigset_t ps_nodefer; /* signals not to defer */
sigset_t ps_sigreset; /* signals that reset when caught */
}; };
/* signal flags */ /* signal flags */