svn commit: [25995] trunk/busybox/shell: hush_test hush_test/hush-misc

vda at busybox.net vda at busybox.net
Mon Apr 6 18:08:36 UTC 2009


Author: vda
Date: 2009-04-06 18:08:35 +0000 (Mon, 06 Apr 2009)
New Revision: 25995

Log:
hush: fix a bunch of obscure while/until/continue bugs

function                                             old     new   delta
run_list                                            1159    1214     +55
done_pipe                                            106     123     +17
done_command                                          86      98     +12
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/0 up/down: 84/0)               Total: 84 bytes



Added:
   trunk/busybox/shell/hush_test/hush-misc/continue2.right
   trunk/busybox/shell/hush_test/hush-misc/continue2.tests
   trunk/busybox/shell/hush_test/hush-misc/continue3.right
   trunk/busybox/shell/hush_test/hush-misc/continue3.tests
   trunk/busybox/shell/hush_test/hush-misc/until1.right
   trunk/busybox/shell/hush_test/hush-misc/until1.tests
   trunk/busybox/shell/hush_test/hush-misc/while2.right
   trunk/busybox/shell/hush_test/hush-misc/while2.tests

Modified:
   trunk/busybox/shell/hush.c
   trunk/busybox/shell/hush_test/run-all


Changeset:
Modified: trunk/busybox/shell/hush.c
===================================================================
--- trunk/busybox/shell/hush.c	2009-04-06 16:27:51 UTC (rev 25994)
+++ trunk/busybox/shell/hush.c	2009-04-06 18:08:35 UTC (rev 25995)
@@ -2994,7 +2994,7 @@
 			struct command *command = &pi->cmds[prn];
 			char **argv = command->argv;
 
-			fprintf(stderr, "%*s prog %d assignment_cnt:%d",
+			fprintf(stderr, "%*s cmd %d assignment_cnt:%d",
 					lvl*2, "", prn,
 					command->assignment_cnt);
 			if (command->group) {
@@ -3038,8 +3038,8 @@
 #else
 	enum { cond_code = 0 };
 #endif
-	/*enum reserved_style*/ smallint rword;
-	/*enum reserved_style*/ smallint last_rword;
+	smallint rword; /* enum reserved_style */
+	smallint last_rword; /* ditto */
 
 	debug_printf_exec("run_list start lvl %d\n", G.run_list_level + 1);
 
@@ -3307,8 +3307,7 @@
 				if (G.run_list_level == 1)
 					insert_bg_job(pi);
 #endif
-				rcode = EXIT_SUCCESS;
-				G.last_return_code = EXIT_SUCCESS;
+				G.last_return_code = rcode = EXIT_SUCCESS;
 				debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
 			} else {
 #if ENABLE_HUSH_JOB
@@ -3334,17 +3333,23 @@
 			cond_code = rcode;
 #endif
 #if ENABLE_HUSH_LOOPS
-		if (rword == RES_WHILE) {
-			if (rcode) {
-				rcode = 0; /* "while false; do...done" - exitcode 0 */
-				goto check_jobs_and_break;
+		/* Beware of "while false; true; do ..."! */
+		if (pi->next && pi->next->res_word == RES_DO) {
+			if (rword == RES_WHILE) {
+				if (rcode) {
+					/* "while false; do...done" - exitcode 0 */
+					G.last_return_code = rcode = EXIT_SUCCESS;
+					debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n");
+					goto check_jobs_and_break;
+				}
 			}
-		}
-		if (rword == RES_UNTIL) {
-			if (!rcode) {
+			if (rword == RES_UNTIL) {
+				if (!rcode) {
+					debug_printf_exec(": until expr is true: breaking\n");
  check_jobs_and_break:
-				checkjobs(NULL);
-				break;
+					checkjobs(NULL);
+					break;
+				}
 			}
 		}
 #endif
@@ -3498,10 +3503,12 @@
 		 && command->redirects == NULL
 		) {
 			debug_printf_parse("done_command: skipping null cmd, num_cmds=%d\n", pi->num_cmds);
+			memset(command, 0, sizeof(*command)); /* paranoia */
 			return pi->num_cmds;
 		}
 		pi->num_cmds++;
 		debug_printf_parse("done_command: ++num_cmds=%d\n", pi->num_cmds);
+		//debug_print_tree(ctx->list_head, 20);
 	} else {
 		debug_printf_parse("done_command: initializing, num_cmds=%d\n", pi->num_cmds);
 	}
@@ -3526,16 +3533,26 @@
 	/* Close previous command */
 	not_null = done_command(ctx);
 	ctx->pipe->followup = type;
-	IF_HAS_KEYWORDS(ctx->pipe->pi_inverted = ctx->ctx_inverted;)
-	IF_HAS_KEYWORDS(ctx->ctx_inverted = 0;)
-	IF_HAS_KEYWORDS(ctx->pipe->res_word = ctx->ctx_res_w;)
+#if HAS_KEYWORDS
+	ctx->pipe->pi_inverted = ctx->ctx_inverted;
+	ctx->ctx_inverted = 0;
+	ctx->pipe->res_word = ctx->ctx_res_w;
+#endif
 
 	/* Without this check, even just <enter> on command line generates
 	 * tree of three NOPs (!). Which is harmless but annoying.
 	 * IOW: it is safe to do it unconditionally.
 	 * RES_NONE case is for "for a in; do ..." (empty IN set)
-	 * to work, possibly other cases too. */
-	if (not_null IF_HAS_KEYWORDS(|| ctx->ctx_res_w != RES_NONE)) {
+	 * and other cases to work. */
+	if (not_null
+#if HAS_KEYWORDS
+	 || ctx->ctx_res_w == RES_FI
+	 || ctx->ctx_res_w == RES_DONE
+	 || ctx->ctx_res_w == RES_FOR
+	 || ctx->ctx_res_w == RES_IN
+	 || ctx->ctx_res_w == RES_ESAC
+#endif
+	) {
 		struct pipe *new_p;
 		debug_printf_parse("done_pipe: adding new pipe: "
 				"not_null:%d ctx->ctx_res_w:%d\n",
@@ -3564,6 +3581,7 @@
 		 * ctx->command = &ctx->pipe->cmds[0];
 		 */
 		done_command(ctx);
+		//debug_print_tree(ctx->list_head, 10);
 	}
 	debug_printf_parse("done_pipe return\n");
 }
@@ -5483,6 +5501,7 @@
 
 static int builtin_exit(char **argv)
 {
+	debug_printf_exec("%s()\n", __func__);
 // TODO: bash does it ONLY on top-level sh exit (+interacive only?)
 	//puts("exit"); /* bash does it */
 // TODO: warn if we have background jobs: "There are stopped jobs"

Added: trunk/busybox/shell/hush_test/hush-misc/continue2.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/continue2.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/continue2.right	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1 @@
+Ok:1

Added: trunk/busybox/shell/hush_test/hush-misc/continue2.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/continue2.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/continue2.tests	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,3 @@
+e=''
+(while test $e && exit 1; true; do e=1; continue; done)
+echo Ok:$?

Added: trunk/busybox/shell/hush_test/hush-misc/continue3.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/continue3.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/continue3.right	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,2 @@
+0
+0

Added: trunk/busybox/shell/hush_test/hush-misc/continue3.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/continue3.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/continue3.tests	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,3 @@
+# Test that "continue" does affect exitcode (sets to 0)
+e=''
+while echo $?; test $e && exit; true; do e=1; false; continue; done

Added: trunk/busybox/shell/hush_test/hush-misc/until1.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/until1.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/until1.right	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,3 @@
+1
+1
+Ok:0

Added: trunk/busybox/shell/hush_test/hush-misc/until1.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/until1.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/until1.tests	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,11 @@
+x=1
+until test "$x" = 4; do echo $x; x=4; done
+
+# We had a bug in multi-line form
+x=1
+until test "$x" = 4; do
+        echo $x
+        x=4
+done
+
+echo Ok:$?

Added: trunk/busybox/shell/hush_test/hush-misc/while2.right
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/while2.right	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/while2.right	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,2 @@
+Hello
+OK:0

Added: trunk/busybox/shell/hush_test/hush-misc/while2.tests
===================================================================
--- trunk/busybox/shell/hush_test/hush-misc/while2.tests	                        (rev 0)
+++ trunk/busybox/shell/hush_test/hush-misc/while2.tests	2009-04-06 18:08:35 UTC (rev 25995)
@@ -0,0 +1,2 @@
+while echo Hello; false; do echo NOT SHOWN; done
+echo OK:$?

Modified: trunk/busybox/shell/hush_test/run-all
===================================================================
--- trunk/busybox/shell/hush_test/run-all	2009-04-06 16:27:51 UTC (rev 25994)
+++ trunk/busybox/shell/hush_test/run-all	2009-04-06 18:08:35 UTC (rev 25995)
@@ -46,7 +46,7 @@
 	test -x "$x" || continue
 	name="${x%%.tests}"
 	test -f "$name.right" || continue
-#	echo Running test: "$name.right"
+#	echo Running test: "$x"
 	{
 	    "$THIS_SH" "./$x" >"$name.xx" 2>&1
 	    diff -u "$name.xx" "$name.right" >"../$1-$x.fail" && rm -f "$name.xx" "../$1-$x.fail"



More information about the busybox-cvs mailing list