[BusyBox] another hush fix

Larry Doolittle ldoolitt at recycle.lbl.gov
Wed Jun 6 17:51:46 UTC 2001


Fixes the interaction between if/then/else/fi syntax and variables.
I planned to do it right from the beginning, but my implementation
was buggy.  Also adds the relevant test cases.  Also adds some old
Matt Kraai variable test cases that got left out somehow.

Is it time to close bugs #1038 and #1039 with the message "use hush
instead"?

     - Larry

diff -urN --exclude=sh.c --exclude=Entries /home/ldoolitt/cvs/busybox/hush.c busybox-trial/hush.c
--- /home/ldoolitt/cvs/busybox/hush.c	Wed Jun  6 11:05:53 2001
+++ busybox-trial/hush.c	Wed Jun  6 16:44:59 2001
@@ -1326,19 +1326,18 @@
 	 * Builtins within pipes have to fork anyway, and are handled in
 	 * pseudo_exec.  "echo foo | read bar" doesn't work on bash, either.
 	 */
-	if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
-		child = & (pi->progs[0]);
-		if (child->group && ! child->subshell) {
-			int squirrel[] = {-1, -1, -1};
-			int rcode;
-			debug_printf("non-subshell grouping\n");
-			setup_redirects(child, squirrel);
-			/* XXX could we merge code with following builtin case,
-			 * by creating a pseudo builtin that calls run_list_real? */
-			rcode = run_list_real(child->group);
-			restore_redirects(squirrel);
-			return rcode;
-		}
+	if (pi->num_progs == 1) child = & (pi->progs[0]);
+	if (pi->num_progs == 1 && child->group && child->subshell == 0) {
+		int squirrel[] = {-1, -1, -1};
+		int rcode;
+		debug_printf("non-subshell grouping\n");
+		setup_redirects(child, squirrel);
+		/* XXX could we merge code with following builtin case,
+		 * by creating a pseudo builtin that calls run_list_real? */
+		rcode = run_list_real(child->group);
+		restore_redirects(squirrel);
+		return rcode;
+	} else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) {
 		for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ }
 		if (i!=0 && child->argv[i]==NULL) {
 			/* assignments, but no command: set the local environment */
@@ -1352,7 +1351,8 @@
 				 * variable. */
 				int export_me=0;
 				char *name, *value;
-				name = strdup(child->argv[i]);
+				name = xstrdup(child->argv[i]);
+				debug_printf("Local environment set: %s\n", name);
 				value = strchr(name, '=');
 				if (value)
 					*value=0;
@@ -1478,6 +1478,7 @@
 		if (rmode == RES_ELIF && !if_code) continue;
 		if (pi->num_progs == 0) continue;
 		rcode = run_pipe_real(pi);
+		debug_printf("run_pipe_real returned %d\n",rcode);
 		if (rcode!=-1) {
 			/* We only ran a builtin: rcode was set by the return value
 			 * of run_pipe_real(), and we don't need to wait for anything. */
@@ -1943,6 +1944,7 @@
 				debug_printf("pop stack\n");
 				old = ctx->stack;
 				old->child->group = ctx->list_head;
+				old->child->subshell = 0;
 				*ctx = *old;   /* physical copy */
 				free(old);
 			}
diff -urN --exclude=sh.c --exclude=Entries /home/ldoolitt/cvs/busybox/tests/sh.testcases busybox-trial/tests/sh.testcases
--- /home/ldoolitt/cvs/busybox/tests/sh.testcases	Tue Jun  5 16:34:48 2001
+++ busybox-trial/tests/sh.testcases	Wed Jun  6 16:39:33 2001
@@ -28,6 +28,35 @@
 if true || false; then echo foo; else echo bar5; fi
 if true && false; then echo bar6; else echo foo; fi
 
+# basic distinction between local and env variables
+unset FOO
+FOO=bar env | grep FOO
+echo "but not here: $FOO"
+FOO=bar
+env | grep FOO
+echo "yes, here: $FOO"
+FOO=
+echo a $FOO b
+echo "a $FOO b"
+
+# not quite so basic variables.  Credit to Matt Kraai.
+unset FOO
+FOO=bar
+export FOO
+env | grep FOO
+unset FOO
+export FOO=bar
+FOO=baz
+env | grep FOO
+
+# interaction between environment variables and if/then and subshells
+FOO=default
+if true; then FOO=new; fi
+echo $FOO
+FOO=default
+(FOO=bogus)
+echo $FOO
+
 # make sure we can duplicate file descriptors properly
 echo replacement >foo 2>&1
 cat foo





More information about the busybox mailing list