summaryrefslogtreecommitdiff
path: root/trap.c
diff options
context:
space:
mode:
authorChet Ramey <chet.ramey@case.edu>2014-01-29 17:00:07 -0500
committerChet Ramey <chet.ramey@case.edu>2014-01-29 17:00:07 -0500
commitb6e23235f28b1c85e18e9a2b7ba8c6b6c46aecbc (patch)
tree00fdd9c37c261d89c994fc1856252df719afec3a /trap.c
parent8581f42df9a1b1d848e2d4bdf3cc951b8d14b5be (diff)
downloadbash-4.3-testing.tar.gz
bash-4.3-rc2 overlaybash-4.3-rc2bash-4.3-testing
Diffstat (limited to 'trap.c')
-rw-r--r--trap.c71
1 files changed, 54 insertions, 17 deletions
diff --git a/trap.c b/trap.c
index 64d7677f..5c31ff60 100644
--- a/trap.c
+++ b/trap.c
@@ -288,7 +288,16 @@ run_pending_traps ()
return;
if (running_trap > 0)
- return; /* no recursive trap invocations */
+ {
+#if defined (DEBUG)
+ internal_warning ("run_pending_traps: recursive invocation while running trap for signal %d", running_trap-1);
+#endif
+#if 0
+ return; /* no recursive trap invocations */
+#else
+ ;
+#endif
+ }
catch_flag = trapped_signal_received = 0;
@@ -304,14 +313,14 @@ run_pending_traps ()
while (pending_traps[sig]--) instead of the if statement. */
if (pending_traps[sig])
{
- sigset_t set, oset;
-
- BLOCK_SIGNAL (sig, set, oset);
+ if (running_trap == sig+1)
+ /*continue*/;
running_trap = sig + 1;
if (sig == SIGINT)
{
+ pending_traps[sig] = 0; /* XXX */
run_interrupt_trap ();
CLRINTERRUPT;
}
@@ -331,9 +340,16 @@ run_pending_traps ()
/* This can happen when run_pending_traps is called while
running a SIGCHLD trap handler. */
running_trap = 0;
- UNBLOCK_SIGNAL (oset);
+ /* want to leave pending_traps[SIGCHLD] alone here */
continue; /* XXX */
}
+ else if (sig == SIGCHLD && (sigmodes[SIGCHLD] & SIG_INPROGRESS))
+ {
+ /* whoops -- print warning? */
+ running_trap = 0; /* XXX */
+ /* want to leave pending_traps[SIGCHLD] alone here */
+ continue;
+ }
#endif
else if (trap_list[sig] == (char *)DEFAULT_SIG ||
trap_list[sig] == (char *)IGNORE_SIG ||
@@ -370,20 +386,19 @@ run_pending_traps ()
#if defined (JOB_CONTROL)
save_pipeline (1); /* XXX only provides one save level */
#endif
+ /* XXX - set pending_traps[sig] = 0 here? */
+ pending_traps[sig] = 0;
evalstring (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
#if defined (JOB_CONTROL)
restore_pipeline (1);
#endif
- restore_parser_state (&pstate);
-
subst_assign_varlist = save_subst_varlist;
+ restore_parser_state (&pstate);
}
- pending_traps[sig] = 0;
+ pending_traps[sig] = 0; /* XXX - move before evalstring? */
running_trap = 0;
-
- UNBLOCK_SIGNAL (oset);
}
}
@@ -852,6 +867,8 @@ run_trap_cleanup (sig)
sigmodes[sig] &= ~(SIG_INPROGRESS|SIG_CHANGED);
}
+#define RECURSIVE_SIG(s) (SPECIAL_TRAP(s) == 0)
+
/* Run a trap command for SIG. SIG is one of the signals the shell treats
specially. Returns the exit status of the executed trap command list. */
static int
@@ -865,6 +882,7 @@ _run_trap_internal (sig, tag)
int flags;
procenv_t save_return_catch;
WORD_LIST *save_subst_varlist;
+ sh_parser_state_t pstate;
#if defined (ARRAY_VARS)
ARRAY *ps;
#endif
@@ -874,7 +892,13 @@ _run_trap_internal (sig, tag)
currently executing in the trap handler. */
if ((sigmodes[sig] & SIG_TRAPPED) && ((sigmodes[sig] & SIG_IGNORED) == 0) &&
(trap_list[sig] != (char *)IMPOSSIBLE_TRAP_HANDLER) &&
+#if 0
+ /* Uncomment this to allow some special signals to recursively execute
+ trap handlers. */
+ (RECURSIVE_SIG (sig) || (sigmodes[sig] & SIG_INPROGRESS) == 0))
+#else
((sigmodes[sig] & SIG_INPROGRESS) == 0))
+#endif
{
old_trap = trap_list[sig];
sigmodes[sig] |= SIG_INPROGRESS;
@@ -882,15 +906,19 @@ _run_trap_internal (sig, tag)
trap_command = savestring (old_trap);
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_parser_state (&pstate);
save_subst_varlist = subst_assign_varlist;
subst_assign_varlist = 0;
+#if defined (JOB_CONTROL)
+ save_pipeline (1); /* XXX only provides one save level */
+#endif
+
/* If we're in a function, make sure return longjmps come here, too. */
save_return_catch_flag = return_catch_flag;
if (return_catch_flag)
@@ -905,13 +933,15 @@ _run_trap_internal (sig, tag)
if (function_code == 0)
parse_and_execute (trap_command, tag, flags);
- restore_token_state (token_state);
- free (token_state);
+ trap_exit_value = last_command_exit_value;
+
+#if defined (JOB_CONTROL)
+ restore_pipeline (1);
+#endif
subst_assign_varlist = save_subst_varlist;
+ restore_parser_state (&pstate);
- trap_exit_value = last_command_exit_value;
- last_command_exit_value = trap_saved_exit_value;
#if defined (ARRAY_VARS)
restore_pipestatus_array (ps);
#endif
@@ -1207,13 +1237,20 @@ signal_is_hard_ignored (sig)
}
void
-set_signal_ignored (sig)
+set_signal_hard_ignored (sig)
int sig;
{
sigmodes[sig] |= SIG_HARD_IGNORE;
original_signals[sig] = SIG_IGN;
}
+void
+set_signal_ignored (sig)
+ int sig;
+{
+ original_signals[sig] = SIG_IGN;
+}
+
int
signal_in_progress (sig)
int sig;