summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bin/sh/error.c26
-rw-r--r--bin/sh/error.h3
-rw-r--r--bin/sh/trap.c12
-rw-r--r--bin/sh/trap.h1
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);
OpenPOWER on IntegriCloud