ash: fix signal handling

This commit is contained in:
Denis Vlasenko 2007-03-21 20:17:27 +00:00
parent b8e72fdde1
commit 7c139b4778

View File

@ -183,7 +183,7 @@ static volatile sig_atomic_t intpending;
/* do we generate EXSIG events */ /* do we generate EXSIG events */
static int exsig; static int exsig;
/* last pending signal */ /* last pending signal */
static volatile sig_atomic_t pendingsigs; static volatile sig_atomic_t pendingsig;
/* /*
* Sigmode records the current value of the signal handlers for the various * Sigmode records the current value of the signal handlers for the various
@ -239,8 +239,15 @@ static void
raise_interrupt(void) raise_interrupt(void)
{ {
int i; int i;
sigset_t mask;
intpending = 0; intpending = 0;
/* Signal is not automatically re-enabled after it is raised,
* do it ourself */
sigemptyset(&mask);
sigprocmask(SIG_SETMASK, &mask, 0);
/* pendingsig = 0; - now done in onsig() */
i = EXSIG; i = EXSIG;
if (gotsig[SIGINT - 1] && !trap[SIGINT]) { if (gotsig[SIGINT - 1] && !trap[SIGINT]) {
if (!(rootshell && iflag)) { if (!(rootshell && iflag)) {
@ -300,7 +307,7 @@ force_int_on(void)
do { \ do { \
exsig++; \ exsig++; \
xbarrier(); \ xbarrier(); \
if (pendingsigs) \ if (pendingsig) \
raise_exception(EXSIG); \ raise_exception(EXSIG); \
} while (0) } while (0)
/* EXSIG is turned off by evalbltin(). */ /* EXSIG is turned off by evalbltin(). */
@ -324,11 +331,13 @@ static void
onsig(int signo) onsig(int signo)
{ {
gotsig[signo - 1] = 1; gotsig[signo - 1] = 1;
pendingsigs = signo; pendingsig = signo;
if (exsig || (signo == SIGINT && !trap[SIGINT])) { if (exsig || (signo == SIGINT && !trap[SIGINT])) {
if (!suppressint) if (!suppressint) {
pendingsig = 0;
raise_interrupt(); raise_interrupt();
}
intpending = 1; intpending = 1;
} }
} }
@ -7441,7 +7450,7 @@ dotrap(void)
int skip = 0; int skip = 0;
savestatus = exitstatus; savestatus = exitstatus;
pendingsigs = 0; pendingsig = 0;
xbarrier(); xbarrier();
for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) { for (i = 0, q = gotsig; i < NSIG - 1; i++, q++) {
@ -7580,7 +7589,7 @@ evaltree(union node *n, int flags)
out: out:
if ((checkexit & exitstatus)) if ((checkexit & exitstatus))
evalskip |= SKIPEVAL; evalskip |= SKIPEVAL;
else if (pendingsigs && dotrap()) else if (pendingsig && dotrap())
goto exexit; goto exexit;
if (flags & EV_EXIT) { if (flags & EV_EXIT) {
@ -8447,7 +8456,7 @@ evalcommand(union node *cmd, int flags)
if (i == EXINT) if (i == EXINT)
j = SIGINT; j = SIGINT;
if (i == EXSIG) if (i == EXSIG)
j = pendingsigs; j = pendingsig;
if (j) if (j)
exit_status = j + 128; exit_status = j + 128;
exitstatus = exit_status; exitstatus = exit_status;