hush: make set -x support optional
No binary (build failed)
—
(log yok)
| @@ -76,7 +76,6 @@ IF_ASH(APPLET(ash, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_AWK(APPLET_NOEXEC(awk, awk, _BB_DIR_USR_BIN, _BB_SUID_DROP, awk)) | |
| IF_BASENAME(APPLET_NOFORK(basename, basename, _BB_DIR_USR_BIN, _BB_SUID_DROP, basename)) | |
| IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, _BB_DIR_BIN, _BB_SUID_DROP, bash)) | |
| - | IF_FEATURE_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, _BB_DIR_BIN, _BB_SUID_DROP, bash)) |
| IF_BBCONFIG(APPLET(bbconfig, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| //IF_BBSH(APPLET(bbsh, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_BEEP(APPLET(beep, _BB_DIR_USR_BIN, _BB_SUID_DROP)) | |
| @@ -183,7 +182,6 @@ IF_HEXDUMP(APPLET_NOEXEC(hexdump, hexdump, _BB_DIR_USR_BIN, _BB_SUID_DROP, hexdu | |
| IF_HOSTID(APPLET_NOFORK(hostid, hostid, _BB_DIR_USR_BIN, _BB_SUID_DROP, hostid)) | |
| IF_HOSTNAME(APPLET(hostname, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_HTTPD(APPLET(httpd, _BB_DIR_USR_SBIN, _BB_SUID_DROP)) | |
| - | IF_HUSH(APPLET(hush, _BB_DIR_BIN, _BB_SUID_DROP)) |
| IF_HWCLOCK(APPLET(hwclock, _BB_DIR_SBIN, _BB_SUID_DROP)) | |
| IF_ID(APPLET(id, _BB_DIR_USR_BIN, _BB_SUID_DROP)) | |
| IF_IFCONFIG(APPLET(ifconfig, _BB_DIR_SBIN, _BB_SUID_DROP)) | |
| @@ -218,7 +216,6 @@ IF_KILL(APPLET(kill, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_KILLALL(APPLET_ODDNAME(killall, kill, _BB_DIR_USR_BIN, _BB_SUID_DROP, killall)) | |
| IF_KILLALL5(APPLET_ODDNAME(killall5, kill, _BB_DIR_USR_BIN, _BB_SUID_DROP, killall5)) | |
| IF_KLOGD(APPLET(klogd, _BB_DIR_SBIN, _BB_SUID_DROP)) | |
| - | IF_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_DROP)) |
| IF_LAST(APPLET(last, _BB_DIR_USR_BIN, _BB_SUID_DROP)) | |
| IF_LENGTH(APPLET_NOFORK(length, length, _BB_DIR_USR_BIN, _BB_SUID_DROP, length)) | |
| IF_LESS(APPLET(less, _BB_DIR_USR_BIN, _BB_SUID_DROP)) | |
| @@ -273,7 +270,6 @@ IF_MODPROBE_SMALL(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_DROP)) | |
| IF_MORE(APPLET(more, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_MOUNT(APPLET(mount, _BB_DIR_BIN, IF_DESKTOP(_BB_SUID_MAYBE) IF_NOT_DESKTOP(_BB_SUID_DROP))) | |
| IF_MOUNTPOINT(APPLET(mountpoint, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| - | IF_MSH(APPLET(msh, _BB_DIR_BIN, _BB_SUID_DROP)) |
| IF_MT(APPLET(mt, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_MV(APPLET(mv, _BB_DIR_BIN, _BB_SUID_DROP)) | |
| IF_NAMEIF(APPLET(nameif, _BB_DIR_SBIN, _BB_SUID_DROP)) | |
| @@ -349,7 +345,6 @@ IF_SETSEBOOL(APPLET(setsebool, _BB_DIR_USR_SBIN, _BB_SUID_DROP)) | |
| IF_SETSID(APPLET(setsid, _BB_DIR_USR_BIN, _BB_SUID_DROP)) | |
| IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, _BB_DIR_USR_BIN, _BB_SUID_DROP, setuidgid)) | |
| IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, _BB_DIR_BIN, _BB_SUID_DROP, sh)) | |
| - | IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, _BB_DIR_BIN, _BB_SUID_DROP, sh)) |
| IF_SHA1SUM(APPLET_ODDNAME(sha1sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_DROP, sha1sum)) | |
| IF_SHA256SUM(APPLET_ODDNAME(sha256sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_DROP, sha256sum)) | |
| IF_SHA512SUM(APPLET_ODDNAME(sha512sum, md5_sha1_sum, _BB_DIR_USR_BIN, _BB_SUID_DROP, sha512sum)) | |
| @@ -119,12 +119,6 @@ INSERT | |
| #define sh_full_usage "" | |
| #define ash_trivial_usage NOUSAGE_STR | |
| #define ash_full_usage "" | |
| - | #define hush_trivial_usage NOUSAGE_STR |
| - | #define hush_full_usage "" |
| - | #define lash_trivial_usage NOUSAGE_STR |
| - | #define lash_full_usage "" |
| - | #define msh_trivial_usage NOUSAGE_STR |
| - | #define msh_full_usage "" |
| #define bash_trivial_usage NOUSAGE_STR | |
| #define bash_full_usage "" | |
| @@ -110,112 +110,6 @@ config ASH_EXPAND_PRMT | |
| This option recreates the prompt string from the environment | |
| variable each time it is displayed. | |
| - | config HUSH |
| - | bool "hush" |
| - | default y |
| - | help |
| - | hush is a small shell (22k). It handles the normal flow control |
| - | constructs such as if/then/elif/else/fi, for/in/do/done, while loops, |
| - | case/esac. Redirections, here documents, $((arithmetic)) |
| - | and functions are supported. |
| - | |
| - | It will compile and work on no-mmu systems. |
| - | |
| - | It does not handle select, aliases, brace expansion, |
| - | tilde expansion, &>file and >&file redirection of stdout+stderr. |
| - | |
| - | config HUSH_BASH_COMPAT |
| - | bool "bash-compatible extensions" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable bash-compatible extensions. |
| - | |
| - | config HUSH_HELP |
| - | bool "help builtin" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable help builtin in hush. Code size + ~1 kbyte. |
| - | |
| - | config HUSH_INTERACTIVE |
| - | bool "Interactive mode" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable interactive mode (prompt and command editing). |
| - | Without this, hush simply reads and executes commands |
| - | from stdin just like a shell script from a file. |
| - | No prompt, no PS1/PS2 magic shell variables. |
| - | |
| - | config HUSH_JOB |
| - | bool "Job control" |
| - | default y |
| - | depends on HUSH_INTERACTIVE |
| - | help |
| - | Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current |
| - | command (not entire shell), fg/bg builtins work. Without this option, |
| - | "cmd &" still works by simply spawning a process and immediately |
| - | prompting for next command (or executing next command in a script), |
| - | but no separate process group is formed. |
| - | |
| - | config HUSH_TICK |
| - | bool "Process substitution" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable process substitution `command` and $(command) in hush. |
| - | |
| - | config HUSH_IF |
| - | bool "Support if/then/elif/else/fi" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable if/then/elif/else/fi in hush. |
| - | |
| - | config HUSH_LOOPS |
| - | bool "Support for, while and until loops" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable for, while and until loops in hush. |
| - | |
| - | config HUSH_CASE |
| - | bool "Support case ... esac statement" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable case ... esac statement in hush. +400 bytes. |
| - | |
| - | config HUSH_FUNCTIONS |
| - | bool "Support funcname() { commands; } syntax" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable support for shell functions in hush. +800 bytes. |
| - | |
| - | config HUSH_LOCAL |
| - | bool "Support local builtin" |
| - | default y |
| - | depends on HUSH_FUNCTIONS |
| - | help |
| - | Enable support for local variables in functions. |
| - | |
| - | config HUSH_EXPORT_N |
| - | bool "Support export '-n' option" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable support for export '-n' option in hush. It is a bash extension. |
| - | |
| - | config HUSH_RANDOM_SUPPORT |
| - | bool "Pseudorandom generator and $RANDOM variable" |
| - | default y |
| - | depends on HUSH |
| - | help |
| - | Enable pseudorandom generator and dynamic variable "$RANDOM". |
| - | Each read of "$RANDOM" will generate a new pseudorandom value. |
| - | |
| choice | |
| prompt "Choose which shell is aliased to 'sh' name" | |
| @@ -9,9 +9,7 @@ lib-y:= | |
| INSERT | |
| lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o | |
| - | lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o |
| lib-$(CONFIG_CTTYHACK) += cttyhack.o | |
| lib-$(CONFIG_SH_MATH_SUPPORT) += math.o | |
| lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o | |
| - | lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o |
| @@ -101,6 +101,136 @@ | |
| # define PIPE_BUF 4096 /* amount of buffering in a pipe */ | |
| #endif | |
| + | //applet:IF_HUSH(APPLET(hush, _BB_DIR_BIN, _BB_SUID_DROP)) |
| + | //applet:IF_MSH(APPLET(msh, _BB_DIR_BIN, _BB_SUID_DROP)) |
| + | //applet:IF_LASH(APPLET(lash, _BB_DIR_BIN, _BB_SUID_DROP)) |
| + | //applet:IF_FEATURE_SH_IS_HUSH(APPLET_ODDNAME(sh, hush, _BB_DIR_BIN, _BB_SUID_DROP, sh)) |
| + | //applet:IF_FEATURE_BASH_IS_HUSH(APPLET_ODDNAME(bash, hush, _BB_DIR_BIN, _BB_SUID_DROP, bash)) |
| + | |
| + | //kbuild:lib-$(CONFIG_HUSH) += hush.o match.o shell_common.o |
| + | //kbuild:lib-$(CONFIG_HUSH_RANDOM_SUPPORT) += random.o |
| + | |
| + | //config:config HUSH |
| + | //config: bool "hush" |
| + | //config: default y |
| + | //config: help |
| + | //config: hush is a small shell (22k). It handles the normal flow control |
| + | //config: constructs such as if/then/elif/else/fi, for/in/do/done, while loops, |
| + | //config: case/esac. Redirections, here documents, $((arithmetic)) |
| + | //config: and functions are supported. |
| + | //config: |
| + | //config: It will compile and work on no-mmu systems. |
| + | //config: |
| + | //config: It does not handle select, aliases, brace expansion, |
| + | //config: tilde expansion, &>file and >&file redirection of stdout+stderr. |
| + | //config: |
| + | //config:config HUSH_BASH_COMPAT |
| + | //config: bool "bash-compatible extensions" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable bash-compatible extensions. |
| + | //config: |
| + | //config:config HUSH_HELP |
| + | //config: bool "help builtin" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable help builtin in hush. Code size + ~1 kbyte. |
| + | //config: |
| + | //config:config HUSH_INTERACTIVE |
| + | //config: bool "Interactive mode" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable interactive mode (prompt and command editing). |
| + | //config: Without this, hush simply reads and executes commands |
| + | //config: from stdin just like a shell script from a file. |
| + | //config: No prompt, no PS1/PS2 magic shell variables. |
| + | //config: |
| + | //config:config HUSH_JOB |
| + | //config: bool "Job control" |
| + | //config: default y |
| + | //config: depends on HUSH_INTERACTIVE |
| + | //config: help |
| + | //config: Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current |
| + | //config: command (not entire shell), fg/bg builtins work. Without this option, |
| + | //config: "cmd &" still works by simply spawning a process and immediately |
| + | //config: prompting for next command (or executing next command in a script), |
| + | //config: but no separate process group is formed. |
| + | //config: |
| + | //config:config HUSH_TICK |
| + | //config: bool "Process substitution" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable process substitution `command` and $(command) in hush. |
| + | //config: |
| + | //config:config HUSH_IF |
| + | //config: bool "Support if/then/elif/else/fi" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable if/then/elif/else/fi in hush. |
| + | //config: |
| + | //config:config HUSH_LOOPS |
| + | //config: bool "Support for, while and until loops" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable for, while and until loops in hush. |
| + | //config: |
| + | //config:config HUSH_CASE |
| + | //config: bool "Support case ... esac statement" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable case ... esac statement in hush. +400 bytes. |
| + | //config: |
| + | //config:config HUSH_FUNCTIONS |
| + | //config: bool "Support funcname() { commands; } syntax" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable support for shell functions in hush. +800 bytes. |
| + | //config: |
| + | //config:config HUSH_LOCAL |
| + | //config: bool "Support local builtin" |
| + | //config: default y |
| + | //config: depends on HUSH_FUNCTIONS |
| + | //config: help |
| + | //config: Enable support for local variables in functions. |
| + | //config: |
| + | //config:config HUSH_RANDOM_SUPPORT |
| + | //config: bool "Pseudorandom generator and $RANDOM variable" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: Enable pseudorandom generator and dynamic variable "$RANDOM". |
| + | //config: Each read of "$RANDOM" will generate a new pseudorandom value. |
| + | //config: |
| + | //config:config HUSH_EXPORT_N |
| + | //config: bool "Support 'export -n' option" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: export -n unexports variables. It is a bash extension. |
| + | //config: |
| + | //config:config HUSH_MODE_X |
| + | //config: bool "Support 'hush -x' option and 'set -x' command" |
| + | //config: default y |
| + | //config: depends on HUSH |
| + | //config: help |
| + | //config: This instructs hush to print commands before execution. Adds ~300 bytes. |
| + | //config: |
| + | |
| + | //usage:#define hush_trivial_usage NOUSAGE_STR |
| + | //usage:#define hush_full_usage "" |
| + | //usage:#define lash_trivial_usage NOUSAGE_STR |
| + | //usage:#define lash_full_usage "" |
| + | //usage:#define msh_trivial_usage NOUSAGE_STR |
| + | //usage:#define msh_full_usage "" |
| + | |
| /* Build knobs */ | |
| #define LEAK_HUNTING 0 | |
| @@ -531,8 +661,13 @@ struct globals { | |
| */ | |
| smallint flag_return_in_progress; | |
| #endif | |
| - | smallint fake_mode; |
| + | smallint n_mode; |
| + | #if ENABLE_HUSH_MODE_X |
| smallint x_mode; | |
| + | # define G_x_mode G.x_mode |
| + | #else |
| + | # define G_x_mode 0 |
| + | #endif |
| smallint exiting; /* used to prevent EXIT trap recursion */ | |
| /* These four support $?, $#, and $1 */ | |
| smalluint last_exitcode; | |
| @@ -3693,9 +3828,10 @@ static void execvp_or_die(char **argv) | |
| _exit(127); /* bash compat */ | |
| } | |
| + | #if ENABLE_HUSH_MODE_X |
| static void dump_cmd_in_x_mode(char **argv) | |
| { | |
| - | if (G.x_mode && argv) { |
| + | if (G_x_mode && argv) { |
| /* We want to output the line in one write op */ | |
| char *buf, *p; | |
| int len; | |
| @@ -3717,6 +3853,9 @@ static void dump_cmd_in_x_mode(char **argv) | |
| free(buf); | |
| } | |
| } | |
| + | #else |
| + | # define dump_cmd_in_x_mode(argv) ((void)0) |
| + | #endif |
| #if BB_MMU | |
| #define pseudo_exec_argv(nommu_save, argv, assignment_cnt, argv_expanded) \ | |
| @@ -4267,18 +4406,18 @@ static NOINLINE int run_pipe(struct pipe *pi) | |
| rcode = setup_redirects(command, squirrel); | |
| restore_redirects(squirrel); | |
| /* Set shell variables */ | |
| - | if (G.x_mode) |
| + | if (G_x_mode) |
| bb_putchar_stderr('+'); | |
| while (*argv) { | |
| p = expand_string_to_string(*argv); | |
| - | if (G.x_mode) |
| + | 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) |
| + | if (G_x_mode) |
| bb_putchar_stderr('\n'); | |
| /* Redirect error sets $? to 1. Otherwise, | |
| * if evaluating assignment value set $?, retain it. | |
| @@ -4943,7 +5082,7 @@ static int run_and_free_list(struct pipe *pi) | |
| { | |
| int rcode = 0; | |
| debug_printf_exec("run_and_free_list entered\n"); | |
| - | if (!G.fake_mode) { |
| + | if (!G.n_mode) { |
| debug_printf_exec(": run_list: 1st pipe with %d cmds\n", pi->num_cmds); | |
| rcode = run_list(pi); | |
| } | |
| @@ -6969,8 +7108,8 @@ 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.x_mode = state; break; |
| + | case 'n': G.n_mode = state; break; |
| + | case 'x': IF_HUSH_MODE_X(G_x_mode = state;) break; |
| default: return EXIT_FAILURE; | |
| } | |
| return EXIT_SUCCESS; | |