diff options
author | Mike Frysinger <vapier@gentoo.org> | 2009-03-28 13:44:51 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2009-03-28 13:44:51 +0000 |
commit | ad88d5a4cfe200191bce4db41b447969719cb8ac (patch) | |
tree | 30c97089e248db47d2d8ad95d23efe07a44b3add | |
parent | 19a7ea126a6f05232ee7d4b786bafab8e28a8beb (diff) | |
download | busybox-w32-ad88d5a4cfe200191bce4db41b447969719cb8ac.tar.gz busybox-w32-ad88d5a4cfe200191bce4db41b447969719cb8ac.tar.bz2 busybox-w32-ad88d5a4cfe200191bce4db41b447969719cb8ac.zip |
unify `set` handling with command line processing, fixup `set` argv processing so it doesnt clobber argv when setting options, and barf on unhandled set options
-rw-r--r-- | shell/hush.c | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/shell/hush.c b/shell/hush.c index 2dd59bbb4..3565cbca3 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -516,6 +516,7 @@ static int builtin_read(char **argv); | |||
516 | static int builtin_test(char **argv); | 516 | static int builtin_test(char **argv); |
517 | static int builtin_true(char **argv); | 517 | static int builtin_true(char **argv); |
518 | static int builtin_set(char **argv); | 518 | static int builtin_set(char **argv); |
519 | static int builtin_set_mode(const char, const char); | ||
519 | static int builtin_shift(char **argv); | 520 | static int builtin_shift(char **argv); |
520 | static int builtin_source(char **argv); | 521 | static int builtin_source(char **argv); |
521 | static int builtin_umask(char **argv); | 522 | static int builtin_umask(char **argv); |
@@ -4256,13 +4257,14 @@ int hush_main(int argc, char **argv) | |||
4256 | * we have to have some stuff (ctty, etc) */ | 4257 | * we have to have some stuff (ctty, etc) */ |
4257 | /* G.interactive_fd++; */ | 4258 | /* G.interactive_fd++; */ |
4258 | break; | 4259 | break; |
4259 | case 'n': | ||
4260 | G.fake_mode = 1; | ||
4261 | break; | ||
4262 | case 's': | 4260 | case 's': |
4263 | /* "-s" means "read from stdin", but this is how we always | 4261 | /* "-s" means "read from stdin", but this is how we always |
4264 | * operate, so simply do nothing here. */ | 4262 | * operate, so simply do nothing here. */ |
4265 | break; | 4263 | break; |
4264 | case 'n': | ||
4265 | case 'x': | ||
4266 | if (!builtin_set_mode('-', opt)) | ||
4267 | break; | ||
4266 | default: | 4268 | default: |
4267 | #ifndef BB_VER | 4269 | #ifndef BB_VER |
4268 | fprintf(stderr, "Usage: sh [FILE]...\n" | 4270 | fprintf(stderr, "Usage: sh [FILE]...\n" |
@@ -4613,10 +4615,11 @@ static int builtin_read(char **argv) | |||
4613 | return set_local_var(string, 0); | 4615 | return set_local_var(string, 0); |
4614 | } | 4616 | } |
4615 | 4617 | ||
4616 | /* built-in 'set' handler | 4618 | /* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set |
4619 | * built-in 'set' handler | ||
4617 | * SUSv3 says: | 4620 | * SUSv3 says: |
4618 | * set [-abCefmnuvx] [-h] [-o option] [argument...] | 4621 | * set [-abCefhmnuvx] [-o option] [argument...] |
4619 | * set [+abCefmnuvx] [+h] [+o option] [argument...] | 4622 | * set [+abCefhmnuvx] [+o option] [argument...] |
4620 | * set -- [argument...] | 4623 | * set -- [argument...] |
4621 | * set -o | 4624 | * set -o |
4622 | * set +o | 4625 | * set +o |
@@ -4631,9 +4634,18 @@ static int builtin_read(char **argv) | |||
4631 | * Set the positional parameters to the expansion of x, even if x expands | 4634 | * Set the positional parameters to the expansion of x, even if x expands |
4632 | * with a leading '-' or '+': set -- $x | 4635 | * with a leading '-' or '+': set -- $x |
4633 | * | 4636 | * |
4634 | * So far, we only support "set -- [argument...]" by ignoring all options | 4637 | * So far, we only support "set -- [argument...]" and some of the short names. |
4635 | * (also, "-o option" will be mishandled by taking "option" as parameter #1). | ||
4636 | */ | 4638 | */ |
4639 | static int builtin_set_mode(const char cstate, const char mode) | ||
4640 | { | ||
4641 | int state = (cstate == '-' ? 1 : 0); | ||
4642 | switch (mode) { | ||
4643 | case 'n': G.fake_mode = state; break; | ||
4644 | case 'x': /*G.debug_mode = state;*/ break; | ||
4645 | default: return EXIT_FAILURE; | ||
4646 | } | ||
4647 | return EXIT_SUCCESS; | ||
4648 | } | ||
4637 | static int builtin_set(char **argv) | 4649 | static int builtin_set(char **argv) |
4638 | { | 4650 | { |
4639 | int n; | 4651 | int n; |
@@ -4647,18 +4659,28 @@ static int builtin_set(char **argv) | |||
4647 | return EXIT_SUCCESS; | 4659 | return EXIT_SUCCESS; |
4648 | } | 4660 | } |
4649 | 4661 | ||
4650 | do { | 4662 | do { |
4651 | if (arg[0] == '+') | 4663 | if (!strcmp(arg, "--")) { |
4664 | ++argv; | ||
4665 | goto set_argv; | ||
4666 | } | ||
4667 | |||
4668 | if (arg[0] == '+' || arg[0] == '-') { | ||
4669 | for (n = 1; arg[n]; ++n) | ||
4670 | if (builtin_set_mode(arg[0], arg[n])) | ||
4671 | goto error; | ||
4652 | continue; | 4672 | continue; |
4653 | if (arg[0] != '-') | ||
4654 | break; | ||
4655 | if (arg[1] == '-' && arg[2] == '\0') { | ||
4656 | argv++; | ||
4657 | break; | ||
4658 | } | 4673 | } |
4674 | |||
4675 | break; | ||
4659 | } while ((arg = *++argv) != NULL); | 4676 | } while ((arg = *++argv) != NULL); |
4660 | /* Now argv[0] is 1st argument */ | 4677 | /* Now argv[0] is 1st argument */ |
4661 | 4678 | ||
4679 | /* Only reset global_argv if we didn't process anything */ | ||
4680 | if (arg == NULL) | ||
4681 | return EXIT_SUCCESS; | ||
4682 | set_argv: | ||
4683 | |||
4662 | /* NB: G.global_argv[0] ($0) is never freed/changed */ | 4684 | /* NB: G.global_argv[0] ($0) is never freed/changed */ |
4663 | g_argv = G.global_argv; | 4685 | g_argv = G.global_argv; |
4664 | if (G.global_args_malloced) { | 4686 | if (G.global_args_malloced) { |
@@ -4681,6 +4703,11 @@ static int builtin_set(char **argv) | |||
4681 | G.global_argc = n; | 4703 | G.global_argc = n; |
4682 | 4704 | ||
4683 | return EXIT_SUCCESS; | 4705 | return EXIT_SUCCESS; |
4706 | |||
4707 | /* Nothing known, so abort */ | ||
4708 | error: | ||
4709 | bb_error_msg("set: %s: invalid option", arg); | ||
4710 | return EXIT_FAILURE; | ||
4684 | } | 4711 | } |
4685 | 4712 | ||
4686 | static int builtin_shift(char **argv) | 4713 | static int builtin_shift(char **argv) |