diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-16 20:00:24 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-01-16 20:00:24 +0100 |
| commit | 12d97b66805f87e535962963e858fc2422ffdbc7 (patch) | |
| tree | 10836c6158a05a505d8a7cb83313cc908e837a50 /shell | |
| parent | 2a1571bfa003233470140a17be4ae4f0239f5a24 (diff) | |
| download | busybox-w32-1_18_2.tar.gz busybox-w32-1_18_2.tar.bz2 busybox-w32-1_18_2.zip | |
apply post-1.18.1 patches, bump version to 1.18.21_18_2
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 105 |
1 files changed, 59 insertions, 46 deletions
diff --git a/shell/hush.c b/shell/hush.c index fa7e4f563..f9f815289 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -913,7 +913,7 @@ static const struct built_in_command bltins2[] = { | |||
| 913 | */ | 913 | */ |
| 914 | #if HUSH_DEBUG | 914 | #if HUSH_DEBUG |
| 915 | /* prevent disasters with G.debug_indent < 0 */ | 915 | /* prevent disasters with G.debug_indent < 0 */ |
| 916 | # define indent() fprintf(stderr, "%*s", (G.debug_indent * 2) & 0xff, "") | 916 | # define indent() fdprintf(2, "%*s", (G.debug_indent * 2) & 0xff, "") |
| 917 | # define debug_enter() (G.debug_indent++) | 917 | # define debug_enter() (G.debug_indent++) |
| 918 | # define debug_leave() (G.debug_indent--) | 918 | # define debug_leave() (G.debug_indent--) |
| 919 | #else | 919 | #else |
| @@ -923,56 +923,56 @@ static const struct built_in_command bltins2[] = { | |||
| 923 | #endif | 923 | #endif |
| 924 | 924 | ||
| 925 | #ifndef debug_printf | 925 | #ifndef debug_printf |
| 926 | # define debug_printf(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 926 | # define debug_printf(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 927 | #endif | 927 | #endif |
| 928 | 928 | ||
| 929 | #ifndef debug_printf_parse | 929 | #ifndef debug_printf_parse |
| 930 | # define debug_printf_parse(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 930 | # define debug_printf_parse(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 931 | #endif | 931 | #endif |
| 932 | 932 | ||
| 933 | #ifndef debug_printf_exec | 933 | #ifndef debug_printf_exec |
| 934 | #define debug_printf_exec(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 934 | #define debug_printf_exec(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 935 | #endif | 935 | #endif |
| 936 | 936 | ||
| 937 | #ifndef debug_printf_env | 937 | #ifndef debug_printf_env |
| 938 | # define debug_printf_env(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 938 | # define debug_printf_env(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 939 | #endif | 939 | #endif |
| 940 | 940 | ||
| 941 | #ifndef debug_printf_jobs | 941 | #ifndef debug_printf_jobs |
| 942 | # define debug_printf_jobs(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 942 | # define debug_printf_jobs(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 943 | # define DEBUG_JOBS 1 | 943 | # define DEBUG_JOBS 1 |
| 944 | #else | 944 | #else |
| 945 | # define DEBUG_JOBS 0 | 945 | # define DEBUG_JOBS 0 |
| 946 | #endif | 946 | #endif |
| 947 | 947 | ||
| 948 | #ifndef debug_printf_expand | 948 | #ifndef debug_printf_expand |
| 949 | # define debug_printf_expand(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 949 | # define debug_printf_expand(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 950 | # define DEBUG_EXPAND 1 | 950 | # define DEBUG_EXPAND 1 |
| 951 | #else | 951 | #else |
| 952 | # define DEBUG_EXPAND 0 | 952 | # define DEBUG_EXPAND 0 |
| 953 | #endif | 953 | #endif |
| 954 | 954 | ||
| 955 | #ifndef debug_printf_varexp | 955 | #ifndef debug_printf_varexp |
| 956 | # define debug_printf_varexp(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 956 | # define debug_printf_varexp(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 957 | #endif | 957 | #endif |
| 958 | 958 | ||
| 959 | #ifndef debug_printf_glob | 959 | #ifndef debug_printf_glob |
| 960 | # define debug_printf_glob(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 960 | # define debug_printf_glob(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 961 | # define DEBUG_GLOB 1 | 961 | # define DEBUG_GLOB 1 |
| 962 | #else | 962 | #else |
| 963 | # define DEBUG_GLOB 0 | 963 | # define DEBUG_GLOB 0 |
| 964 | #endif | 964 | #endif |
| 965 | 965 | ||
| 966 | #ifndef debug_printf_list | 966 | #ifndef debug_printf_list |
| 967 | # define debug_printf_list(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 967 | # define debug_printf_list(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 968 | #endif | 968 | #endif |
| 969 | 969 | ||
| 970 | #ifndef debug_printf_subst | 970 | #ifndef debug_printf_subst |
| 971 | # define debug_printf_subst(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 971 | # define debug_printf_subst(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 972 | #endif | 972 | #endif |
| 973 | 973 | ||
| 974 | #ifndef debug_printf_clean | 974 | #ifndef debug_printf_clean |
| 975 | # define debug_printf_clean(...) (indent(), fprintf(stderr, __VA_ARGS__)) | 975 | # define debug_printf_clean(...) (indent(), fdprintf(2, __VA_ARGS__)) |
| 976 | # define DEBUG_CLEAN 1 | 976 | # define DEBUG_CLEAN 1 |
| 977 | #else | 977 | #else |
| 978 | # define DEBUG_CLEAN 0 | 978 | # define DEBUG_CLEAN 0 |
| @@ -982,9 +982,9 @@ static const struct built_in_command bltins2[] = { | |||
| 982 | static void debug_print_strings(const char *prefix, char **vv) | 982 | static void debug_print_strings(const char *prefix, char **vv) |
| 983 | { | 983 | { |
| 984 | indent(); | 984 | indent(); |
| 985 | fprintf(stderr, "%s:\n", prefix); | 985 | fdprintf(2, "%s:\n", prefix); |
| 986 | while (*vv) | 986 | while (*vv) |
| 987 | fprintf(stderr, " '%s'\n", *vv++); | 987 | fdprintf(2, " '%s'\n", *vv++); |
| 988 | } | 988 | } |
| 989 | #else | 989 | #else |
| 990 | # define debug_print_strings(prefix, vv) ((void)0) | 990 | # define debug_print_strings(prefix, vv) ((void)0) |
| @@ -1416,6 +1416,22 @@ static void hush_exit(int exitcode) | |||
| 1416 | builtin_eval(argv); | 1416 | builtin_eval(argv); |
| 1417 | } | 1417 | } |
| 1418 | 1418 | ||
| 1419 | #if ENABLE_FEATURE_CLEAN_UP | ||
| 1420 | { | ||
| 1421 | struct variable *cur_var; | ||
| 1422 | if (G.cwd != bb_msg_unknown) | ||
| 1423 | free((char*)G.cwd); | ||
| 1424 | cur_var = G.top_var; | ||
| 1425 | while (cur_var) { | ||
| 1426 | struct variable *tmp = cur_var; | ||
| 1427 | if (!cur_var->max_len) | ||
| 1428 | free(cur_var->varstr); | ||
| 1429 | cur_var = cur_var->next; | ||
| 1430 | free(tmp); | ||
| 1431 | } | ||
| 1432 | } | ||
| 1433 | #endif | ||
| 1434 | |||
| 1419 | #if ENABLE_HUSH_JOB | 1435 | #if ENABLE_HUSH_JOB |
| 1420 | fflush_all(); | 1436 | fflush_all(); |
| 1421 | sigexit(- (exitcode & 0xff)); | 1437 | sigexit(- (exitcode & 0xff)); |
| @@ -2158,22 +2174,22 @@ static void debug_print_list(const char *prefix, o_string *o, int n) | |||
| 2158 | int i = 0; | 2174 | int i = 0; |
| 2159 | 2175 | ||
| 2160 | indent(); | 2176 | indent(); |
| 2161 | fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n", | 2177 | fdprintf(2, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n", |
| 2162 | prefix, list, n, string_start, o->length, o->maxlen, | 2178 | prefix, list, n, string_start, o->length, o->maxlen, |
| 2163 | !!(o->o_expflags & EXP_FLAG_GLOB), | 2179 | !!(o->o_expflags & EXP_FLAG_GLOB), |
| 2164 | o->has_quoted_part, | 2180 | o->has_quoted_part, |
| 2165 | !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); | 2181 | !!(o->o_expflags & EXP_FLAG_ESC_GLOB_CHARS)); |
| 2166 | while (i < n) { | 2182 | while (i < n) { |
| 2167 | indent(); | 2183 | indent(); |
| 2168 | fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i], | 2184 | fdprintf(2, " list[%d]=%d '%s' %p\n", i, (int)(uintptr_t)list[i], |
| 2169 | o->data + (int)list[i] + string_start, | 2185 | o->data + (int)(uintptr_t)list[i] + string_start, |
| 2170 | o->data + (int)list[i] + string_start); | 2186 | o->data + (int)(uintptr_t)list[i] + string_start); |
| 2171 | i++; | 2187 | i++; |
| 2172 | } | 2188 | } |
| 2173 | if (n) { | 2189 | if (n) { |
| 2174 | const char *p = o->data + (int)list[n - 1] + string_start; | 2190 | const char *p = o->data + (int)(uintptr_t)list[n - 1] + string_start; |
| 2175 | indent(); | 2191 | indent(); |
| 2176 | fprintf(stderr, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); | 2192 | fdprintf(2, " total_sz:%ld\n", (long)((p + strlen(p) + 1) - o->data)); |
| 2177 | } | 2193 | } |
| 2178 | } | 2194 | } |
| 2179 | #else | 2195 | #else |
| @@ -2672,18 +2688,18 @@ static void debug_print_tree(struct pipe *pi, int lvl) | |||
| 2672 | 2688 | ||
| 2673 | pin = 0; | 2689 | pin = 0; |
| 2674 | while (pi) { | 2690 | while (pi) { |
| 2675 | fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "", | 2691 | fdprintf(2, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "", |
| 2676 | pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]); | 2692 | pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]); |
| 2677 | prn = 0; | 2693 | prn = 0; |
| 2678 | while (prn < pi->num_cmds) { | 2694 | while (prn < pi->num_cmds) { |
| 2679 | struct command *command = &pi->cmds[prn]; | 2695 | struct command *command = &pi->cmds[prn]; |
| 2680 | char **argv = command->argv; | 2696 | char **argv = command->argv; |
| 2681 | 2697 | ||
| 2682 | fprintf(stderr, "%*s cmd %d assignment_cnt:%d", | 2698 | fdprintf(2, "%*s cmd %d assignment_cnt:%d", |
| 2683 | lvl*2, "", prn, | 2699 | lvl*2, "", prn, |
| 2684 | command->assignment_cnt); | 2700 | command->assignment_cnt); |
| 2685 | if (command->group) { | 2701 | if (command->group) { |
| 2686 | fprintf(stderr, " group %s: (argv=%p)%s%s\n", | 2702 | fdprintf(2, " group %s: (argv=%p)%s%s\n", |
| 2687 | CMDTYPE[command->cmd_type], | 2703 | CMDTYPE[command->cmd_type], |
| 2688 | argv | 2704 | argv |
| 2689 | # if !BB_MMU | 2705 | # if !BB_MMU |
| @@ -2697,10 +2713,10 @@ static void debug_print_tree(struct pipe *pi, int lvl) | |||
| 2697 | continue; | 2713 | continue; |
| 2698 | } | 2714 | } |
| 2699 | if (argv) while (*argv) { | 2715 | if (argv) while (*argv) { |
| 2700 | fprintf(stderr, " '%s'", *argv); | 2716 | fdprintf(2, " '%s'", *argv); |
| 2701 | argv++; | 2717 | argv++; |
| 2702 | } | 2718 | } |
| 2703 | fprintf(stderr, "\n"); | 2719 | fdprintf(2, "\n"); |
| 2704 | prn++; | 2720 | prn++; |
| 2705 | } | 2721 | } |
| 2706 | pi = pi->next; | 2722 | pi = pi->next; |
| @@ -4106,7 +4122,16 @@ static struct pipe *parse_stream(char **pstring, | |||
| 4106 | if (IS_NULL_CMD(ctx.command) | 4122 | if (IS_NULL_CMD(ctx.command) |
| 4107 | && dest.length == 0 && !dest.has_quoted_part | 4123 | && dest.length == 0 && !dest.has_quoted_part |
| 4108 | ) { | 4124 | ) { |
| 4109 | continue; | 4125 | /* This newline can be ignored. But... |
| 4126 | * without the below check, interactive shell | ||
| 4127 | * will ignore even lines with bare <newline>, | ||
| 4128 | * and show the continuation prompt: | ||
| 4129 | * ps1_prompt$ <enter> | ||
| 4130 | * ps2> _ <=== wrong prompt, should be ps1 | ||
| 4131 | */ | ||
| 4132 | struct pipe *pi = ctx.list_head; | ||
| 4133 | if (pi->num_cmds != 0) | ||
| 4134 | continue; | ||
| 4110 | } | 4135 | } |
| 4111 | /* Treat newline as a command separator. */ | 4136 | /* Treat newline as a command separator. */ |
| 4112 | done_pipe(&ctx, PIPE_SEQ); | 4137 | done_pipe(&ctx, PIPE_SEQ); |
| @@ -7445,7 +7470,7 @@ int hush_main(int argc, char **argv) | |||
| 7445 | unsigned builtin_argc; | 7470 | unsigned builtin_argc; |
| 7446 | char **e; | 7471 | char **e; |
| 7447 | struct variable *cur_var; | 7472 | struct variable *cur_var; |
| 7448 | struct variable shell_ver; | 7473 | struct variable *shell_ver; |
| 7449 | 7474 | ||
| 7450 | INIT_G(); | 7475 | INIT_G(); |
| 7451 | if (EXIT_SUCCESS) /* if EXIT_SUCCESS == 0, it is already done */ | 7476 | if (EXIT_SUCCESS) /* if EXIT_SUCCESS == 0, it is already done */ |
| @@ -7454,17 +7479,17 @@ int hush_main(int argc, char **argv) | |||
| 7454 | G.argv0_for_re_execing = argv[0]; | 7479 | G.argv0_for_re_execing = argv[0]; |
| 7455 | #endif | 7480 | #endif |
| 7456 | /* Deal with HUSH_VERSION */ | 7481 | /* Deal with HUSH_VERSION */ |
| 7457 | memset(&shell_ver, 0, sizeof(shell_ver)); | 7482 | shell_ver = xzalloc(sizeof(*shell_ver)); |
| 7458 | shell_ver.flg_export = 1; | 7483 | shell_ver->flg_export = 1; |
| 7459 | shell_ver.flg_read_only = 1; | 7484 | shell_ver->flg_read_only = 1; |
| 7460 | /* Code which handles ${var<op>...} needs writable values for all variables, | 7485 | /* Code which handles ${var<op>...} needs writable values for all variables, |
| 7461 | * therefore we xstrdup: */ | 7486 | * therefore we xstrdup: */ |
| 7462 | shell_ver.varstr = xstrdup(hush_version_str), | 7487 | shell_ver->varstr = xstrdup(hush_version_str); |
| 7463 | G.top_var = &shell_ver; | ||
| 7464 | /* Create shell local variables from the values | 7488 | /* Create shell local variables from the values |
| 7465 | * currently living in the environment */ | 7489 | * currently living in the environment */ |
| 7466 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); | 7490 | debug_printf_env("unsetenv '%s'\n", "HUSH_VERSION"); |
| 7467 | unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ | 7491 | unsetenv("HUSH_VERSION"); /* in case it exists in initial env */ |
| 7492 | G.top_var = shell_ver; | ||
| 7468 | cur_var = G.top_var; | 7493 | cur_var = G.top_var; |
| 7469 | e = environ; | 7494 | e = environ; |
| 7470 | if (e) while (*e) { | 7495 | if (e) while (*e) { |
| @@ -7479,8 +7504,8 @@ int hush_main(int argc, char **argv) | |||
| 7479 | e++; | 7504 | e++; |
| 7480 | } | 7505 | } |
| 7481 | /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */ | 7506 | /* (Re)insert HUSH_VERSION into env (AFTER we scanned the env!) */ |
| 7482 | debug_printf_env("putenv '%s'\n", shell_ver.varstr); | 7507 | debug_printf_env("putenv '%s'\n", shell_ver->varstr); |
| 7483 | putenv(shell_ver.varstr); | 7508 | putenv(shell_ver->varstr); |
| 7484 | 7509 | ||
| 7485 | /* Export PWD */ | 7510 | /* Export PWD */ |
| 7486 | set_pwd_var(/*exp:*/ 1); | 7511 | set_pwd_var(/*exp:*/ 1); |
| @@ -7840,18 +7865,6 @@ int hush_main(int argc, char **argv) | |||
| 7840 | parse_and_run_file(stdin); | 7865 | parse_and_run_file(stdin); |
| 7841 | 7866 | ||
| 7842 | final_return: | 7867 | final_return: |
| 7843 | #if ENABLE_FEATURE_CLEAN_UP | ||
| 7844 | if (G.cwd != bb_msg_unknown) | ||
| 7845 | free((char*)G.cwd); | ||
| 7846 | cur_var = G.top_var->next; | ||
| 7847 | while (cur_var) { | ||
| 7848 | struct variable *tmp = cur_var; | ||
| 7849 | if (!cur_var->max_len) | ||
| 7850 | free(cur_var->varstr); | ||
| 7851 | cur_var = cur_var->next; | ||
| 7852 | free(tmp); | ||
| 7853 | } | ||
| 7854 | #endif | ||
| 7855 | hush_exit(G.last_exitcode); | 7868 | hush_exit(G.last_exitcode); |
| 7856 | } | 7869 | } |
| 7857 | 7870 | ||
