diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-06 23:06:57 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-06 23:06:57 +0100 |
commit | c7a7ce06b82ef6a4e5f6146046792daf666e3c6d (patch) | |
tree | 686f3ae9f340fcfdcffacc07fe60bc1d2729c9c3 | |
parent | a1331371748fe23ffaec0720f5c5f4f661c37789 (diff) | |
download | busybox-w32-c7a7ce06b82ef6a4e5f6146046792daf666e3c6d.tar.gz busybox-w32-c7a7ce06b82ef6a4e5f6146046792daf666e3c6d.tar.bz2 busybox-w32-c7a7ce06b82ef6a4e5f6146046792daf666e3c6d.zip |
bc: fix exit codes for FEATURE_CLEAN_UP=y
$ echo 0/0 | ./busybox bc; echo $?
bc: divide by zero
1
$ echo halt | ./busybox bc; echo $?
0 <------- was 1
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | miscutils/bc.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index 3f7da3abc..45cdeae7f 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -741,6 +741,7 @@ typedef unsigned long (*BcProgramBuiltIn)(BcNum *); | |||
741 | 741 | ||
742 | struct globals { | 742 | struct globals { |
743 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) | 743 | IF_FEATURE_BC_SIGNALS(smallint ttyin;) |
744 | IF_FEATURE_CLEAN_UP(smallint exiting;) | ||
744 | smallint eof; | 745 | smallint eof; |
745 | char sbgn; | 746 | char sbgn; |
746 | char send; | 747 | char send; |
@@ -776,6 +777,11 @@ struct globals { | |||
776 | #else | 777 | #else |
777 | # define G_ttyin 0 | 778 | # define G_ttyin 0 |
778 | #endif | 779 | #endif |
780 | #if ENABLE_FEATURE_CLEAN_UP | ||
781 | # define G_exiting G.exiting | ||
782 | #else | ||
783 | # define G_exiting 0 | ||
784 | #endif | ||
779 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) | 785 | #define IS_BC (ENABLE_BC && (!ENABLE_DC || applet_name[0] == 'b')) |
780 | 786 | ||
781 | #if ENABLE_BC | 787 | #if ENABLE_BC |
@@ -921,13 +927,14 @@ static void fflush_and_check(void) | |||
921 | } | 927 | } |
922 | 928 | ||
923 | #if ENABLE_FEATURE_CLEAN_UP | 929 | #if ENABLE_FEATURE_CLEAN_UP |
924 | #define quit_or_return_for_exit() \ | 930 | #define QUIT_OR_RETURN_TO_MAIN \ |
925 | do { \ | 931 | do { \ |
926 | IF_FEATURE_BC_SIGNALS(G_ttyin = 0;) /* do not loop in main loop anymore */ \ | 932 | IF_FEATURE_BC_SIGNALS(G_ttyin = 0;) /* do not loop in main loop anymore */ \ |
933 | G_exiting = 1; \ | ||
927 | return BC_STATUS_FAILURE; \ | 934 | return BC_STATUS_FAILURE; \ |
928 | } while (0) | 935 | } while (0) |
929 | #else | 936 | #else |
930 | #define quit_or_return_for_exit() quit() | 937 | #define QUIT_OR_RETURN_TO_MAIN quit() |
931 | #endif | 938 | #endif |
932 | 939 | ||
933 | static void quit(void) NORETURN; | 940 | static void quit(void) NORETURN; |
@@ -4708,7 +4715,7 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4708 | // "quit" is a compile-time command. For example, | 4715 | // "quit" is a compile-time command. For example, |
4709 | // "if (0 == 1) quit" terminates when parsing the statement, | 4716 | // "if (0 == 1) quit" terminates when parsing the statement, |
4710 | // not when it is executed | 4717 | // not when it is executed |
4711 | quit_or_return_for_exit(); | 4718 | QUIT_OR_RETURN_TO_MAIN; |
4712 | } | 4719 | } |
4713 | 4720 | ||
4714 | case BC_LEX_KEY_RETURN: | 4721 | case BC_LEX_KEY_RETURN: |
@@ -6411,9 +6418,7 @@ static BcStatus bc_program_nquit(void) | |||
6411 | if (G.prog.stack.len < val) | 6418 | if (G.prog.stack.len < val) |
6412 | return bc_error_stack_has_too_few_elements(); | 6419 | return bc_error_stack_has_too_few_elements(); |
6413 | if (G.prog.stack.len == val) { | 6420 | if (G.prog.stack.len == val) { |
6414 | if (ENABLE_FEATURE_CLEAN_UP) | 6421 | QUIT_OR_RETURN_TO_MAIN; |
6415 | return BC_STATUS_FAILURE; | ||
6416 | quit(); | ||
6417 | } | 6422 | } |
6418 | 6423 | ||
6419 | bc_vec_npop(&G.prog.stack, val); | 6424 | bc_vec_npop(&G.prog.stack, val); |
@@ -6627,7 +6632,7 @@ static BcStatus bc_program_exec(void) | |||
6627 | 6632 | ||
6628 | case BC_INST_HALT: | 6633 | case BC_INST_HALT: |
6629 | { | 6634 | { |
6630 | quit_or_return_for_exit(); | 6635 | QUIT_OR_RETURN_TO_MAIN; |
6631 | break; | 6636 | break; |
6632 | } | 6637 | } |
6633 | 6638 | ||
@@ -6872,7 +6877,7 @@ static BcStatus bc_program_exec(void) | |||
6872 | case BC_INST_QUIT: | 6877 | case BC_INST_QUIT: |
6873 | { | 6878 | { |
6874 | if (G.prog.stack.len <= 2) | 6879 | if (G.prog.stack.len <= 2) |
6875 | quit_or_return_for_exit(); | 6880 | QUIT_OR_RETURN_TO_MAIN; |
6876 | bc_vec_npop(&G.prog.stack, 2); | 6881 | bc_vec_npop(&G.prog.stack, 2); |
6877 | break; | 6882 | break; |
6878 | } | 6883 | } |
@@ -7489,6 +7494,8 @@ static BcStatus bc_vm_run(void) | |||
7489 | { | 7494 | { |
7490 | BcStatus st = bc_vm_exec(); | 7495 | BcStatus st = bc_vm_exec(); |
7491 | #if ENABLE_FEATURE_CLEAN_UP | 7496 | #if ENABLE_FEATURE_CLEAN_UP |
7497 | if (G_exiting) // it was actually "halt" or "quit" | ||
7498 | st = EXIT_SUCCESS; | ||
7492 | bc_vm_free(); | 7499 | bc_vm_free(); |
7493 | # if ENABLE_FEATURE_EDITING | 7500 | # if ENABLE_FEATURE_EDITING |
7494 | free_line_input_t(G.line_input_state); | 7501 | free_line_input_t(G.line_input_state); |