diff options
Diffstat (limited to 'miscutils')
-rw-r--r-- | miscutils/bc.c | 43 |
1 files changed, 36 insertions, 7 deletions
diff --git a/miscutils/bc.c b/miscutils/bc.c index eb5aff5e2..5966953d2 100644 --- a/miscutils/bc.c +++ b/miscutils/bc.c | |||
@@ -754,6 +754,9 @@ struct globals { | |||
754 | #define INIT_G() do { \ | 754 | #define INIT_G() do { \ |
755 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ | 755 | SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ |
756 | } while (0) | 756 | } while (0) |
757 | #define FREE_G() do { \ | ||
758 | FREE_PTR_TO_GLOBALS(); \ | ||
759 | } while (0) | ||
757 | #define G_posix (ENABLE_BC && (option_mask32 & BC_FLAG_S)) | 760 | #define G_posix (ENABLE_BC && (option_mask32 & BC_FLAG_S)) |
758 | #define G_warn (ENABLE_BC && (option_mask32 & BC_FLAG_W)) | 761 | #define G_warn (ENABLE_BC && (option_mask32 & BC_FLAG_W)) |
759 | #define G_exreg (ENABLE_DC && (option_mask32 & BC_FLAG_X)) | 762 | #define G_exreg (ENABLE_DC && (option_mask32 & BC_FLAG_X)) |
@@ -898,6 +901,16 @@ static void fflush_and_check(void) | |||
898 | bb_perror_msg_and_die("output error"); | 901 | bb_perror_msg_and_die("output error"); |
899 | } | 902 | } |
900 | 903 | ||
904 | #if ENABLE_FEATURE_CLEAN_UP | ||
905 | #define quit_or_return_for_exit() \ | ||
906 | do { \ | ||
907 | G.ttyin = 0; /* do not loop in main loop anymore */ \ | ||
908 | return BC_STATUS_FAILURE; \ | ||
909 | } while (0) | ||
910 | #else | ||
911 | #define quit_or_return_for_exit() quit() | ||
912 | #endif | ||
913 | |||
901 | static void quit(void) NORETURN; | 914 | static void quit(void) NORETURN; |
902 | static void quit(void) | 915 | static void quit(void) |
903 | { | 916 | { |
@@ -929,7 +942,7 @@ static NOINLINE int bc_error_fmt(const char *fmt, ...) | |||
929 | bc_verror_msg(fmt, p); | 942 | bc_verror_msg(fmt, p); |
930 | va_end(p); | 943 | va_end(p); |
931 | 944 | ||
932 | if (!G.ttyin) | 945 | if (!ENABLE_FEATURE_CLEAN_UP && !G.ttyin) |
933 | exit(1); | 946 | exit(1); |
934 | return BC_STATUS_FAILURE; | 947 | return BC_STATUS_FAILURE; |
935 | } | 948 | } |
@@ -949,7 +962,7 @@ static NOINLINE int bc_posix_error_fmt(const char *fmt, ...) | |||
949 | // Do we treat non-POSIX constructs as errors? | 962 | // Do we treat non-POSIX constructs as errors? |
950 | if (!(option_mask32 & BC_FLAG_S)) | 963 | if (!(option_mask32 & BC_FLAG_S)) |
951 | return BC_STATUS_SUCCESS; // no, it's a warning | 964 | return BC_STATUS_SUCCESS; // no, it's a warning |
952 | if (!G.ttyin) | 965 | if (!ENABLE_FEATURE_CLEAN_UP && !G.ttyin) |
953 | exit(1); | 966 | exit(1); |
954 | return BC_STATUS_FAILURE; | 967 | return BC_STATUS_FAILURE; |
955 | } | 968 | } |
@@ -4645,7 +4658,7 @@ static BcStatus bc_parse_stmt(BcParse *p) | |||
4645 | // "quit" is a compile-time command. For example, | 4658 | // "quit" is a compile-time command. For example, |
4646 | // "if (0 == 1) quit" terminates when parsing the statement, | 4659 | // "if (0 == 1) quit" terminates when parsing the statement, |
4647 | // not when it is executed | 4660 | // not when it is executed |
4648 | quit(); | 4661 | quit_or_return_for_exit(); |
4649 | } | 4662 | } |
4650 | 4663 | ||
4651 | case BC_LEX_KEY_RETURN: | 4664 | case BC_LEX_KEY_RETURN: |
@@ -6347,8 +6360,11 @@ static BcStatus bc_program_nquit(void) | |||
6347 | 6360 | ||
6348 | if (G.prog.stack.len < val) | 6361 | if (G.prog.stack.len < val) |
6349 | return bc_error_stack_has_too_few_elements(); | 6362 | return bc_error_stack_has_too_few_elements(); |
6350 | if (G.prog.stack.len == val) | 6363 | if (G.prog.stack.len == val) { |
6364 | if (ENABLE_FEATURE_CLEAN_UP) | ||
6365 | return BC_STATUS_FAILURE; | ||
6351 | quit(); | 6366 | quit(); |
6367 | } | ||
6352 | 6368 | ||
6353 | bc_vec_npop(&G.prog.stack, val); | 6369 | bc_vec_npop(&G.prog.stack, val); |
6354 | 6370 | ||
@@ -6579,7 +6595,7 @@ static BcStatus bc_program_exec(void) | |||
6579 | 6595 | ||
6580 | case BC_INST_HALT: | 6596 | case BC_INST_HALT: |
6581 | { | 6597 | { |
6582 | quit(); | 6598 | quit_or_return_for_exit(); |
6583 | break; | 6599 | break; |
6584 | } | 6600 | } |
6585 | 6601 | ||
@@ -6824,7 +6840,7 @@ static BcStatus bc_program_exec(void) | |||
6824 | case BC_INST_QUIT: | 6840 | case BC_INST_QUIT: |
6825 | { | 6841 | { |
6826 | if (G.prog.stack.len <= 2) | 6842 | if (G.prog.stack.len <= 2) |
6827 | quit(); | 6843 | quit_or_return_for_exit(); |
6828 | bc_vec_npop(&G.prog.stack, 2); | 6844 | bc_vec_npop(&G.prog.stack, 2); |
6829 | break; | 6845 | break; |
6830 | } | 6846 | } |
@@ -7018,6 +7034,12 @@ static BcStatus bc_vm_stdin(void) | |||
7018 | bc_vec_concat(&buffer, buf.v); | 7034 | bc_vec_concat(&buffer, buf.v); |
7019 | s = bc_vm_process(buffer.v); | 7035 | s = bc_vm_process(buffer.v); |
7020 | if (s) { | 7036 | if (s) { |
7037 | if (ENABLE_FEATURE_CLEAN_UP && !G.ttyin) { | ||
7038 | // Debug config, non-interactive mode: | ||
7039 | // return all the way back to main. | ||
7040 | // Non-debug builds do not come here, they exit. | ||
7041 | break; | ||
7042 | } | ||
7021 | fflush_and_check(); | 7043 | fflush_and_check(); |
7022 | fputs("ready for more input\n", stderr); | 7044 | fputs("ready for more input\n", stderr); |
7023 | } | 7045 | } |
@@ -7241,6 +7263,12 @@ static BcStatus bc_vm_exec(void) | |||
7241 | for (i = 0; !s && i < G.files.len; ++i) | 7263 | for (i = 0; !s && i < G.files.len; ++i) |
7242 | s = bc_vm_file(*((char **) bc_vec_item(&G.files, i))); | 7264 | s = bc_vm_file(*((char **) bc_vec_item(&G.files, i))); |
7243 | if (s) { | 7265 | if (s) { |
7266 | if (ENABLE_FEATURE_CLEAN_UP && !G.ttyin) { | ||
7267 | // Debug config, non-interactive mode: | ||
7268 | // return all the way back to main. | ||
7269 | // Non-debug builds do not come here, they exit. | ||
7270 | return s; | ||
7271 | } | ||
7244 | fflush_and_check(); | 7272 | fflush_and_check(); |
7245 | fputs("ready for more input\n", stderr); | 7273 | fputs("ready for more input\n", stderr); |
7246 | } | 7274 | } |
@@ -7254,7 +7282,7 @@ static BcStatus bc_vm_exec(void) | |||
7254 | } | 7282 | } |
7255 | 7283 | ||
7256 | #if ENABLE_FEATURE_CLEAN_UP | 7284 | #if ENABLE_FEATURE_CLEAN_UP |
7257 | static void bc_program_free() | 7285 | static void bc_program_free(void) |
7258 | { | 7286 | { |
7259 | bc_num_free(&G.prog.ib); | 7287 | bc_num_free(&G.prog.ib); |
7260 | bc_num_free(&G.prog.ob); | 7288 | bc_num_free(&G.prog.ob); |
@@ -7397,6 +7425,7 @@ static BcStatus bc_vm_run(int argc, char *argv[], | |||
7397 | 7425 | ||
7398 | #if ENABLE_FEATURE_CLEAN_UP | 7426 | #if ENABLE_FEATURE_CLEAN_UP |
7399 | bc_vm_free(); | 7427 | bc_vm_free(); |
7428 | FREE_G(); | ||
7400 | #endif | 7429 | #endif |
7401 | return st; | 7430 | return st; |
7402 | } | 7431 | } |