aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-07-27 14:12:05 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-07-27 14:12:05 +0200
commit9dda9270df3108bb85b29c6d382a3477aeb3344b (patch)
tree63d8b8bba2d2f42a6c152eb5aa2b6aef5f774dc6
parent186cf4976768029113cf8438734a65bf2c489c5c (diff)
downloadbusybox-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.c34
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