mirror of https://github.com/mirror/busybox.git
Apply post-1.18.4 fixes, bump version to 1.18.5
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>1_18_stable 1_18_5
parent
30f0ea6cab
commit
2e79bc6c77
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VERSION = 1
|
||||
PATCHLEVEL = 18
|
||||
SUBLEVEL = 4
|
||||
SUBLEVEL = 5
|
||||
EXTRAVERSION =
|
||||
NAME = Unnamed
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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/^[^ ]*//' \
|
||||
|
|
82
shell/hush.c
82
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 */
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
OK:0
|
|
@ -0,0 +1,4 @@
|
|||
while false; do
|
||||
# bash will require at least ":" here...
|
||||
done
|
||||
echo OK:$?
|
Loading…
Reference in New Issue