summaryrefslogtreecommitdiff
path: root/trap.c
diff options
context:
space:
mode:
Diffstat (limited to 'trap.c')
-rw-r--r--trap.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/trap.c b/trap.c
index 8c054755..dd0245e6 100644
--- a/trap.c
+++ b/trap.c
@@ -297,11 +297,13 @@ void
run_pending_traps ()
{
register int sig;
- int old_exit_value, x;
- int old_running;
+ int x;
+ volatile int old_exit_value, old_running;
WORD_LIST *save_subst_varlist;
HASH_TABLE *save_tempenv;
sh_parser_state_t pstate;
+ volatile int save_return_catch_flag, function_code;
+ procenv_t save_return_catch;
#if defined (ARRAY_VARS)
ARRAY *ps;
#endif
@@ -341,9 +343,7 @@ run_pending_traps ()
while (pending_traps[sig]--) instead of the if statement. */
if (pending_traps[sig])
{
- if (running_trap == sig+1)
- /*continue*/;
-
+ /* XXX - set last_command_exit_value = trap_saved_exit_value here? */
running_trap = sig + 1;
if (sig == SIGINT)
@@ -419,7 +419,6 @@ run_pending_traps ()
}
else
{
- /* XXX - should we use save_parser_state/restore_parser_state? */
save_parser_state (&pstate);
save_subst_varlist = subst_assign_varlist;
subst_assign_varlist = 0;
@@ -432,7 +431,23 @@ run_pending_traps ()
/* XXX - set pending_traps[sig] = 0 here? */
pending_traps[sig] = 0;
evalnest++;
- evalstring (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
+
+ function_code = 0;
+ save_return_catch_flag = return_catch_flag;
+ if (return_catch_flag)
+ {
+ COPY_PROCENV (return_catch, save_return_catch);
+ function_code = setjmp_nosigs (return_catch);
+ }
+
+ if (function_code == 0)
+ x = parse_and_execute (savestring (trap_list[sig]), "trap", SEVAL_NONINT|SEVAL_NOHIST|SEVAL_RESETLINE);
+ else
+ {
+ parse_and_execute_cleanup (sig + 1); /* XXX - could use -1 */
+ x = return_catch_value;
+ }
+
evalnest--;
#if defined (JOB_CONTROL)
restore_pipeline (1);
@@ -441,6 +456,19 @@ run_pending_traps ()
subst_assign_varlist = save_subst_varlist;
restore_parser_state (&pstate);
temporary_env = save_tempenv;
+
+ if (save_return_catch_flag)
+ {
+ return_catch_flag = save_return_catch_flag;
+ return_catch_value = x;
+ COPY_PROCENV (save_return_catch, return_catch);
+ if (function_code)
+ {
+ running_trap = old_running; /* XXX */
+ /* caller will set last_command_exit_value */
+ sh_longjmp (return_catch, 1);
+ }
+ }
}
pending_traps[sig] = 0; /* XXX - move before evalstring? */