From: Denys Vlasenko Date: Sun, 12 Jun 2011 15:49:38 +0000 (+0200) Subject: Apply post-1.18.4 fixes, bump version to 1.18.5 X-Git-Tag: 1_18_5 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=refs%2Fheads%2F1_18_stable;p=oweals%2Fbusybox.git Apply post-1.18.4 fixes, bump version to 1.18.5 Signed-off-by: Denys Vlasenko --- 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:$?