Apply post-1.18.4 fixes, bump version to 1.18.5 1_18_stable 1_18_5
authorDenys Vlasenko <vda.linux@googlemail.com>
Sun, 12 Jun 2011 15:49:38 +0000 (17:49 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sun, 12 Jun 2011 15:49:38 +0000 (17:49 +0200)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Makefile
procps/fuser.c
scripts/mkconfigs
shell/hush.c
shell/hush_test/hush-misc/while3.right [new file with mode: 0644]
shell/hush_test/hush-misc/while3.tests [new file with mode: 0755]

index cb0e3e4346f71c9f57394c112ce68c972584af4a..75933c25021cf88b64c240432614ad7124ca1dea 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 18
-SUBLEVEL = 4
+SUBLEVEL = 5
 EXTRAVERSION =
 NAME = Unnamed
 
index addf1a7d83c1ec4c5ea103be85fb46912d7f0873..be19098dde93fd6b8f145ff945c11032f0f124ac 100644 (file)
@@ -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:
index 47ac53330854efa3a32dcd17e20c96f379044277..db94fcc442e73c369981c419138d89a4e7c0dafd 100755 (executable)
@@ -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/^[^ ]*//' \
index 58d2c11a98d1e2fc772d0387e4ed8ecb939f99bd..f0a0d85a3b4ddc8062c85143df729e422ffbaca2 100644 (file)
@@ -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 (file)
index 0000000..7c4d7be
--- /dev/null
@@ -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 (executable)
index 0000000..9132b5f
--- /dev/null
@@ -0,0 +1,4 @@
+while false; do
+    # bash will require at least ":" here...
+done
+echo OK:$?