aboutsummaryrefslogtreecommitdiffstats
path: root/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'trap.c')
-rw-r--r--trap.c74
1 files changed, 65 insertions, 9 deletions
diff --git a/trap.c b/trap.c
index 27a8aca..86665e7 100644
--- a/trap.c
+++ b/trap.c
@@ -1,7 +1,7 @@
/* trap.c -- Not the trap command, but useful functions for manipulating
those objects. The trap command is in builtins/trap.def. */
-/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
+/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
@@ -113,9 +113,6 @@ int trap_saved_exit_value;
/* The (trapped) signal received while executing in the `wait' builtin */
int wait_signal_received;
-/* A value which can never be the target of a trap handler. */
-#define IMPOSSIBLE_TRAP_HANDLER (SigHandler *)initialize_traps
-
#define GETORIGSIG(sig) \
do { \
original_signals[sig] = (SigHandler *)set_signal_handler (sig, SIG_DFL); \
@@ -124,6 +121,13 @@ int wait_signal_received;
sigmodes[sig] |= SIG_HARD_IGNORE; \
} while (0)
+#define SETORIGSIG(sig,handler) \
+ do { \
+ original_signals[sig] = handler; \
+ if (original_signals[sig] == SIG_IGN) \
+ sigmodes[sig] |= SIG_HARD_IGNORE; \
+ } while (0)
+
#define GET_ORIGINAL_SIGNAL(sig) \
if (sig && sig < NSIG && original_signals[sig] == IMPOSSIBLE_TRAP_HANDLER) \
GETORIGSIG(sig)
@@ -143,7 +147,7 @@ initialize_traps ()
{
pending_traps[i] = 0;
trap_list[i] = (char *)DEFAULT_SIG;
- sigmodes[i] = SIG_INHERITED;
+ sigmodes[i] = SIG_INHERITED; /* XXX - only set, not used */
original_signals[i] = IMPOSSIBLE_TRAP_HANDLER;
}
@@ -265,6 +269,9 @@ run_pending_traps ()
register int sig;
int old_exit_value, *token_state;
WORD_LIST *save_subst_varlist;
+#if defined (ARRAY_VARS)
+ ARRAY *ps;
+#endif
if (catch_flag == 0) /* simple optimization */
return;
@@ -273,6 +280,9 @@ run_pending_traps ()
/* Preserve $? when running trap. */
old_exit_value = last_command_exit_value;
+#if defined (ARRAY_VARS)
+ ps = save_pipestatus_array ();
+#endif
for (sig = 1; sig < NSIG; sig++)
{
@@ -357,6 +367,9 @@ run_pending_traps ()
}
}
+#if defined (ARRAY_VARS)
+ restore_pipestatus_array (ps);
+#endif
last_command_exit_value = old_exit_value;
}
@@ -594,6 +607,24 @@ get_original_signal (sig)
GETORIGSIG (sig);
}
+void
+get_all_original_signals ()
+{
+ register int i;
+
+ for (i = 1; i < NSIG; i++)
+ GET_ORIGINAL_SIGNAL (i);
+}
+
+void
+set_original_signal (sig, handler)
+ int sig;
+ SigHandler *handler;
+{
+ if (sig > 0 && sig < NSIG && original_signals[sig] == (SigHandler *)IMPOSSIBLE_TRAP_HANDLER)
+ SETORIGSIG (sig, handler);
+}
+
/* Restore the default action for SIG; i.e., the action the shell
would have taken before you used the trap command. This is called
from trap_builtin (), which takes care to restore the handlers for
@@ -674,8 +705,14 @@ run_exit_trap ()
{
char *trap_command;
int code, function_code, retval;
+#if defined (ARRAY_VARS)
+ ARRAY *ps;
+#endif
trap_saved_exit_value = last_command_exit_value;
+#if defined (ARRAY_VARS)
+ ps = save_pipestatus_array ();
+#endif
function_code = 0;
/* Run the trap only if signal 0 is trapped and not ignored, and we are not
@@ -715,6 +752,9 @@ run_exit_trap ()
return retval;
}
+#if defined (ARRAY_VARS)
+ restore_pipestatus_array (ps);
+#endif
return (trap_saved_exit_value);
}
@@ -737,6 +777,9 @@ _run_trap_internal (sig, tag)
int save_return_catch_flag, function_code, flags;
procenv_t save_return_catch;
WORD_LIST *save_subst_varlist;
+#if defined (ARRAY_VARS)
+ ARRAY *ps;
+#endif
trap_exit_value = function_code = 0;
/* Run the trap only if SIG is trapped and not ignored, and we are not
@@ -752,6 +795,9 @@ _run_trap_internal (sig, tag)
running_trap = sig + 1;
trap_saved_exit_value = last_command_exit_value;
+#if defined (ARRAY_VARS)
+ ps = save_pipestatus_array ();
+#endif
token_state = save_token_state ();
save_subst_varlist = subst_assign_varlist;
@@ -778,6 +824,9 @@ _run_trap_internal (sig, tag)
trap_exit_value = last_command_exit_value;
last_command_exit_value = trap_saved_exit_value;
+#if defined (ARRAY_VARS)
+ restore_pipestatus_array (ps);
+#endif
running_trap = 0;
sigmodes[sig] &= ~SIG_INPROGRESS;
@@ -888,7 +937,6 @@ run_interrupt_trap ()
_run_trap_internal (SIGINT, "interrupt trap");
}
-#ifdef INCLUDE_UNUSED
/* Free all the allocated strings in the list of traps and reset the trap
values to the default. Intended to be called from subshells that want
to complete work done by reset_signal_handlers upon execution of a
@@ -912,9 +960,9 @@ free_trap_string (sig)
change_signal (sig, (char *)DEFAULT_SIG);
sigmodes[sig] &= ~SIG_TRAPPED;
}
-#endif
-/* Reset the handler for SIG to the original value. */
+/* Reset the handler for SIG to the original value but leave the trap string
+ in place. */
static void
reset_signal (sig)
int sig;
@@ -979,7 +1027,8 @@ reset_or_restore_signal_handlers (reset)
}
/* Reset trapped signals to their original values, but don't free the
- trap strings. Called by the command substitution code. */
+ trap strings. Called by the command substitution code and other places
+ that create a "subshell environment". */
void
reset_signal_handlers ()
{
@@ -1049,6 +1098,13 @@ signal_is_ignored (sig)
return (sigmodes[sig] & SIG_IGNORED);
}
+int
+signal_is_hard_ignored (sig)
+ int sig;
+{
+ return (sigmodes[sig] & SIG_HARD_IGNORE);
+}
+
void
set_signal_ignored (sig)
int sig;