diff options
author | Denys Vlasenko | 2010-07-16 12:35:35 +0200 |
---|---|---|
committer | Denys Vlasenko | 2010-07-16 12:35:35 +0200 |
commit | 3f5fae07725b0cc24587c7965f17ac57e5610bfb (patch) | |
tree | e7104de3ac24c5cc2a87970294a1fc7d72aa3fe5 /shell | |
parent | b3389de04b1fe398e5f88446dd23a7826139da7d (diff) | |
download | busybox-3f5fae07725b0cc24587c7965f17ac57e5610bfb.zip busybox-3f5fae07725b0cc24587c7965f17ac57e5610bfb.tar.gz |
hush: add support for set -x
function old new delta
run_pipe 1442 1568 +126
dump_cmd_in_x_mode - 126 +126
builtin_trap 441 462 +21
pseudo_exec_argv 171 187 +16
reset_traps_to_defaults 214 229 +15
check_and_run_traps 227 232 +5
hush_exit 98 101 +3
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 6/0 up/down: 312/0) Total: 312 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/shell/hush.c b/shell/hush.c index 14f8f24..7640bd6 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -532,6 +532,7 @@ struct globals { smallint flag_return_in_progress; #endif smallint fake_mode; + smallint x_mode; smallint exiting; /* used to prevent EXIT trap recursion */ /* These four support $?, $#, and $1 */ smalluint last_exitcode; @@ -3692,6 +3693,31 @@ static void execvp_or_die(char **argv) _exit(127); /* bash compat */ } +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; + + len = 3; + n = 0; + while (argv[n]) + len += strlen(argv[n++]) + 1; + buf = xmalloc(len); + buf[0] = '+'; + p = buf + 1; + n = 0; + while (argv[n]) + p += sprintf(p, " %s", argv[n++]); + *p++ = '\n'; + *p = '\0'; + fputs(buf, stderr); + free(buf); + } +} + #if BB_MMU #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ pseudo_exec_argv(argv, assignment_cnt, argv_expanded) @@ -3714,6 +3740,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, char **new_env; new_env = expand_assignments(argv, assignment_cnt); + dump_cmd_in_x_mode(new_env); if (!argv[assignment_cnt]) { /* Case when we are here: ... | var=val | ... @@ -3742,6 +3769,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, nommu_save->argv = argv; #endif } + dump_cmd_in_x_mode(argv); #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU if (strchr(argv[0], '/') != NULL) @@ -4239,13 +4267,19 @@ static NOINLINE int run_pipe(struct pipe *pi) rcode = setup_redirects(command, squirrel); restore_redirects(squirrel); /* Set shell variables */ + if (G.x_mode) + bb_putchar_stderr('+'); while (*argv) { p = expand_string_to_string(*argv); + if (G.x_mode) + fprintf(stderr, " %s", p); debug_printf_exec("set shell var:'%s'->'%s'\n", *argv, p); set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); argv++; } + if (G.x_mode) + bb_putchar_stderr('\n'); /* Redirect error sets $? to 1. Otherwise, * if evaluating assignment value set $?, retain it. * Try "false; q=`exit 2`; echo $?" - should print 2: */ @@ -4305,6 +4339,8 @@ static NOINLINE int run_pipe(struct pipe *pi) rcode = setup_redirects(command, squirrel); if (rcode == 0) { new_env = expand_assignments(argv, command->assignment_cnt); + dump_cmd_in_x_mode(new_env); + dump_cmd_in_x_mode(argv_expanded); old_vars = set_vars_and_save_old(new_env); if (!funcp) { debug_printf_exec(": builtin '%s' '%s'...\n", @@ -4346,6 +4382,8 @@ static NOINLINE int run_pipe(struct pipe *pi) rcode = setup_redirects(command, squirrel); if (rcode == 0) { new_env = expand_assignments(argv, command->assignment_cnt); + dump_cmd_in_x_mode(new_env); + dump_cmd_in_x_mode(argv_expanded); old_vars = set_vars_and_save_old(new_env); debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", argv_expanded[0], argv_expanded[1]); @@ -6932,7 +6970,7 @@ static int set_mode(const char cstate, const char mode) int state = (cstate == '-' ? 1 : 0); switch (mode) { case 'n': G.fake_mode = state; break; - case 'x': /*G.debug_mode = state;*/ break; + case 'x': G.x_mode = state; break; default: return EXIT_FAILURE; } return EXIT_SUCCESS; |