diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-06 00:29:22 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-12-06 00:29:22 +0100 |
| commit | e873ff9660a2f02a4b2647b74212e74649726e7d (patch) | |
| tree | ab4725c2bad619ec50d97b9f9f100770ce5009f6 /miscutils | |
| parent | 050b0fe9a7b5a3e4aab1d308637ae6a3bb0a67cb (diff) | |
| download | busybox-w32-e873ff9660a2f02a4b2647b74212e74649726e7d.tar.gz busybox-w32-e873ff9660a2f02a4b2647b74212e74649726e7d.tar.bz2 busybox-w32-e873ff9660a2f02a4b2647b74212e74649726e7d.zip | |
bc: if FEATURE_CLEAN_UP, clean up allocations on exits
Will have exitcode 1 even on "quit" and "halt", is it a problem?
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
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 | } |
