[git commit 1_18_stable] Apply post-1.18.4 fixes, bump version to 1.18.5

Denys Vlasenko vda.linux at googlemail.com
Sun Jun 12 15:15:16 UTC 2011


commit: http://git.busybox.net/busybox/commit/?id=2e79bc6c77560d4460847a459857039774de004a
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/1_18_stable

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 Makefile                               |    2 +-
 procps/fuser.c                         |    2 +-
 scripts/mkconfigs                      |    4 +-
 shell/hush.c                           |   82 ++++++++++++++++++++-----------
 shell/hush_test/hush-misc/while3.right |    1 +
 shell/hush_test/hush-misc/while3.tests |    4 ++
 6 files changed, 62 insertions(+), 33 deletions(-)
 create mode 100644 shell/hush_test/hush-misc/while3.right
 create mode 100755 shell/hush_test/hush-misc/while3.tests

diff --git a/Makefile b/Makefile
index cb0e3e4..75933c2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 18
-SUBLEVEL = 4
+SUBLEVEL = 5
 EXTRAVERSION =
 NAME = Unnamed
 
diff --git a/procps/fuser.c b/procps/fuser.c
index addf1a7..be19098 100644
--- a/procps/fuser.c
+++ b/procps/fuser.c
@@ -271,7 +271,7 @@ Find processes which use FILEs or PORTs
 		if (sscanf(*pp, "%u/%4s", &port, tproto) != 2)
 			goto file;
 		sprintf(path, "/proc/net/%s", tproto);
-		if (access(path, R_OK) != 0) { /* PORT/PROTO */
+		if (access(path, R_OK) == 0) { /* PORT/PROTO */
 			scan_proc_net(path, port);
 		} else { /* FILE */
  file:
diff --git a/scripts/mkconfigs b/scripts/mkconfigs
index 47ac533..db94fcc 100755
--- a/scripts/mkconfigs
+++ b/scripts/mkconfigs
@@ -42,7 +42,7 @@ echo "\
  */
 static const char bbconfig_config[] ALIGN1 ="
 
-grep '^#\? \?CONFIG_' "$config" \
+grep -e '^# CONFIG_' -e '^CONFIG_' "$config" \
 | sed -e 's/\"/\\\"/g' -e 's/^/"/' -e 's/$/\\n"/'
 
 echo ";"
@@ -63,7 +63,7 @@ echo "\
  */
 static const char bbconfig_config_bz2[] ALIGN1 = {"
 
-grep '^#\? \?CONFIG_' "$config" \
+grep -e '^# CONFIG_' -e '^CONFIG_' "$config" \
 | bzip2 -1 | dd bs=2 skip=1 2>/dev/null \
 | od -v -t x1 \
 | sed -e 's/^[^ ]*//' \
diff --git a/shell/hush.c b/shell/hush.c
index 58d2c11..f0a0d85 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -427,6 +427,15 @@ enum {
 /* Used for initialization: o_string foo = NULL_O_STRING; */
 #define NULL_O_STRING { NULL }
 
+#ifndef debug_printf_parse
+static const char *const assignment_flag[] = {
+	"MAYBE_ASSIGNMENT",
+	"DEFINITELY_ASSIGNMENT",
+	"NOT_ASSIGNMENT",
+	"WORD_IS_KEYWORD",
+};
+#endif
+
 /* I can almost use ordinary FILE*.  Is open_memstream() universally
  * available?  Where is it documented? */
 typedef struct in_str {
@@ -2885,24 +2894,24 @@ static const struct reserved_combo* match_reserved_word(o_string *word)
 	 */
 	static const struct reserved_combo reserved_list[] = {
 # if ENABLE_HUSH_IF
-		{ "!",     RES_NONE,  NOT_ASSIGNMENT , 0 },
-		{ "if",    RES_IF,    WORD_IS_KEYWORD, FLAG_THEN | FLAG_START },
-		{ "then",  RES_THEN,  WORD_IS_KEYWORD, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
-		{ "elif",  RES_ELIF,  WORD_IS_KEYWORD, FLAG_THEN },
-		{ "else",  RES_ELSE,  WORD_IS_KEYWORD, FLAG_FI   },
-		{ "fi",    RES_FI,    NOT_ASSIGNMENT , FLAG_END  },
+		{ "!",     RES_NONE,  NOT_ASSIGNMENT  , 0 },
+		{ "if",    RES_IF,    MAYBE_ASSIGNMENT, FLAG_THEN | FLAG_START },
+		{ "then",  RES_THEN,  MAYBE_ASSIGNMENT, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
+		{ "elif",  RES_ELIF,  MAYBE_ASSIGNMENT, FLAG_THEN },
+		{ "else",  RES_ELSE,  MAYBE_ASSIGNMENT, FLAG_FI   },
+		{ "fi",    RES_FI,    NOT_ASSIGNMENT  , FLAG_END  },
 # endif
 # if ENABLE_HUSH_LOOPS
-		{ "for",   RES_FOR,   NOT_ASSIGNMENT , FLAG_IN | FLAG_DO | FLAG_START },
-		{ "while", RES_WHILE, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
-		{ "until", RES_UNTIL, WORD_IS_KEYWORD, FLAG_DO | FLAG_START },
-		{ "in",    RES_IN,    NOT_ASSIGNMENT , FLAG_DO   },
-		{ "do",    RES_DO,    WORD_IS_KEYWORD, FLAG_DONE },
-		{ "done",  RES_DONE,  NOT_ASSIGNMENT , FLAG_END  },
+		{ "for",   RES_FOR,   NOT_ASSIGNMENT  , FLAG_IN | FLAG_DO | FLAG_START },
+		{ "while", RES_WHILE, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
+		{ "until", RES_UNTIL, MAYBE_ASSIGNMENT, FLAG_DO | FLAG_START },
+		{ "in",    RES_IN,    NOT_ASSIGNMENT  , FLAG_DO   },
+		{ "do",    RES_DO,    MAYBE_ASSIGNMENT, FLAG_DONE },
+		{ "done",  RES_DONE,  NOT_ASSIGNMENT  , FLAG_END  },
 # endif
 # if ENABLE_HUSH_CASE
-		{ "case",  RES_CASE,  NOT_ASSIGNMENT , FLAG_MATCH | FLAG_START },
-		{ "esac",  RES_ESAC,  NOT_ASSIGNMENT , FLAG_END  },
+		{ "case",  RES_CASE,  NOT_ASSIGNMENT  , FLAG_MATCH | FLAG_START },
+		{ "esac",  RES_ESAC,  NOT_ASSIGNMENT  , FLAG_END  },
 # endif
 	};
 	const struct reserved_combo *r;
@@ -2968,6 +2977,7 @@ static int reserved_word(o_string *word, struct parse_context *ctx)
 	ctx->ctx_res_w = r->res;
 	ctx->old_flag = r->flag;
 	word->o_assignment = r->assignment_flag;
+	debug_printf_parse("word->o_assignment='%s'\n", assignment_flag[word->o_assignment]);
 
 	if (ctx->old_flag & FLAG_END) {
 		struct parse_context *old;
@@ -3034,18 +3044,6 @@ static int done_word(o_string *word, struct parse_context *ctx)
 		debug_printf_parse("word stored in rd_filename: '%s'\n", word->data);
 		ctx->pending_redirect = NULL;
 	} else {
-		/* If this word wasn't an assignment, next ones definitely
-		 * can't be assignments. Even if they look like ones. */
-		if (word->o_assignment != DEFINITELY_ASSIGNMENT
-		 && word->o_assignment != WORD_IS_KEYWORD
-		) {
-			word->o_assignment = NOT_ASSIGNMENT;
-		} else {
-			if (word->o_assignment == DEFINITELY_ASSIGNMENT)
-				command->assignment_cnt++;
-			word->o_assignment = MAYBE_ASSIGNMENT;
-		}
-
 #if HAS_KEYWORDS
 # if ENABLE_HUSH_CASE
 		if (ctx->ctx_dsemicolon
@@ -3065,8 +3063,9 @@ static int done_word(o_string *word, struct parse_context *ctx)
 		 && ctx->ctx_res_w != RES_CASE
 # endif
 		) {
-			debug_printf_parse("checking '%s' for reserved-ness\n", word->data);
-			if (reserved_word(word, ctx)) {
+			int reserved = reserved_word(word, ctx);
+			debug_printf_parse("checking for reserved-ness: %d\n", reserved);
+			if (reserved) {
 				o_reset_to_empty_unquoted(word);
 				debug_printf_parse("done_word return %d\n",
 						(ctx->ctx_res_w == RES_SNTX));
@@ -3087,6 +3086,23 @@ static int done_word(o_string *word, struct parse_context *ctx)
 					"groups and arglists don't mix\n");
 			return 1;
 		}
+
+		/* If this word wasn't an assignment, next ones definitely
+		 * can't be assignments. Even if they look like ones. */
+		if (word->o_assignment != DEFINITELY_ASSIGNMENT
+		 && word->o_assignment != WORD_IS_KEYWORD
+		) {
+			word->o_assignment = NOT_ASSIGNMENT;
+		} else {
+			if (word->o_assignment == DEFINITELY_ASSIGNMENT) {
+				command->assignment_cnt++;
+				debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
+			}
+			debug_printf_parse("word->o_assignment was:'%s'\n", assignment_flag[word->o_assignment]);
+			word->o_assignment = MAYBE_ASSIGNMENT;
+		}
+		debug_printf_parse("word->o_assignment='%s'\n", assignment_flag[word->o_assignment]);
+
 		if (word->has_quoted_part
 		 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
 		 && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
@@ -4105,6 +4121,7 @@ static struct pipe *parse_stream(char **pstring,
 			 && is_well_formed_var_name(dest.data, '=')
 			) {
 				dest.o_assignment = DEFINITELY_ASSIGNMENT;
+				debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
 			}
 			continue;
 		}
@@ -4154,6 +4171,7 @@ static struct pipe *parse_stream(char **pstring,
 					heredoc_cnt = 0;
 				}
 				dest.o_assignment = MAYBE_ASSIGNMENT;
+				debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
 				ch = ';';
 				/* note: if (is_blank) continue;
 				 * will still trigger for us */
@@ -4203,6 +4221,7 @@ static struct pipe *parse_stream(char **pstring,
 			}
 			done_pipe(&ctx, PIPE_SEQ);
 			dest.o_assignment = MAYBE_ASSIGNMENT;
+			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
 			/* Do we sit outside of any if's, loops or case's? */
 			if (!HAS_KEYWORDS
 			 IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
@@ -4309,6 +4328,7 @@ static struct pipe *parse_stream(char **pstring,
 			/* ch is a special char and thus this word
 			 * cannot be an assignment */
 			dest.o_assignment = NOT_ASSIGNMENT;
+			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
 		}
 
 		/* Note: nommu_addchr(&ctx.as_string, ch) is already done */
@@ -4406,6 +4426,7 @@ static struct pipe *parse_stream(char **pstring,
 			/* We just finished a cmd. New one may start
 			 * with an assignment */
 			dest.o_assignment = MAYBE_ASSIGNMENT;
+			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
 			break;
 		case '&':
 			if (done_word(&dest, &ctx)) {
@@ -7292,7 +7313,10 @@ static int run_list(struct pipe *pi)
 #endif
 #if ENABLE_HUSH_LOOPS
 		/* Beware of "while false; true; do ..."! */
-		if (pi->next && pi->next->res_word == RES_DO) {
+		if (pi->next
+		 && (pi->next->res_word == RES_DO || pi->next->res_word == RES_DONE)
+		/* (the second check above is needed for "while ...; do \n done" case) */
+		) {
 			if (rword == RES_WHILE) {
 				if (rcode) {
 					/* "while false; do...done" - exitcode 0 */
diff --git a/shell/hush_test/hush-misc/while3.right b/shell/hush_test/hush-misc/while3.right
new file mode 100644
index 0000000..7c4d7be
--- /dev/null
+++ b/shell/hush_test/hush-misc/while3.right
@@ -0,0 +1 @@
+OK:0
diff --git a/shell/hush_test/hush-misc/while3.tests b/shell/hush_test/hush-misc/while3.tests
new file mode 100755
index 0000000..9132b5f
--- /dev/null
+++ b/shell/hush_test/hush-misc/while3.tests
@@ -0,0 +1,4 @@
+while false; do
+    # bash will require at least ":" here...
+done
+echo OK:$?
-- 
1.7.3.4



More information about the busybox-cvs mailing list