diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-03 11:21:13 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-04-03 11:21:13 +0200 |
commit | 5fa0505f8a74848ce4d2a7a4ed905e1bb8af3fe6 (patch) | |
tree | 626cdb9979f4ccddd4566c8073c5d316b1af97b1 /shell | |
parent | 11752d46d18ff4a04a9f6736d129a82756a65a22 (diff) | |
download | busybox-w32-5fa0505f8a74848ce4d2a7a4ed905e1bb8af3fe6.tar.gz busybox-w32-5fa0505f8a74848ce4d2a7a4ed905e1bb8af3fe6.tar.bz2 busybox-w32-5fa0505f8a74848ce4d2a7a4ed905e1bb8af3fe6.zip |
hush: fix "set -e; false || x=1; echo OK"
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ash_test/ash-misc/assignment5.right | 5 | ||||
-rwxr-xr-x | shell/ash_test/ash-misc/assignment5.tests | 9 | ||||
-rw-r--r-- | shell/hush.c | 22 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/assignment5.right | 5 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/assignment5.tests | 9 |
5 files changed, 43 insertions, 7 deletions
diff --git a/shell/ash_test/ash-misc/assignment5.right b/shell/ash_test/ash-misc/assignment5.right new file mode 100644 index 000000000..a91554c09 --- /dev/null +++ b/shell/ash_test/ash-misc/assignment5.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Zero1:0 | ||
2 | Zero2:0 | ||
3 | Zero3:0 | ||
4 | Zero4:0 x:1 y:1 | ||
5 | Three:3 x:1 y:1 | ||
diff --git a/shell/ash_test/ash-misc/assignment5.tests b/shell/ash_test/ash-misc/assignment5.tests new file mode 100755 index 000000000..0b8104285 --- /dev/null +++ b/shell/ash_test/ash-misc/assignment5.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | true; a=1; echo Zero1:$? | ||
2 | false; a=1; echo Zero2:$? | ||
3 | false || a=1; echo Zero3:$? | ||
4 | |||
5 | false || x=$? y=`echo $?`; echo Zero4:$? x:$x y:$y | ||
6 | false || x=$? y=`echo $?; exit 3`; echo Three:$? x:$x y:$y | ||
7 | |||
8 | #ash sets z=1 instead of z=3. disabled for now | ||
9 | #false || x=$? y=`echo $?; exit 3` z=`echo $?`; echo x:$x y:$y z:$z | ||
diff --git a/shell/hush.c b/shell/hush.c index 184d720f5..b64993faa 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -894,8 +894,9 @@ struct globals { | |||
894 | # define G_flag_return_in_progress 0 | 894 | # define G_flag_return_in_progress 0 |
895 | #endif | 895 | #endif |
896 | smallint exiting; /* used to prevent EXIT trap recursion */ | 896 | smallint exiting; /* used to prevent EXIT trap recursion */ |
897 | /* These four support $?, $#, and $1 */ | 897 | /* These support $?, $#, and $1 */ |
898 | smalluint last_exitcode; | 898 | smalluint last_exitcode; |
899 | smalluint expand_exitcode; | ||
899 | smalluint last_bg_pid_exitcode; | 900 | smalluint last_bg_pid_exitcode; |
900 | #if ENABLE_HUSH_SET | 901 | #if ENABLE_HUSH_SET |
901 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ | 902 | /* are global_argv and global_argv[1..n] malloced? (note: not [0]) */ |
@@ -6209,6 +6210,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg) | |||
6209 | * and $IFS-split */ | 6210 | * and $IFS-split */ |
6210 | debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); | 6211 | debug_printf_subst("SUBST '%s' first_ch %x\n", arg, first_ch); |
6211 | G.last_exitcode = process_command_subs(&subst_result, arg); | 6212 | G.last_exitcode = process_command_subs(&subst_result, arg); |
6213 | G.expand_exitcode = G.last_exitcode; | ||
6212 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); | 6214 | debug_printf_subst("SUBST RES:%d '%s'\n", G.last_exitcode, subst_result.data); |
6213 | val = subst_result.data; | 6215 | val = subst_result.data; |
6214 | goto store_val; | 6216 | goto store_val; |
@@ -8245,9 +8247,11 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8245 | #endif | 8247 | #endif |
8246 | 8248 | ||
8247 | if (argv[command->assignment_cnt] == NULL) { | 8249 | if (argv[command->assignment_cnt] == NULL) { |
8248 | /* Assignments, but no command */ | 8250 | /* Assignments, but no command. |
8249 | /* Ensure redirects take effect (that is, create files). | 8251 | * Ensure redirects take effect (that is, create files). |
8250 | * Try "a=t >file" */ | 8252 | * Try "a=t >file" |
8253 | */ | ||
8254 | G.expand_exitcode = 0; | ||
8251 | #if 0 /* A few cases in testsuite fail with this code. FIXME */ | 8255 | #if 0 /* A few cases in testsuite fail with this code. FIXME */ |
8252 | rcode = redirect_and_varexp_helper(&new_env, /*old_vars:*/ NULL, command, &squirrel, /*argv_expanded:*/ NULL); | 8256 | rcode = redirect_and_varexp_helper(&new_env, /*old_vars:*/ NULL, command, &squirrel, /*argv_expanded:*/ NULL); |
8253 | /* Set shell variables */ | 8257 | /* Set shell variables */ |
@@ -8265,7 +8269,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8265 | * if evaluating assignment value set $?, retain it. | 8269 | * if evaluating assignment value set $?, retain it. |
8266 | * Try "false; q=`exit 2`; echo $?" - should print 2: */ | 8270 | * Try "false; q=`exit 2`; echo $?" - should print 2: */ |
8267 | if (rcode == 0) | 8271 | if (rcode == 0) |
8268 | rcode = G.last_exitcode; | 8272 | rcode = G.expand_exitcode; |
8269 | /* Exit, _skipping_ variable restoring code: */ | 8273 | /* Exit, _skipping_ variable restoring code: */ |
8270 | goto clean_up_and_ret0; | 8274 | goto clean_up_and_ret0; |
8271 | 8275 | ||
@@ -8292,9 +8296,13 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8292 | bb_putchar_stderr('\n'); | 8296 | bb_putchar_stderr('\n'); |
8293 | /* Redirect error sets $? to 1. Otherwise, | 8297 | /* Redirect error sets $? to 1. Otherwise, |
8294 | * if evaluating assignment value set $?, retain it. | 8298 | * if evaluating assignment value set $?, retain it. |
8295 | * Try "false; q=`exit 2`; echo $?" - should print 2: */ | 8299 | * Else, clear $?: |
8300 | * false; q=`exit 2`; echo $? - should print 2 | ||
8301 | * false; x=1; echo $? - should print 0 | ||
8302 | * Because of the 2nd case, we can't just use G.last_exitcode. | ||
8303 | */ | ||
8296 | if (rcode == 0) | 8304 | if (rcode == 0) |
8297 | rcode = G.last_exitcode; | 8305 | rcode = G.expand_exitcode; |
8298 | IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) | 8306 | IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;) |
8299 | debug_leave(); | 8307 | debug_leave(); |
8300 | debug_printf_exec("run_pipe: return %d\n", rcode); | 8308 | debug_printf_exec("run_pipe: return %d\n", rcode); |
diff --git a/shell/hush_test/hush-misc/assignment5.right b/shell/hush_test/hush-misc/assignment5.right new file mode 100644 index 000000000..a91554c09 --- /dev/null +++ b/shell/hush_test/hush-misc/assignment5.right | |||
@@ -0,0 +1,5 @@ | |||
1 | Zero1:0 | ||
2 | Zero2:0 | ||
3 | Zero3:0 | ||
4 | Zero4:0 x:1 y:1 | ||
5 | Three:3 x:1 y:1 | ||
diff --git a/shell/hush_test/hush-misc/assignment5.tests b/shell/hush_test/hush-misc/assignment5.tests new file mode 100755 index 000000000..0b8104285 --- /dev/null +++ b/shell/hush_test/hush-misc/assignment5.tests | |||
@@ -0,0 +1,9 @@ | |||
1 | true; a=1; echo Zero1:$? | ||
2 | false; a=1; echo Zero2:$? | ||
3 | false || a=1; echo Zero3:$? | ||
4 | |||
5 | false || x=$? y=`echo $?`; echo Zero4:$? x:$x y:$y | ||
6 | false || x=$? y=`echo $?; exit 3`; echo Three:$? x:$x y:$y | ||
7 | |||
8 | #ash sets z=1 instead of z=3. disabled for now | ||
9 | #false || x=$? y=`echo $?; exit 3` z=`echo $?`; echo x:$x y:$y z:$z | ||