aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2009-03-28 13:44:51 +0000
committerMike Frysinger <vapier@gentoo.org>2009-03-28 13:44:51 +0000
commitad88d5a4cfe200191bce4db41b447969719cb8ac (patch)
tree30c97089e248db47d2d8ad95d23efe07a44b3add
parent19a7ea126a6f05232ee7d4b786bafab8e28a8beb (diff)
downloadbusybox-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.c57
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);
516static int builtin_test(char **argv); 516static int builtin_test(char **argv);
517static int builtin_true(char **argv); 517static int builtin_true(char **argv);
518static int builtin_set(char **argv); 518static int builtin_set(char **argv);
519static int builtin_set_mode(const char, const char);
519static int builtin_shift(char **argv); 520static int builtin_shift(char **argv);
520static int builtin_source(char **argv); 521static int builtin_source(char **argv);
521static int builtin_umask(char **argv); 522static 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 */
4639static 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}
4637static int builtin_set(char **argv) 4649static 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
4686static int builtin_shift(char **argv) 4713static int builtin_shift(char **argv)