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 /shell | |
| 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>
Diffstat (limited to 'shell')
| -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 | ||
