diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2010-12-21 21:18:12 +0100 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2010-12-21 21:18:12 +0100 |
commit | 75eb9d20e9e672c33e377221d1f7d4546f919f9e (patch) | |
tree | 3e3d37790da52daea325b34f9e52d07942c9fff7 /shell | |
parent | 51d714ce7e8d68f0762d89b2a67cf42d2c991685 (diff) | |
download | busybox-w32-75eb9d20e9e672c33e377221d1f7d4546f919f9e.tar.gz busybox-w32-75eb9d20e9e672c33e377221d1f7d4546f919f9e.tar.bz2 busybox-w32-75eb9d20e9e672c33e377221d1f7d4546f919f9e.zip |
hush: fix FEATURE_CLEAN_UP code (was freeing unallocated memory)
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/shell/hush.c b/shell/hush.c index 2bca9aa87..a771e9cd9 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -931,7 +931,7 @@ static const struct built_in_command bltins2[] = { | |||
931 | */ | 931 | */ |
932 | #if HUSH_DEBUG | 932 | #if HUSH_DEBUG |
933 | /* prevent disasters with G.debug_indent < 0 */ | 933 | /* prevent disasters with G.debug_indent < 0 */ |
934 | # define indent() fprintf(stderr, "%*s", (G.debug_indent * 2) & 0xff, "") | 934 | # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "") |
935 | # define debug_enter() (G.debug_indent++) | 935 | # define debug_enter() (G.debug_indent++) |
936 | # define debug_leave() (G.debug_indent--) | 936 | # define debug_leave() (G.debug_indent--) |
937 | #else | 937 | #else |
@@ -941,56 +941,56 @@ static const struct built_in_command bltins2[] = { | |||
941 | #endif | 941 | #endif |
942 | 942 | ||
943 | #ifndef debug_printf | 943 | #ifndef debug_printf |
944 | # define debug_printf(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 944 | # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__)) |
945 | #endif | 945 | #endif |
946 | 946 | ||
947 | #ifndef debug_printf_parse | 947 | #ifndef debug_printf_parse |
948 | # define debug_printf_parse(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 948 | # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__)) |
949 | #endif | 949 | #endif |
950 | 950 | ||
951 | #ifndef debug_printf_exec | 951 | #ifndef debug_printf_exec |
952 | #define debug_printf_exec(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 952 | #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__)) |
953 | #endif | 953 | #endif |
954 | 954 | ||
955 | #ifndef debug_printf_env | 955 | #ifndef debug_printf_env |
956 | # define debug_printf_env(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 956 | # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__)) |
957 | #endif | 957 | #endif |
958 | 958 | ||
959 | #ifndef debug_printf_jobs | 959 | #ifndef debug_printf_jobs |
960 | # define debug_printf_jobs(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 960 | # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__)) |
961 | # define DEBUG_JOBS 1 | 961 | # define DEBUG_JOBS 1 |
962 | #else | 962 | #else |
963 | # define DEBUG_JOBS 0 | 963 | # define DEBUG_JOBS 0 |
964 | #endif | 964 | #endif |
965 | 965 | ||
966 | #ifndef debug_printf_expand | 966 | #ifndef debug_printf_expand |
967 | # define debug_printf_expand(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 967 | # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__)) |
968 | # define DEBUG_EXPAND 1 | 968 | # define DEBUG_EXPAND 1 |
969 | #else | 969 | #else |
970 | # define DEBUG_EXPAND 0 | 970 | # define DEBUG_EXPAND 0 |
971 | #endif | 971 | #endif |
972 | 972 | ||
973 | #ifndef debug_printf_varexp | 973 | #ifndef debug_printf_varexp |
974 | # define debug_printf_varexp(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 974 | # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__)) |
975 | #endif | 975 | #endif |
976 | 976 | ||
977 | #ifndef debug_printf_glob | 977 | #ifndef debug_printf_glob |
978 | # define debug_printf_glob(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 978 | # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__)) |
979 | # define DEBUG_GLOB 1 | 979 | # define DEBUG_GLOB 1 |
980 | #else | 980 | #else |
981 | # define DEBUG_GLOB 0 | 981 | # define DEBUG_GLOB 0 |
982 | #endif | 982 | #endif |
983 | 983 | ||
984 | #ifndef debug_printf_list | 984 | #ifndef debug_printf_list |
985 | # define debug_printf_list(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 985 | # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__)) |
986 | #endif | 986 | #endif |
987 | 987 | ||
988 | #ifndef debug_printf_subst | 988 | #ifndef debug_printf_subst |
989 | # define debug_printf_subst(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 989 | # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__)) |
990 | #endif | 990 | #endif |
991 | 991 | ||
992 | #ifndef debug_printf_clean | 992 | #ifndef debug_printf_clean |
993 | # define debug_printf_clean(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 993 | # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__)) |
994 | # define DEBUG_CLEAN 1 | 994 | # define DEBUG_CLEAN 1 |
995 | #else | 995 | #else |
996 | # define DEBUG_CLEAN 0 | 996 | # define DEBUG_CLEAN 0 |
@@ -1000,9 +1000,9 @@ static const struct built_in_command bltins2[] = { | |||
1000 | static void debug_print_strings(const char *prefix, char **vv) | 1000 | static void debug_print_strings(const char *prefix, char **vv) |
1001 | { | 1001 | { |
1002 | indent(); | 1002 | indent(); |
1003 | fprintf(stderr, "%s:\n", prefix); | 1003 | fdprintf(2, "%s:\n", prefix); |
1004 | while (*vv) | 1004 | while (*vv) |
1005 | fprintf(stderr, " '%s'\n", *vv++); | 1005 | fdprintf(2, " '%s'\n", *vv++); |
1006 | } | 1006 | } |
1007 | #else | 1007 | #else |
1008 | # define debug_print_strings(prefix, vv) ((void)0) | 1008 | # define debug_print_strings(prefix, vv) ((void)0) |
@@ -1434,6 +1434,22 @@ static void hush_exit(int exitcode) | |||
1434 | builtin_eval(argv); | 1434 | builtin_eval(argv); |
1435 | } | 1435 | } |
1436 | 1436 | ||
1437 | #if ENABLE_FEATURE_CLEAN_UP | ||
1438 | { | ||
1439 | struct variable *cur_var; | ||
1440 | if (G.cwd != bb_msg_unknown) | ||
1441 | free((char*)G.cwd); | ||
1442 | cur_var = G.top_var; | ||
1443 | while (cur_var) { | ||
1444 | struct variable *tmp = cur_var; | ||
1445 | if (!cur_var->max_len) | ||
1446 | free(cur_var->varstr); | ||
1447 | cur_var = cur_var->next; | ||
1448 | free(tmp); | ||
1449 | } | ||
1450 | } | ||
1451 | #endif | ||
1452 | |||
1437 | #if ENABLE_HUSH_JOB | 1453 | #if ENABLE_HUSH_JOB |
1438 | fflush_all(); | 1454 | fflush_all(); |
1439 | sigexit(- (exitcode & 0xff)); | 1455 | sigexit(- (exitcode & 0xff)); |
@@ -2176,22 +2192,22 @@ static void debug_print_list(const char *prefix, o_string *o, int n) | |||
2176 | int i = 0; | 2192 | int i = 0; |
2177 | 2193 | ||
2178 | indent(); | 2194 | indent(); |
2179 | fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n", | 2195 | fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n", |
2180 | prefix, list, n, string_start, o->length, o->maxlen, | 2196 | prefix, list, n, string_start, o->length, o->maxlen, |
2181 | !!(o->o_expflags & EXP_FLAG_GLOB), | 2197 | !!(o->o_expflags & EXP_FLAG_GLOB), |
2182 | o->has_quoted_part, | 2198 | o->has_quoted_part, |
2183 | !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | 2199 | !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); |
2184 | while (i < n) { | 2200 | while (i < n) { |
2185 | indent(); | 2201 | indent(); |
2186 | fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i], | 2202 | fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i], |
2187 | o->data + (int)list[i] + string_start, | 2203 | o->data + (int)(uintptr_t)list[i] + string_start, |
2188 | o->data + (int)list[i] + string_start); | 2204 | o->data + (int)(uintptr_t)list[i] + string_start); |
2189 | i++; | 2205 | i++; |
2190 | } | 2206 | } |
2191 | if (n) { | 2207 | if (n) { |
2192 | const char *p = o->data + (int)list[n - 1] + string_start; | 2208 | const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start; |
2193 | indent(); | 2209 | indent(); |
2194 | fprintf(stderr, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); | 2210 | fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); |
2195 | } | 2211 | } |
2196 | } | 2212 | } |
2197 | #else | 2213 | #else |
@@ -2690,18 +2706,18 @@ static void debug_print_tree(struct pipe *pi, int lvl) | |||
2690 | 2706 | ||
2691 | pin = 0; | 2707 | pin = 0; |
2692 | while (pi) { | 2708 | while (pi) { |
2693 | fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "", | 2709 | fdprintf(2, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "", |
2694 | pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]); | 2710 | pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]); |
2695 | prn = 0; | 2711 | prn = 0; |
2696 | while (prn < pi->num_cmds) { | 2712 | while (prn < pi->num_cmds) { |
2697 | struct command *command = &pi->cmds[prn]; | 2713 | struct command *command = &pi->cmds[prn]; |
2698 | char **argv = command->argv; | 2714 | char **argv = command->argv; |
2699 | 2715 | ||
2700 | fprintf(stderr, "%*s cmd %d assignment_cnt:%d", | 2716 | fdprintf(2, "%*s cmd %d assignment_cnt:%d", |
2701 | lvl*2, "", prn, | 2717 | lvl*2, "", prn, |
2702 | command->assignment_cnt); | 2718 | command->assignment_cnt); |
2703 | if (command->group) { | 2719 | if (command->group) { |
2704 | fprintf(stderr, " group %s: (argv=%p)%s%s\n", | 2720 | fdprintf(2, " group %s: (argv=%p)%s%s\n", |
2705 | CMDTYPE[command->cmd_type], | 2721 | CMDTYPE[command->cmd_type], |
2706 | argv | 2722 | argv |
2707 | # if !BB_MMU | 2723 | # if !BB_MMU |
@@ -2715,10 +2731,10 @@ static void debug_print_tree(struct pipe *pi, int lvl) | |||
2715 | continue; | 2731 | continue; |
2716 | } | 2732 | } |
2717 | if (argv) while (*argv) { | 2733 | if (argv) while (*argv) { |
2718 | fprintf(stderr, " '%s'", *argv); | 2734 | fdprintf(2, " '%s'", *argv); |
2719 | argv++; | 2735 | argv++; |
2720 | } | 2736 | } |
2721 | fprintf(stderr, "\n"); | 2737 | fdprintf(2, "\n"); |
2722 | prn++; | 2738 | prn++; |
2723 | } | 2739 | } |
2724 | pi = pi->next; | 2740 | pi = pi->next; |
@@ -7463,7 +7479,7 @@ int hush_main(int argc, char **argv) | |||
7463 | unsigned builtin_argc; | 7479 | unsigned builtin_argc; |
7464 | char **e; | 7480 | char **e; |
7465 | struct variable *cur_var; | 7481 | struct variable *cur_var; |
7466 | struct variable shell_ver; | 7482 | struct variable *shell_ver; |
7467 | 7483 | ||
7468 | INIT_G(); | 7484 | INIT_G(); |
7469 | if (EXIT_SUCCESS) /* if EXIT_SUCCESS == 0, it is already done */ | 7485 | if (EXIT_SUCCESS) /* if EXIT_SUCCESS == 0, it is already done */ |
@@ -7472,17 +7488,17 @@ int hush_main(int argc, char **argv) | |||
7472 | G.argv0_for_re_execing = argv[0]; | 7488 | G.argv0_for_re_execing = argv[0]; |
7473 | #endif | 7489 | #endif |
7474 | /* Deal with HUSH_VERSION */ | 7490 | /* Deal with HUSH_VERSION */ |
7475 | memset(&shell_ver, 0, sizeof(shell_ver)); | 7491 | shell_ver = xzalloc(sizeof(*shell_ver)); |
7476 | shell_ver.flg_export = 1; | 7492 | shell_ver->flg_export = 1; |
7477 | shell_ver.flg_read_only = 1; | 7493 | shell_ver->flg_read_only = 1; |
7478 | /* Code which handles ${var<op>...} needs writable values for all variables, | 7494 | /* Code which handles ${var<op>...} needs writable values for all variables, |
7479 | * therefore we xstrdup: */ | 7495 | * therefore we xstrdup: */ |
7480 | shell_ver.varstr = xstrdup(hush_version_str), | 7496 | shell_ver->varstr = xstrdup(hush_version_str); |
7481 | G.top_var = &shell_ver; | ||
7482 | /* Create shell local variables from the values | 7497 | /* Create shell local variables from the values |
7483 | * currently living in the environment */ | 7498 | * currently living in the environment */ |
7484 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); | 7499 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); |
7485 | unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ | 7500 | unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ |
7501 | G.top_var = shell_ver; | ||
7486 | cur_var = G.top_var; | 7502 | cur_var = G.top_var; |
7487 | e = environ; | 7503 | e = environ; |
7488 | if (e) while (*e) { | 7504 | if (e) while (*e) { |
@@ -7497,8 +7513,8 @@ int hush_main(int argc, char **argv) | |||
7497 | e++; | 7513 | e++; |
7498 | } | 7514 | } |
7499 | /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */ | 7515 | /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */ |
7500 | debug_printf_env("putenv '%s'\n", shell_ver.varstr); | 7516 | debug_printf_env("putenv '%s'\n", shell_ver->varstr); |
7501 | putenv(shell_ver.varstr); | 7517 | putenv(shell_ver->varstr); |
7502 | 7518 | ||
7503 | /* Export PWD */ | 7519 | /* Export PWD */ |
7504 | set_pwd_var(/*exp:*/ 1); | 7520 | set_pwd_var(/*exp:*/ 1); |
@@ -7858,18 +7874,6 @@ int hush_main(int argc, char **argv) | |||
7858 | parse_and_run_file(stdin); | 7874 | parse_and_run_file(stdin); |
7859 | 7875 | ||
7860 | final_return: | 7876 | final_return: |
7861 | #if ENABLE_FEATURE_CLEAN_UP | ||
7862 | if (G.cwd != bb_msg_unknown) | ||
7863 | free((char*)G.cwd); | ||
7864 | cur_var = G.top_var->next; | ||
7865 | while (cur_var) { | ||
7866 | struct variable *tmp = cur_var; | ||
7867 | if (!cur_var->max_len) | ||
7868 | free(cur_var->varstr); | ||
7869 | cur_var = cur_var->next; | ||
7870 | free(tmp); | ||
7871 | } | ||
7872 | #endif | ||
7873 | hush_exit(G.last_exitcode); | 7877 | hush_exit(G.last_exitcode); |
7874 | } | 7878 | } |
7875 | 7879 | ||