diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-16 12:35:35 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-16 12:35:35 +0200 |
commit | 3f5fae07725b0cc24587c7965f17ac57e5610bfb (patch) | |
tree | e7104de3ac24c5cc2a87970294a1fc7d72aa3fe5 | |
parent | b3389de04b1fe398e5f88446dd23a7826139da7d (diff) | |
download | busybox-w32-3f5fae07725b0cc24587c7965f17ac57e5610bfb.tar.gz busybox-w32-3f5fae07725b0cc24587c7965f17ac57e5610bfb.tar.bz2 busybox-w32-3f5fae07725b0cc24587c7965f17ac57e5610bfb.zip |
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>
-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 14f8f2422..7640bd6ba 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -532,6 +532,7 @@ struct globals { | |||
532 | smallint flag_return_in_progress; | 532 | smallint flag_return_in_progress; |
533 | #endif | 533 | #endif |
534 | smallint fake_mode; | 534 | smallint fake_mode; |
535 | smallint x_mode; | ||
535 | smallint exiting; /* used to prevent EXIT trap recursion */ | 536 | smallint exiting; /* used to prevent EXIT trap recursion */ |
536 | /* These four support $?, $#, and $1 */ | 537 | /* These four support $?, $#, and $1 */ |
537 | smalluint last_exitcode; | 538 | smalluint last_exitcode; |
@@ -3692,6 +3693,31 @@ static void execvp_or_die(char **argv) | |||
3692 | _exit(127); /* bash compat */ | 3693 | _exit(127); /* bash compat */ |
3693 | } | 3694 | } |
3694 | 3695 | ||
3696 | static void dump_cmd_in_x_mode(char **argv) | ||
3697 | { | ||
3698 | if (G.x_mode && argv) { | ||
3699 | /* We want to output the line in one write op */ | ||
3700 | char *buf, *p; | ||
3701 | int len; | ||
3702 | int n; | ||
3703 | |||
3704 | len = 3; | ||
3705 | n = 0; | ||
3706 | while (argv[n]) | ||
3707 | len += strlen(argv[n++]) + 1; | ||
3708 | buf = xmalloc(len); | ||
3709 | buf[0] = '+'; | ||
3710 | p = buf + 1; | ||
3711 | n = 0; | ||
3712 | while (argv[n]) | ||
3713 | p += sprintf(p, " %s", argv[n++]); | ||
3714 | *p++ = '\n'; | ||
3715 | *p = '\0'; | ||
3716 | fputs(buf, stderr); | ||
3717 | free(buf); | ||
3718 | } | ||
3719 | } | ||
3720 | |||
3695 | #if BB_MMU | 3721 | #if BB_MMU |
3696 | #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ | 3722 | #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ |
3697 | pseudo_exec_argv(argv, assignment_cnt, argv_expanded) | 3723 | pseudo_exec_argv(argv, assignment_cnt, argv_expanded) |
@@ -3714,6 +3740,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
3714 | char **new_env; | 3740 | char **new_env; |
3715 | 3741 | ||
3716 | new_env = expand_assignments(argv, assignment_cnt); | 3742 | new_env = expand_assignments(argv, assignment_cnt); |
3743 | dump_cmd_in_x_mode(new_env); | ||
3717 | 3744 | ||
3718 | if (!argv[assignment_cnt]) { | 3745 | if (!argv[assignment_cnt]) { |
3719 | /* Case when we are here: ... | var=val | ... | 3746 | /* Case when we are here: ... | var=val | ... |
@@ -3742,6 +3769,7 @@ static NOINLINE void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
3742 | nommu_save->argv = argv; | 3769 | nommu_save->argv = argv; |
3743 | #endif | 3770 | #endif |
3744 | } | 3771 | } |
3772 | dump_cmd_in_x_mode(argv); | ||
3745 | 3773 | ||
3746 | #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU | 3774 | #if ENABLE_FEATURE_SH_STANDALONE || BB_MMU |
3747 | if (strchr(argv[0], '/') != NULL) | 3775 | if (strchr(argv[0], '/') != NULL) |
@@ -4239,13 +4267,19 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
4239 | rcode = setup_redirects(command, squirrel); | 4267 | rcode = setup_redirects(command, squirrel); |
4240 | restore_redirects(squirrel); | 4268 | restore_redirects(squirrel); |
4241 | /* Set shell variables */ | 4269 | /* Set shell variables */ |
4270 | if (G.x_mode) | ||
4271 | bb_putchar_stderr('+'); | ||
4242 | while (*argv) { | 4272 | while (*argv) { |
4243 | p = expand_string_to_string(*argv); | 4273 | p = expand_string_to_string(*argv); |
4274 | if (G.x_mode) | ||
4275 | fprintf(stderr, " %s", p); | ||
4244 | debug_printf_exec("set shell var:'%s'->'%s'\n", | 4276 | debug_printf_exec("set shell var:'%s'->'%s'\n", |
4245 | *argv, p); | 4277 | *argv, p); |
4246 | set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); | 4278 | set_local_var(p, /*exp:*/ 0, /*lvl:*/ 0, /*ro:*/ 0); |
4247 | argv++; | 4279 | argv++; |
4248 | } | 4280 | } |
4281 | if (G.x_mode) | ||
4282 | bb_putchar_stderr('\n'); | ||
4249 | /* Redirect error sets $? to 1. Otherwise, | 4283 | /* Redirect error sets $? to 1. Otherwise, |
4250 | * if evaluating assignment value set $?, retain it. | 4284 | * if evaluating assignment value set $?, retain it. |
4251 | * Try "false; q=`exit 2`; echo $?" - should print 2: */ | 4285 | * Try "false; q=`exit 2`; echo $?" - should print 2: */ |
@@ -4305,6 +4339,8 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
4305 | rcode = setup_redirects(command, squirrel); | 4339 | rcode = setup_redirects(command, squirrel); |
4306 | if (rcode == 0) { | 4340 | if (rcode == 0) { |
4307 | new_env = expand_assignments(argv, command->assignment_cnt); | 4341 | new_env = expand_assignments(argv, command->assignment_cnt); |
4342 | dump_cmd_in_x_mode(new_env); | ||
4343 | dump_cmd_in_x_mode(argv_expanded); | ||
4308 | old_vars = set_vars_and_save_old(new_env); | 4344 | old_vars = set_vars_and_save_old(new_env); |
4309 | if (!funcp) { | 4345 | if (!funcp) { |
4310 | debug_printf_exec(": builtin '%s' '%s'...\n", | 4346 | debug_printf_exec(": builtin '%s' '%s'...\n", |
@@ -4346,6 +4382,8 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
4346 | rcode = setup_redirects(command, squirrel); | 4382 | rcode = setup_redirects(command, squirrel); |
4347 | if (rcode == 0) { | 4383 | if (rcode == 0) { |
4348 | new_env = expand_assignments(argv, command->assignment_cnt); | 4384 | new_env = expand_assignments(argv, command->assignment_cnt); |
4385 | dump_cmd_in_x_mode(new_env); | ||
4386 | dump_cmd_in_x_mode(argv_expanded); | ||
4349 | old_vars = set_vars_and_save_old(new_env); | 4387 | old_vars = set_vars_and_save_old(new_env); |
4350 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", | 4388 | debug_printf_exec(": run_nofork_applet '%s' '%s'...\n", |
4351 | argv_expanded[0], argv_expanded[1]); | 4389 | argv_expanded[0], argv_expanded[1]); |
@@ -6932,7 +6970,7 @@ static int set_mode(const char cstate, const char mode) | |||
6932 | int state = (cstate == '-' ? 1 : 0); | 6970 | int state = (cstate == '-' ? 1 : 0); |
6933 | switch (mode) { | 6971 | switch (mode) { |
6934 | case 'n': G.fake_mode = state; break; | 6972 | case 'n': G.fake_mode = state; break; |
6935 | case 'x': /*G.debug_mode = state;*/ break; | 6973 | case 'x': G.x_mode = state; break; |
6936 | default: return EXIT_FAILURE; | 6974 | default: return EXIT_FAILURE; |
6937 | } | 6975 | } |
6938 | return EXIT_SUCCESS; | 6976 | return EXIT_SUCCESS; |