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>
This commit is contained in:
Denys Vlasenko 2010-07-16 12:35:35 +02:00
parent b3389de04b
commit 3f5fae0772

View File

@ -532,6 +532,7 @@ struct globals {
smallint flag_return_in_progress; smallint flag_return_in_progress;
#endif #endif
smallint fake_mode; smallint fake_mode;
smallint x_mode;
smallint exiting; /* used to prevent EXIT trap recursion */ smallint exiting; /* used to prevent EXIT trap recursion */
/* These four support $?, $#, and $1 */ /* These four support $?, $#, and $1 */
smalluint last_exitcode; smalluint last_exitcode;
@ -3692,6 +3693,31 @@ static void execvp_or_die(char **argv)
_exit(127); /* bash compat */ _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 #if BB_MMU
#define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \
pseudo_exec_argv(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; char **new_env;
new_env = expand_assignments(argv, assignment_cnt); new_env = expand_assignments(argv, assignment_cnt);
dump_cmd_in_x_mode(new_env);
if (!argv[assignment_cnt]) { if (!argv[assignment_cnt]) {
/* Case when we are here: ... | var=val | ... /* 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; nommu_save->argv = argv;
#endif #endif
} }
dump_cmd_in_x_mode(argv);
#if ENABLE_FEATURE_SH_STANDALONE || BB_MMU #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU
if (strchr(argv[0], '/') != NULL) if (strchr(argv[0], '/') != NULL)
@ -4239,13 +4267,19 @@ static NOINLINE int run_pipe(struct pipe *pi)
rcode = setup_redirects(command, squirrel); rcode = setup_redirects(command, squirrel);
restore_redirects(squirrel); restore_redirects(squirrel);
/* Set shell variables */ /* Set shell variables */
if (G.x_mode)
bb_putchar_stderr('+');
while (*argv) { while (*argv) {
p = expand_string_to_string(*argv); p = expand_string_to_string(*argv);
if (G.x_mode)
fprintf(stderr, " %s", p);
debug_printf_exec("set shell var:'%s'->'%s'\n", debug_printf_exec("set shell var:'%s'->'%s'\n",
*argv, p); *argv, p);
set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0);
argv++; argv++;
} }
if (G.x_mode)
bb_putchar_stderr('\n');
/* Redirect error sets $? to 1. Otherwise, /* Redirect error sets $? to 1. Otherwise,
* if evaluating assignment value set $?, retain it. * if evaluating assignment value set $?, retain it.
* Try "false; q=`exit 2`; echo $?" - should print 2: */ * 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); rcode = setup_redirects(command, squirrel);
if (rcode == 0) { if (rcode == 0) {
new_env = expand_assignments(argv, command->assignment_cnt); 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); old_vars = set_vars_and_save_old(new_env);
if (!funcp) { if (!funcp) {
debug_printf_exec(": builtin '%s' '%s'...\n", debug_printf_exec(": builtin '%s' '%s'...\n",
@ -4346,6 +4382,8 @@ static NOINLINE int run_pipe(struct pipe *pi)
rcode = setup_redirects(command, squirrel); rcode = setup_redirects(command, squirrel);
if (rcode == 0) { if (rcode == 0) {
new_env = expand_assignments(argv, command->assignment_cnt); 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); old_vars = set_vars_and_save_old(new_env);
debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", debug_printf_exec(": run_nofork_applet '%s' '%s'...\n",
argv_expanded[0], argv_expanded[1]); 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); int state = (cstate == '-' ? 1 : 0);
switch (mode) { switch (mode) {
case 'n': G.fake_mode = state; break; 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; default: return EXIT_FAILURE;
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;