diff options
-rw-r--r-- | shell/ash_test/ash-misc/exitcode_trap6.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/exitcode_trap6.tests | 11 | ||||
-rw-r--r-- | shell/hush.c | 4 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/exitcode_trap6.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/exitcode_trap6.tests | 11 |
5 files changed, 29 insertions, 1 deletions
diff --git a/shell/ash_test/ash-misc/exitcode_trap6.right b/shell/ash_test/ash-misc/exitcode_trap6.right new file mode 100644 index 000000000..b76c1908e --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode_trap6.right | |||
@@ -0,0 +1,2 @@ | |||
1 | INT | ||
2 | 42:42 | ||
diff --git a/shell/ash_test/ash-misc/exitcode_trap6.tests b/shell/ash_test/ash-misc/exitcode_trap6.tests new file mode 100755 index 000000000..15fb99d2d --- /dev/null +++ b/shell/ash_test/ash-misc/exitcode_trap6.tests | |||
@@ -0,0 +1,11 @@ | |||
1 | # "exit" in trap should not use last command's exitcode, | ||
2 | # but exitcode on entering the trap. | ||
3 | # Nested trap should not interfere with this. | ||
4 | $THIS_SH -c ' | ||
5 | trap "echo INT" int | ||
6 | trap "kill -int $$;exit" term | ||
7 | kill $$ & | ||
8 | (exit 42) | ||
9 | wait | ||
10 | ' | ||
11 | echo 42:$? | ||
diff --git a/shell/hush.c b/shell/hush.c index b881b001a..357a354e2 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2107,16 +2107,18 @@ static int check_and_run_traps(void) | |||
2107 | if (G_traps[sig][0]) { | 2107 | if (G_traps[sig][0]) { |
2108 | /* We have user-defined handler */ | 2108 | /* We have user-defined handler */ |
2109 | smalluint save_rcode; | 2109 | smalluint save_rcode; |
2110 | int save_pre; | ||
2110 | char *argv[3]; | 2111 | char *argv[3]; |
2111 | /* argv[0] is unused */ | 2112 | /* argv[0] is unused */ |
2112 | argv[1] = xstrdup(G_traps[sig]); | 2113 | argv[1] = xstrdup(G_traps[sig]); |
2113 | /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */ | 2114 | /* why strdup? trap can modify itself: trap 'trap "echo oops" INT' INT */ |
2114 | argv[2] = NULL; | 2115 | argv[2] = NULL; |
2116 | save_pre = G.pre_trap_exitcode; | ||
2115 | G.pre_trap_exitcode = save_rcode = G.last_exitcode; | 2117 | G.pre_trap_exitcode = save_rcode = G.last_exitcode; |
2116 | builtin_eval(argv); | 2118 | builtin_eval(argv); |
2117 | free(argv[1]); | 2119 | free(argv[1]); |
2120 | G.pre_trap_exitcode = save_pre; | ||
2118 | G.last_exitcode = save_rcode; | 2121 | G.last_exitcode = save_rcode; |
2119 | G.pre_trap_exitcode = -1; | ||
2120 | # if ENABLE_HUSH_FUNCTIONS | 2122 | # if ENABLE_HUSH_FUNCTIONS |
2121 | if (G.return_exitcode >= 0) { | 2123 | if (G.return_exitcode >= 0) { |
2122 | debug_printf_exec("trap exitcode:%d\n", G.return_exitcode); | 2124 | debug_printf_exec("trap exitcode:%d\n", G.return_exitcode); |
diff --git a/shell/hush_test/hush-misc/exitcode_trap6.right b/shell/hush_test/hush-misc/exitcode_trap6.right new file mode 100644 index 000000000..b76c1908e --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode_trap6.right | |||
@@ -0,0 +1,2 @@ | |||
1 | INT | ||
2 | 42:42 | ||
diff --git a/shell/hush_test/hush-misc/exitcode_trap6.tests b/shell/hush_test/hush-misc/exitcode_trap6.tests new file mode 100755 index 000000000..15fb99d2d --- /dev/null +++ b/shell/hush_test/hush-misc/exitcode_trap6.tests | |||
@@ -0,0 +1,11 @@ | |||
1 | # "exit" in trap should not use last command's exitcode, | ||
2 | # but exitcode on entering the trap. | ||
3 | # Nested trap should not interfere with this. | ||
4 | $THIS_SH -c ' | ||
5 | trap "echo INT" int | ||
6 | trap "kill -int $$;exit" term | ||
7 | kill $$ & | ||
8 | (exit 42) | ||
9 | wait | ||
10 | ' | ||
11 | echo 42:$? | ||