diff options
-rw-r--r-- | bin/sh/error.c | 26 | ||||
-rw-r--r-- | bin/sh/error.h | 3 | ||||
-rw-r--r-- | bin/sh/trap.c | 12 | ||||
-rw-r--r-- | bin/sh/trap.h | 1 |
4 files changed, 21 insertions, 21 deletions
diff --git a/bin/sh/error.c b/bin/sh/error.c index 96a0092..fedffaa 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -90,13 +90,14 @@ exraise(int e) /* - * Called from trap.c when a SIGINT is received. (If the user specifies - * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. If SIGINTs are not suppressed and - * the shell is not a root shell, then we want to be terminated if we - * get here, as if we were terminated directly by a SIGINT. Arrange for - * this here. + * Called from trap.c when a SIGINT is received and not suppressed, or when + * an interrupt is pending and interrupts are re-enabled using INTON. + * (If the user specifies that SIGINT is to be trapped or ignored using the + * trap builtin, then this routine is not called.) Suppressint is nonzero + * when interrupts are held using the INTOFF macro. If SIGINTs are not + * suppressed and the shell is not a root shell, then we want to be + * terminated if we get here, as if we were terminated directly by a SIGINT. + * Arrange for this here. */ void @@ -104,16 +105,6 @@ onint(void) { sigset_t sigs; - /* - * The !in_dotrap here is safe. The only way we can arrive here - * with in_dotrap set is that a trap handler set SIGINT to SIG_DFL - * and killed itself. - */ - - if (suppressint && !in_dotrap) { - intpending++; - return; - } intpending = 0; sigemptyset(&sigs); sigprocmask(SIG_SETMASK, &sigs, NULL); @@ -130,6 +121,7 @@ onint(void) else { signal(SIGINT, SIG_DFL); kill(getpid(), SIGINT); + _exit(128 + SIGINT); } } diff --git a/bin/sh/error.h b/bin/sh/error.h index d0a4bca..a60b1fa 100644 --- a/bin/sh/error.h +++ b/bin/sh/error.h @@ -75,11 +75,12 @@ extern volatile sig_atomic_t intpending; #define is_int_on() suppressint #define SETINTON(s) suppressint = (s) #define FORCEINTON {suppressint = 0; if (intpending) onint();} +#define SET_PENDING_INT intpending = 1 #define CLEAR_PENDING_INT intpending = 0 #define int_pending() intpending void exraise(int) __dead2; -void onint(void); +void onint(void) __dead2; void warning(const char *, ...) __printflike(1, 2); void error(const char *, ...) __printf0like(1, 2) __dead2; void exerror(int, const char *, ...) __printf0like(2, 3) __dead2; diff --git a/bin/sh/trap.c b/bin/sh/trap.c index 8ea3b12..c23e6bc 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -75,7 +75,7 @@ __FBSDID("$FreeBSD$"); static char sigmode[NSIG]; /* current value of signal */ volatile sig_atomic_t pendingsig; /* indicates some signal received */ volatile sig_atomic_t pendingsig_waitcmd; /* indicates SIGINT/SIGQUIT received */ -int in_dotrap; /* do we execute in a trap handler? */ +static int in_dotrap; /* do we execute in a trap handler? */ static char *volatile trap[NSIG]; /* trap handler commands */ static volatile sig_atomic_t gotsig[NSIG]; /* indicates specified signal received */ @@ -380,7 +380,15 @@ onsig(int signo) { if (signo == SIGINT && trap[SIGINT] == NULL) { - onint(); + /* + * The !in_dotrap here is safe. The only way we can arrive + * here with in_dotrap set is that a trap handler set SIGINT to + * SIG_DFL and killed itself. + */ + if (suppressint && !in_dotrap) + SET_PENDING_INT; + else + onint(); return; } diff --git a/bin/sh/trap.h b/bin/sh/trap.h index 541b9b1..a272839 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -35,7 +35,6 @@ extern volatile sig_atomic_t pendingsig; extern volatile sig_atomic_t pendingsig_waitcmd; -extern int in_dotrap; void clear_traps(void); int have_traps(void); |