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:
parent
b6de784e2f
commit
dedc04fe95
@ -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) {
|
||||||
|
@ -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 */
|
||||||
|
Loading…
Reference in New Issue
Block a user