94 lines
2.6 KiB
Diff
94 lines
2.6 KiB
Diff
|
diff --git a/execute_cmd.c b/execute_cmd.c
|
||
|
--- a/execute_cmd.c
|
||
|
+++ b/execute_cmd.c
|
||
|
@@ -3624,6 +3624,7 @@ execute_case_command (case_command)
|
||
|
free (pattern);
|
||
|
|
||
|
dispose_words (es);
|
||
|
+ QUIT;
|
||
|
|
||
|
if (match)
|
||
|
{
|
||
|
diff --git a/patchlevel.h b/patchlevel.h
|
||
|
--- a/patchlevel.h
|
||
|
+++ b/patchlevel.h
|
||
|
@@ -25,6 +25,6 @@
|
||
|
regexp `^#define[ ]*PATCHLEVEL', since that's what support/mkversion.sh
|
||
|
looks for to find the patch level (for the sccs version string). */
|
||
|
|
||
|
-#define PATCHLEVEL 13
|
||
|
+#define PATCHLEVEL 14
|
||
|
|
||
|
#endif /* _PATCHLEVEL_H_ */
|
||
|
diff --git a/sig.c b/sig.c
|
||
|
--- a/sig.c
|
||
|
+++ b/sig.c
|
||
|
@@ -94,6 +94,7 @@ static SigHandler *old_winch = (SigHandler *)SIG_DFL;
|
||
|
#endif
|
||
|
|
||
|
static void initialize_shell_signals PARAMS((void));
|
||
|
+static void kill_shell PARAMS((int));
|
||
|
|
||
|
void
|
||
|
initialize_signals (reinit)
|
||
|
@@ -486,6 +487,8 @@ restore_sigmask ()
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
+static int handling_termsig = 0;
|
||
|
+
|
||
|
sighandler
|
||
|
termsig_sighandler (sig)
|
||
|
int sig;
|
||
|
@@ -532,6 +535,14 @@ termsig_sighandler (sig)
|
||
|
sig == terminating_signal)
|
||
|
terminate_immediately = 1;
|
||
|
|
||
|
+ /* If we are currently handling a terminating signal, we have a couple of
|
||
|
+ choices here. We can ignore this second terminating signal and let the
|
||
|
+ shell exit from the first one, or we can exit immediately by killing
|
||
|
+ the shell with this signal. This code implements the latter; to implement
|
||
|
+ the former, replace the kill_shell(sig) with return. */
|
||
|
+ if (handling_termsig)
|
||
|
+ kill_shell (sig); /* just short-circuit now */
|
||
|
+
|
||
|
terminating_signal = sig;
|
||
|
|
||
|
if (terminate_immediately)
|
||
|
@@ -564,16 +575,13 @@ void
|
||
|
termsig_handler (sig)
|
||
|
int sig;
|
||
|
{
|
||
|
- static int handling_termsig = 0;
|
||
|
- int i, core;
|
||
|
- sigset_t mask;
|
||
|
-
|
||
|
/* Simple semaphore to keep this function from being executed multiple
|
||
|
times. Since we no longer are running as a signal handler, we don't
|
||
|
block multiple occurrences of the terminating signals while running. */
|
||
|
if (handling_termsig)
|
||
|
return;
|
||
|
- handling_termsig = 1;
|
||
|
+
|
||
|
+ handling_termsig = terminating_signal; /* for termsig_sighandler */
|
||
|
terminating_signal = 0; /* keep macro from re-testing true. */
|
||
|
|
||
|
/* I don't believe this condition ever tests true. */
|
||
|
@@ -613,6 +621,16 @@ termsig_handler (sig)
|
||
|
|
||
|
run_exit_trap (); /* XXX - run exit trap possibly in signal context? */
|
||
|
|
||
|
+ kill_shell (sig);
|
||
|
+}
|
||
|
+
|
||
|
+static void
|
||
|
+kill_shell (sig)
|
||
|
+ int sig;
|
||
|
+{
|
||
|
+ int i, core;
|
||
|
+ sigset_t mask;
|
||
|
+
|
||
|
/* We don't change the set of blocked signals. If a user starts the shell
|
||
|
with a terminating signal blocked, we won't get here (and if by some
|
||
|
magic chance we do, we'll exit below). What we do is to restore the
|