aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/hush.c78
1 files changed, 60 insertions, 18 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e9212cefc..ac8467fb4 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -8030,28 +8030,67 @@ static void execvp_or_die(char **argv)
}
#if ENABLE_HUSH_MODE_X
+static void print_optionally_squoted(FILE *fp, const char *str)
+{
+ unsigned len;
+ const char *cp;
+
+ cp = str;
+ if (str[0] != '{' && str[0] != '(') for (;;) {
+ if (!*cp) {
+ /* string has no special chars */
+ fputs(str, fp);
+ return;
+ }
+ if (*cp == '\\') break;
+ if (*cp == '\'') break;
+ if (*cp == '"') break;
+ if (*cp == '$') break;
+ if (*cp == '!') break;
+ if (*cp == '*') break;
+ if (*cp == '[') break;
+ if (*cp == ']') break;
+#if ENABLE_HUSH_TICK
+ if (*cp == '`') break;
+#endif
+ if (isspace(*cp)) break;
+ cp++;
+ }
+
+ cp = str;
+ for (;;) {
+ /* print '....' up to EOL or first squote */
+ len = (int)(strchrnul(cp, '\'') - cp);
+ if (len != 0) {
+ fprintf(fp, "'%.*s'", len, cp);
+ cp += len;
+ }
+ if (*cp == '\0')
+ break;
+ /* string contains squote(s), print them as \' */
+ fprintf(fp, "\\'");
+ cp++;
+ }
+}
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;
- unsigned len;
unsigned n;
- len = G.x_mode_depth + 3; /* "+[+++...][ cmd...]\n\0" */
- n = 0;
- while (argv[n])
- len += strlen(argv[n++]) + 1;
- p = buf = xmalloc(len);
+ /* "+[+++...][ cmd...]\n\0" */
n = G.x_mode_depth;
- do *p++ = '+'; while ((int)(--n) >= 0);
+ do bb_putchar_stderr('+'); while ((int)(--n) >= 0);
n = 0;
- while (argv[n])
- p += sprintf(p, " %s", argv[n++]);
- *p++ = '\n';
- *p = '\0';
- fputs(buf, stderr);
- free(buf);
+ while (argv[n]) {
+ if (argv[n][0] == '\0')
+ fputs(" ''", stderr);
+ else {
+ bb_putchar_stderr(' ');
+ print_optionally_squoted(stderr, argv[n]);
+ }
+ n++;
+ }
+ bb_putchar_stderr('\n');
}
}
#else
@@ -8845,13 +8884,18 @@ static NOINLINE int run_pipe(struct pipe *pi)
);
#if ENABLE_HUSH_MODE_X
if (G_x_mode) {
+ char *eq;
if (i == 0) {
unsigned n = G.x_mode_depth;
do
bb_putchar_stderr('+');
while ((int)(--n) >= 0);
}
- fprintf(stderr, " %s", p);
+ eq = strchrnul(p, '=');
+ fprintf(stderr, " %.*s=", (int)(eq - p), p);
+ if (*eq)
+ print_optionally_squoted(stderr, eq + 1);
+ bb_putchar_stderr('\n');
}
#endif
debug_printf_env("set shell var:'%s'->'%s'\n", *argv, p);
@@ -8861,8 +8905,6 @@ static NOINLINE int run_pipe(struct pipe *pi)
}
i++;
}
- if (G_x_mode)
- bb_putchar_stderr('\n');
/* Redirect error sets $? to 1. Otherwise,
* if evaluating assignment value set $?, retain it.
* Else, clear $?: