aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--shell/hush.c105
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[] = {
982static void debug_print_strings(const char *prefix, char **vv) 982static 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