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-w32-9dda9270df3108bb85b29c6d382a3477aeb3344b.tar.gz busybox-w32-9dda9270df3108bb85b29c6d382a3477aeb3344b.tar.bz2 busybox-w32-9dda9270df3108bb85b29c6d382a3477aeb3344b.zip |
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 { | |||
896 | 896 | ||
897 | char o_opt[NUM_OPT_O]; | 897 | char o_opt[NUM_OPT_O]; |
898 | #if ENABLE_HUSH_MODE_X | 898 | #if ENABLE_HUSH_MODE_X |
899 | smalluint x_mode_depth; | ||
900 | # define G_x_mode (G.o_opt[OPT_O_XTRACE]) | 899 | # define G_x_mode (G.o_opt[OPT_O_XTRACE]) |
901 | #else | 900 | #else |
902 | # define G_x_mode 0 | 901 | # define G_x_mode 0 |
@@ -956,6 +955,9 @@ struct globals { | |||
956 | # endif | 955 | # endif |
957 | struct function *top_func; | 956 | struct function *top_func; |
958 | #endif | 957 | #endif |
958 | #if ENABLE_HUSH_MODE_X | ||
959 | unsigned x_mode_depth; | ||
960 | #endif | ||
959 | /* Signal and trap handling */ | 961 | /* Signal and trap handling */ |
960 | #if ENABLE_HUSH_FAST | 962 | #if ENABLE_HUSH_FAST |
961 | unsigned count_SIGCHLD; | 963 | unsigned count_SIGCHLD; |
@@ -7247,6 +7249,7 @@ static int generate_stream_from_string(const char *s, pid_t *pid_p) | |||
7247 | CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ | 7249 | CLEAR_RANDOM_T(&G.random_gen); /* or else $RANDOM repeats in child */ |
7248 | reset_traps_to_defaults(); | 7250 | reset_traps_to_defaults(); |
7249 | IF_HUSH_MODE_X(G.x_mode_depth++;) | 7251 | IF_HUSH_MODE_X(G.x_mode_depth++;) |
7252 | //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); | ||
7250 | parse_and_run_string(s); | 7253 | parse_and_run_string(s); |
7251 | _exit(G.last_exitcode); | 7254 | _exit(G.last_exitcode); |
7252 | # else | 7255 | # else |
@@ -8032,17 +8035,16 @@ static void dump_cmd_in_x_mode(char **argv) | |||
8032 | if (G_x_mode && argv) { | 8035 | if (G_x_mode && argv) { |
8033 | /* We want to output the line in one write op */ | 8036 | /* We want to output the line in one write op */ |
8034 | char *buf, *p; | 8037 | char *buf, *p; |
8035 | int len; | 8038 | unsigned len; |
8036 | int n; | 8039 | unsigned n; |
8037 | 8040 | ||
8038 | len = G.x_mode_depth + 3; /* "+[+++...]<cmd...>\n\0" */ | 8041 | len = G.x_mode_depth + 3; /* "+[+++...][ cmd...]\n\0" */ |
8039 | n = 0; | 8042 | n = 0; |
8040 | while (argv[n]) | 8043 | while (argv[n]) |
8041 | len += strlen(argv[n++]) + 1; | 8044 | len += strlen(argv[n++]) + 1; |
8042 | p = buf = xmalloc(len); | 8045 | p = buf = xmalloc(len); |
8043 | n = G.x_mode_depth; | 8046 | n = G.x_mode_depth; |
8044 | while (n-- >= 0) | 8047 | do *p++ = '+'; while ((int)(--n) >= 0); |
8045 | *p++ = '+'; | ||
8046 | n = 0; | 8048 | n = 0; |
8047 | while (argv[n]) | 8049 | while (argv[n]) |
8048 | p += sprintf(p, " %s", argv[n++]); | 8050 | p += sprintf(p, " %s", argv[n++]); |
@@ -8835,21 +8837,23 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
8835 | restore_redirects(squirrel); | 8837 | restore_redirects(squirrel); |
8836 | 8838 | ||
8837 | /* Set shell variables */ | 8839 | /* Set shell variables */ |
8838 | #if ENABLE_HUSH_MODE_X | ||
8839 | if (G_x_mode) { | ||
8840 | int n = G.x_mode_depth; | ||
8841 | while (n-- >= 0) | ||
8842 | bb_putchar_stderr('+'); | ||
8843 | } | ||
8844 | #endif | ||
8845 | i = 0; | 8840 | i = 0; |
8846 | while (i < command->assignment_cnt) { | 8841 | while (i < command->assignment_cnt) { |
8847 | char *p = expand_string_to_string(argv[i], | 8842 | char *p = expand_string_to_string(argv[i], |
8848 | EXP_FLAG_ESC_GLOB_CHARS, | 8843 | EXP_FLAG_ESC_GLOB_CHARS, |
8849 | /*unbackslash:*/ 1 | 8844 | /*unbackslash:*/ 1 |
8850 | ); | 8845 | ); |
8851 | if (G_x_mode) | 8846 | #if ENABLE_HUSH_MODE_X |
8847 | if (G_x_mode) { | ||
8848 | if (i == 0) { | ||
8849 | unsigned n = G.x_mode_depth; | ||
8850 | do | ||
8851 | bb_putchar_stderr('+'); | ||
8852 | while ((int)(--n) >= 0); | ||
8853 | } | ||
8852 | fprintf(stderr, " %s", p); | 8854 | fprintf(stderr, " %s", p); |
8855 | } | ||
8856 | #endif | ||
8853 | debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); | 8857 | debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p); |
8854 | if (set_local_var(p, /*flag:*/ 0)) { | 8858 | if (set_local_var(p, /*flag:*/ 0)) { |
8855 | /* assignment to readonly var / putenv error? */ | 8859 | /* assignment to readonly var / putenv error? */ |
@@ -10246,6 +10250,7 @@ static int FAST_FUNC builtin_eval(char **argv) | |||
10246 | return EXIT_SUCCESS; | 10250 | return EXIT_SUCCESS; |
10247 | 10251 | ||
10248 | IF_HUSH_MODE_X(G.x_mode_depth++;) | 10252 | IF_HUSH_MODE_X(G.x_mode_depth++;) |
10253 | //bb_error_msg("%s: ++x_mode_depth=%d", __func__, G.x_mode_depth); | ||
10249 | if (!argv[1]) { | 10254 | if (!argv[1]) { |
10250 | /* bash: | 10255 | /* bash: |
10251 | * eval "echo Hi; done" ("done" is syntax error): | 10256 | * eval "echo Hi; done" ("done" is syntax error): |
@@ -10276,6 +10281,7 @@ static int FAST_FUNC builtin_eval(char **argv) | |||
10276 | free(str); | 10281 | free(str); |
10277 | } | 10282 | } |
10278 | IF_HUSH_MODE_X(G.x_mode_depth--;) | 10283 | IF_HUSH_MODE_X(G.x_mode_depth--;) |
10284 | //bb_error_msg("%s: --x_mode_depth=%d", __func__, G.x_mode_depth); | ||
10279 | return G.last_exitcode; | 10285 | return G.last_exitcode; |
10280 | } | 10286 | } |
10281 | 10287 | ||