diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-27 14:12:05 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2018-07-27 14:12:05 +0200 |
commit | 9dda9270df3108bb85b29c6d382a3477aeb3344b (patch) | |
tree | 63d8b8bba2d2f42a6c152eb5aa2b6aef5f774dc6 | |
parent | 186cf4976768029113cf8438734a65bf2c489c5c (diff) | |
download | busybox-9dda9270df3108bb85b29c6d382a3477aeb3344b.tar.gz |
hush: fix "set -x" output prefix overlapping for v="..`cmd`.." case
Was printing initial "+" prefix for the assignment, that printing
"+ cmd"
then printing the expanded " v=VAL" string.
Delay printing of "+" prefix for the assignment to after expansion.
function old new delta
run_pipe 1883 1902 +19
builtin_eval 127 133 +6
expand_vars_to_list 1103 1106 +3
dump_cmd_in_x_mode 144 142 -2
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 28/-2) Total: 26 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/shell/hush.c b/shell/hush.c index 1ac2db381..e9212cefc 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -896,7 +896,6 @@ struct globals { char o_opt[NUM_OPT_O]; #if ENABLE_HUSH_MODE_X - smalluint x_mode_depth; # define G_x_mode (G.o_opt[OPT_O_XTRACE]) #else # define G_x_mode 0 @@ -956,6 +955,9 @@ struct globals { # endif struct function *top_func; #endif +#if ENABLE_HUSH_MODE_X + unsigned x_mode_depth; +#endif /* Signal and trap handling */ #if ENABLE_HUSH_FAST unsigned count_SIGCHLD; @@ -7247,6 +7249,7 @@ static int generate_stream_from_string(const char *s, pid_t *pid_p) CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ reset_traps_to_defaults(); IF_HUSH_MODE_X(G.x_mode_depth++;) + //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); parse_and_run_string(s); _exit(G.last_exitcode); # else @@ -8032,17 +8035,16 @@ static void dump_cmd_in_x_mode(char **argv) if (G_x_mode && argv) { /* We want to output the line in one write op */ char *buf, *p; - int len; - int n; + unsigned len; + unsigned n; - len = G.x_mode_depth + 3; /* "+[+++...]<cmd...>\n\0" */ + len = G.x_mode_depth + 3; /* "+[+++...][ cmd...]\n\0" */ n = 0; while (argv[n]) len += strlen(argv[n++]) + 1; p = buf = xmalloc(len); n = G.x_mode_depth; - while (n-- >= 0) - *p++ = '+'; + do *p++ = '+'; while ((int)(--n) >= 0); n = 0; while (argv[n]) p += sprintf(p, " %s", argv[n++]); @@ -8835,21 +8837,23 @@ static NOINLINE int run_pipe(struct pipe *pi) restore_redirects(squirrel); /* Set shell variables */ -#if ENABLE_HUSH_MODE_X - if (G_x_mode) { - int n = G.x_mode_depth; - while (n-- >= 0) - bb_putchar_stderr('+'); - } -#endif i = 0; while (i < command->assignment_cnt) { char *p = expand_string_to_string(argv[i], EXP_FLAG_ESC_GLOB_CHARS, /*unbackslash:*/ 1 ); - if (G_x_mode) +#if ENABLE_HUSH_MODE_X + if (G_x_mode) { + if (i == 0) { + unsigned n = G.x_mode_depth; + do + bb_putchar_stderr('+'); + while ((int)(--n) >= 0); + } fprintf(stderr, " %s", p); + } +#endif debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); if (set_local_var(p, /*flag:*/ 0)) { /* assignment to readonly var / putenv error? */ @@ -10246,6 +10250,7 @@ static int FAST_FUNC builtin_eval(char **argv) return EXIT_SUCCESS; IF_HUSH_MODE_X(G.x_mode_depth++;) + //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); if (!argv[1]) { /* bash: * eval "echo Hi; done" ("done" is syntax error): @@ -10276,6 +10281,7 @@ static int FAST_FUNC builtin_eval(char **argv) free(str); } IF_HUSH_MODE_X(G.x_mode_depth--;) + //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth); return G.last_exitcode; } |