diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/shell/hush.c b/shell/hush.c index bb4fdc295..422fc63f6 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -344,8 +344,7 @@ typedef enum redir_type { | |||
344 | 344 | ||
345 | REDIRFD_CLOSE = -3, | 345 | REDIRFD_CLOSE = -3, |
346 | REDIRFD_SYNTAX_ERR = -2, | 346 | REDIRFD_SYNTAX_ERR = -2, |
347 | REDIRFD_TO_FILE = -1, | 347 | REDIRFD_TO_FILE = -1, /* otherwise, rd_fd if redirected to rd_dup */ |
348 | /* otherwise, rd_fd is redirected to rd_dup */ | ||
349 | 348 | ||
350 | HEREDOC_SKIPTABS = 1, | 349 | HEREDOC_SKIPTABS = 1, |
351 | HEREDOC_QUOTED = 2, | 350 | HEREDOC_QUOTED = 2, |
@@ -3999,6 +3998,7 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
3999 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; | 3998 | ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED; |
4000 | } | 3999 | } |
4001 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); | 4000 | debug_printf_parse("word stored in rd_filename: '%s'\n", word->data); |
4001 | ctx->pending_redirect = NULL; | ||
4002 | } else { | 4002 | } else { |
4003 | /* If this word wasn't an assignment, next ones definitely | 4003 | /* If this word wasn't an assignment, next ones definitely |
4004 | * can't be assignments. Even if they look like ones. */ | 4004 | * can't be assignments. Even if they look like ones. */ |
@@ -4076,19 +4076,19 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
4076 | debug_print_strings("word appended to argv", command->argv); | 4076 | debug_print_strings("word appended to argv", command->argv); |
4077 | } | 4077 | } |
4078 | 4078 | ||
4079 | o_reset(word); | ||
4080 | ctx->pending_redirect = NULL; | ||
4081 | |||
4082 | #if ENABLE_HUSH_LOOPS | 4079 | #if ENABLE_HUSH_LOOPS |
4083 | /* Force FOR to have just one word (variable name) */ | ||
4084 | /* NB: basically, this makes hush see "for v in ..." syntax as if | ||
4085 | * as it is "for v; in ...". FOR and IN become two pipe structs | ||
4086 | * in parse tree. */ | ||
4087 | if (ctx->ctx_res_w == RES_FOR) { | 4080 | if (ctx->ctx_res_w == RES_FOR) { |
4088 | if (!is_well_formed_var_name(command->argv[0], '\0')) { | 4081 | if (word->o_quoted |
4089 | syntax_error("malformed variable name in for"); | 4082 | || !is_well_formed_var_name(command->argv[0], '\0') |
4083 | ) { | ||
4084 | /* bash says "not a valid identifier" */ | ||
4085 | syntax_error("not a valid identifier in for"); | ||
4090 | return 1; | 4086 | return 1; |
4091 | } | 4087 | } |
4088 | /* Force FOR to have just one word (variable name) */ | ||
4089 | /* NB: basically, this makes hush see "for v in ..." | ||
4090 | * syntax as if it is "for v; in ...". FOR and IN become | ||
4091 | * two pipe structs in parse tree. */ | ||
4092 | done_pipe(ctx, PIPE_SEQ); | 4092 | done_pipe(ctx, PIPE_SEQ); |
4093 | } | 4093 | } |
4094 | #endif | 4094 | #endif |
@@ -4098,6 +4098,9 @@ static int done_word(o_string *word, struct parse_context *ctx) | |||
4098 | done_pipe(ctx, PIPE_SEQ); | 4098 | done_pipe(ctx, PIPE_SEQ); |
4099 | } | 4099 | } |
4100 | #endif | 4100 | #endif |
4101 | |||
4102 | o_reset(word); | ||
4103 | |||
4101 | debug_printf_parse("done_word return 0\n"); | 4104 | debug_printf_parse("done_word return 0\n"); |
4102 | return 0; | 4105 | return 0; |
4103 | } | 4106 | } |
@@ -6197,6 +6200,8 @@ static int builtin_read(char **argv) | |||
6197 | 6200 | ||
6198 | if (argv[1]) { | 6201 | if (argv[1]) { |
6199 | name = argv[1]; | 6202 | name = argv[1]; |
6203 | /* bash (3.2.33(1)) bug: "read 0abcd" will execute, | ||
6204 | * and _after_ that_ it will complain */ | ||
6200 | if (!is_well_formed_var_name(name, '\0')) { | 6205 | if (!is_well_formed_var_name(name, '\0')) { |
6201 | /* Mimic bash message */ | 6206 | /* Mimic bash message */ |
6202 | bb_error_msg("read: '%s': not a valid identifier", name); | 6207 | bb_error_msg("read: '%s': not a valid identifier", name); |
@@ -6204,6 +6209,8 @@ static int builtin_read(char **argv) | |||
6204 | } | 6209 | } |
6205 | } | 6210 | } |
6206 | 6211 | ||
6212 | //TODO: bash unbackslashes input, splits words and puts them in argv[i] | ||
6213 | |||
6207 | string = xmalloc_reads(STDIN_FILENO, xasprintf("%s=", name), NULL); | 6214 | string = xmalloc_reads(STDIN_FILENO, xasprintf("%s=", name), NULL); |
6208 | return set_local_var(string, 0, 0); | 6215 | return set_local_var(string, 0, 0); |
6209 | } | 6216 | } |