summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-06-12 17:49:38 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-06-12 17:49:38 +0200
commit2e79bc6c77560d4460847a459857039774de004a (patch)
tree17148ca59e5b221bcd0dda72023c6ac4748e93f4
parent30f0ea6cab956ed59ecc5de82459187763a2b868 (diff)
downloadbusybox-1_18_stable.tar.gz
Apply post-1.18.4 fixes, bump version to 1.18.51_18_51_18_stable
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--Makefile2
-rw-r--r--procps/fuser.c2
-rwxr-xr-xscripts/mkconfigs4
-rw-r--r--shell/hush.c82
-rw-r--r--shell/hush_test/hush-misc/while3.right1
-rwxr-xr-xshell/hush_test/hush-misc/while3.tests4
6 files changed, 62 insertions, 33 deletions
diff --git a/Makefile b/Makefile
index cb0e3e434..75933c250 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 addf1a7d8..be19098dd 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 47ac53330..db94fcc44 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 58d2c11a9..f0a0d85a3 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 000000000..7c4d7beb0
--- /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 000000000..9132b5f4d
--- /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:$?