svn commit: [25856] trunk/busybox/shell

vapier at busybox.net vapier at busybox.net
Sat Mar 28 13:44:52 UTC 2009


Author: vapier
Date: 2009-03-28 13:44:51 +0000 (Sat, 28 Mar 2009)
New Revision: 25856

Log:
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

Modified:
   trunk/busybox/shell/hush.c


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2009-03-28 13:10:17 UTC (rev 25855)
+++ trunk/busybox/shell/hush.c	2009-03-28 13:44:51 UTC (rev 25856)
@@ -516,6 +516,7 @@
 static int builtin_test(char **argv);
 static int builtin_true(char **argv);
 static int builtin_set(char **argv);
+static int builtin_set_mode(const char, const char);
 static int builtin_shift(char **argv);
 static int builtin_source(char **argv);
 static int builtin_umask(char **argv);
@@ -4256,13 +4257,14 @@
 			 * we have to have some stuff (ctty, etc) */
 			/* G.interactive_fd++; */
 			break;
-		case 'n':
-			G.fake_mode = 1;
-			break;
 		case 's':
 			/* "-s" means "read from stdin", but this is how we always
 			 * operate, so simply do nothing here. */
 			break;
+		case 'n':
+		case 'x':
+			if (!builtin_set_mode('-', opt))
+				break;
 		default:
 #ifndef BB_VER
 			fprintf(stderr, "Usage: sh [FILE]...\n"
@@ -4613,10 +4615,11 @@
 	return set_local_var(string, 0);
 }
 
-/* built-in 'set' handler
+/* http://www.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#set
+ * built-in 'set' handler
  * SUSv3 says:
- * set [-abCefmnuvx] [-h] [-o option] [argument...]
- * set [+abCefmnuvx] [+h] [+o option] [argument...]
+ * set [-abCefhmnuvx] [-o option] [argument...]
+ * set [+abCefhmnuvx] [+o option] [argument...]
  * set -- [argument...]
  * set -o
  * set +o
@@ -4631,9 +4634,18 @@
  * Set the positional parameters to the expansion of x, even if x expands
  * with a leading '-' or '+': set -- $x
  *
- * So far, we only support "set -- [argument...]" by ignoring all options
- * (also, "-o option" will be mishandled by taking "option" as parameter #1).
+ * So far, we only support "set -- [argument...]" and some of the short names.
  */
+static int builtin_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.debug_mode = state;*/ break;
+		default:  return EXIT_FAILURE;
+	}
+	return EXIT_SUCCESS;
+}
 static int builtin_set(char **argv)
 {
 	int n;
@@ -4647,18 +4659,28 @@
 		return EXIT_SUCCESS;
 	}
 
-	do  {
-		if (arg[0] == '+')
+	do {
+		if (!strcmp(arg, "--")) {
+			++argv;
+			goto set_argv;
+		}
+
+		if (arg[0] == '+' || arg[0] == '-') {
+			for (n = 1; arg[n]; ++n)
+				if (builtin_set_mode(arg[0], arg[n]))
+					goto error;
 			continue;
-		if (arg[0] != '-')
-			break;
-		if (arg[1] == '-' && arg[2] == '\0') {
-			argv++;
-			break;
 		}
+
+		break;
 	} while ((arg = *++argv) != NULL);
 	/* Now argv[0] is 1st argument */
 
+	/* Only reset global_argv if we didn't process anything */
+	if (arg == NULL)
+		return EXIT_SUCCESS;
+ set_argv:
+
 	/* NB: G.global_argv[0] ($0) is never freed/changed */
 	g_argv = G.global_argv;
 	if (G.global_args_malloced) {
@@ -4681,6 +4703,11 @@
 	G.global_argc = n;
 
 	return EXIT_SUCCESS;
+
+	/* Nothing known, so abort */
+ error:
+	bb_error_msg("set: %s: invalid option", arg);
+	return EXIT_FAILURE;
 }
 
 static int builtin_shift(char **argv)



More information about the busybox-cvs mailing list