summaryrefslogtreecommitdiff
path: root/sig.c
diff options
context:
space:
mode:
authorStephen Hemminger <stephen.hemminger@vyatta.com>2010-04-09 16:13:32 -0700
committerStephen Hemminger <stephen.hemminger@vyatta.com>2010-04-09 16:15:01 -0700
commit2d698b6e42d8dca191ac795ef5dba3bf62496eec (patch)
treeac5e0b67043c50f49160e9fe407435706cf30444 /sig.c
parentf1250933e4a2ac09a3d0b25b3877068e12f44da5 (diff)
downloadvyatta-bash-2d698b6e42d8dca191ac795ef5dba3bf62496eec.tar.gz
vyatta-bash-2d698b6e42d8dca191ac795ef5dba3bf62496eec.zip
Integrate bash 3.2 version
This is merge of current Debian stable (Lenny) version of Bash with Vyatta changes.
Diffstat (limited to 'sig.c')
-rw-r--r--sig.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/sig.c b/sig.c
index 9480279..2bd6cae 100644
--- a/sig.c
+++ b/sig.c
@@ -1,6 +1,6 @@
/* sig.c - interface for shell signal handlers and signal initialization. */
-/* Copyright (C) 1994-2005 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2006 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -59,11 +59,14 @@ extern int loop_level, continuing, breaking;
extern int parse_and_execute_level, shell_initialized;
/* Non-zero after SIGINT. */
-int interrupt_state;
+volatile int interrupt_state = 0;
/* Non-zero after SIGWINCH */
volatile int sigwinch_received = 0;
+/* Set to the value of any terminating signal received. */
+volatile int terminating_signal = 0;
+
/* The environment at the top-level R-E loop. We use this in
the case of error return. */
procenv_t top_level;
@@ -76,6 +79,9 @@ sigset_t top_level_mask;
/* When non-zero, we throw_to_top_level (). */
int interrupt_immediately = 0;
+/* When non-zero, we call the terminating signal handler immediately. */
+int terminate_immediately = 0;
+
#if defined (SIGWINCH)
static SigHandler *old_winch = (SigHandler *)SIG_DFL;
#endif
@@ -223,7 +229,7 @@ initialize_terminating_signals ()
this is possible in Posix. Unfortunately, we have to call signal ()
on non-Posix systems for each signal in terminating_signals. */
#if defined (HAVE_POSIX_SIGNALS)
- act.sa_handler = termination_unwind_protect;
+ act.sa_handler = termsig_sighandler;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
sigemptyset (&oact.sa_mask);
@@ -259,7 +265,7 @@ initialize_terminating_signals ()
if (signal_is_trapped (XSIG (i)))
continue;
- XHANDLER(i) = signal (XSIG (i), termination_unwind_protect);
+ XHANDLER(i) = signal (XSIG (i), termsig_sighandler);
XSAFLAGS(i) = 0;
/* Don't do anything with signals that are ignored at shell entry
if the shell is not interactive. */
@@ -418,17 +424,39 @@ jump_to_top_level (value)
}
sighandler
-termination_unwind_protect (sig)
+termsig_sighandler (sig)
int sig;
{
+ terminating_signal = sig;
+
+ if (terminate_immediately)
+ {
+ terminate_immediately = 0;
+ termsig_handler (sig);
+ }
+
+ SIGRETURN (0);
+}
+
+void
+termsig_handler (sig)
+ int sig;
+{
+ static int handling_termsig = 0;
+
+ /* 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;
+ terminating_signal = 0; /* keep macro from re-testing true. */
+
/* I don't believe this condition ever tests true. */
if (sig == SIGINT && signal_is_trapped (SIGINT))
run_interrupt_trap ();
#if defined (HISTORY)
- /* This might be unsafe, since it eventually calls functions POSIX says
- not to call from signal handlers. If it's a problem, take this code
- out. */
if (interactive_shell && sig != SIGABRT)
maybe_save_shell_history ();
#endif /* HISTORY */
@@ -446,8 +474,6 @@ termination_unwind_protect (sig)
run_exit_trap ();
set_signal_handler (sig, SIG_DFL);
kill (getpid (), sig);
-
- SIGRETURN (0);
}
/* What we really do when SIGINT occurs. */