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:
parent
b3389de04b
commit
3f5fae0772
40
shell/hush.c
40
shell/hush.c
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user