aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/hush.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 6172f2285..b881b001a 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -988,6 +988,7 @@ struct globals {
# define G_fatal_sig_mask 0
#endif
#if ENABLE_HUSH_TRAP
+ int pre_trap_exitcode;
# if ENABLE_HUSH_FUNCTIONS
int return_exitcode;
# endif
@@ -2111,10 +2112,11 @@ static int check_and_run_traps(void)
argv[1] = xstrdup(G_traps[sig]);
/* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */
argv[2] = NULL;
- save_rcode = G.last_exitcode;
+ G.pre_trap_exitcode = save_rcode = G.last_exitcode;
builtin_eval(argv);
free(argv[1]);
G.last_exitcode = save_rcode;
+ G.pre_trap_exitcode = -1;
# if ENABLE_HUSH_FUNCTIONS
if (G.return_exitcode >= 0) {
debug_printf_exec("trap exitcode:%d\n", G.return_exitcode);
@@ -9927,8 +9929,11 @@ int hush_main(int argc, char **argv)
INIT_G();
if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */
G.last_exitcode = EXIT_SUCCESS;
-#if ENABLE_HUSH_TRAP && ENABLE_HUSH_FUNCTIONS
+#if ENABLE_HUSH_TRAP
+# if ENABLE_HUSH_FUNCTIONS
G.return_exitcode = -1;
+# endif
+ G.pre_trap_exitcode = -1;
#endif
#if ENABLE_HUSH_FAST
@@ -10575,8 +10580,13 @@ static int FAST_FUNC builtin_exit(char **argv)
/* note: EXIT trap is run by hush_exit */
argv = skip_dash_dash(argv);
- if (argv[0] == NULL)
+ if (argv[0] == NULL) {
+#if ENABLE_HUSH_TRAP
+ if (G.pre_trap_exitcode >= 0) /* "exit" in trap uses $? from before the trap */
+ hush_exit(G.pre_trap_exitcode);
+#endif
hush_exit(G.last_exitcode);
+ }
/* mimic bash: exit 123abc == exit 255 + error msg */
xfunc_error_retval = 255;
/* bash: exit -2 == exit 254, no error msg */