diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-09-04 06:22:10 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-09-04 06:22:10 +0200 |
commit | b5be13ccd9ce2120468a381a5475955013c0f049 (patch) | |
tree | cf2b99e5a1fc91944dade4c72694f7704502d438 | |
parent | 2156e228537065f04e5f862e186421df0db36612 (diff) | |
download | busybox-w32-b5be13ccd9ce2120468a381a5475955013c0f049.tar.gz busybox-w32-b5be13ccd9ce2120468a381a5475955013c0f049.tar.bz2 busybox-w32-b5be13ccd9ce2120468a381a5475955013c0f049.zip |
hush: fix a nommu bug where a part of function body is lost if run in a pipe
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 35 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/nommu3.right | 2 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/nommu3.tests | 15 |
3 files changed, 42 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index 3ca04494c..752080a64 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -3161,11 +3161,29 @@ static int reserved_word(o_string *word, struct parse_context *ctx) | |||
3161 | old->command->group = ctx->list_head; | 3161 | old->command->group = ctx->list_head; |
3162 | old->command->cmd_type = CMD_NORMAL; | 3162 | old->command->cmd_type = CMD_NORMAL; |
3163 | # if !BB_MMU | 3163 | # if !BB_MMU |
3164 | o_addstr(&old->as_string, ctx->as_string.data); | 3164 | /* At this point, the compound command's string is in |
3165 | o_free_unsafe(&ctx->as_string); | 3165 | * ctx->as_string... except for the leading keyword! |
3166 | old->command->group_as_string = xstrdup(old->as_string.data); | 3166 | * Consider this example: "echo a | if true; then echo a; fi" |
3167 | debug_printf_parse("pop, remembering as:'%s'\n", | 3167 | * ctx->as_string will contain "true; then echo a; fi", |
3168 | old->command->group_as_string); | 3168 | * with "if " remaining in old->as_string! |
3169 | */ | ||
3170 | { | ||
3171 | char *str; | ||
3172 | int len = old->as_string.length; | ||
3173 | /* Concatenate halves */ | ||
3174 | o_addstr(&old->as_string, ctx->as_string.data); | ||
3175 | o_free_unsafe(&ctx->as_string); | ||
3176 | /* Find where leading keyword starts in first half */ | ||
3177 | str = old->as_string.data + len; | ||
3178 | if (str > old->as_string.data) | ||
3179 | str--; /* skip whitespace after keyword */ | ||
3180 | while (str > old->as_string.data && isalpha(str[-1])) | ||
3181 | str--; | ||
3182 | /* Ugh, we're done with this horrid hack */ | ||
3183 | old->command->group_as_string = xstrdup(str); | ||
3184 | debug_printf_parse("pop, remembering as:'%s'\n", | ||
3185 | old->command->group_as_string); | ||
3186 | } | ||
3169 | # endif | 3187 | # endif |
3170 | *ctx = *old; /* physical copy */ | 3188 | *ctx = *old; /* physical copy */ |
3171 | free(old); | 3189 | free(old); |
@@ -4248,7 +4266,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4248 | pi = NULL; | 4266 | pi = NULL; |
4249 | } | 4267 | } |
4250 | #if !BB_MMU | 4268 | #if !BB_MMU |
4251 | debug_printf_parse("as_string '%s'\n", ctx.as_string.data); | 4269 | debug_printf_parse("as_string1 '%s'\n", ctx.as_string.data); |
4252 | if (pstring) | 4270 | if (pstring) |
4253 | *pstring = ctx.as_string.data; | 4271 | *pstring = ctx.as_string.data; |
4254 | else | 4272 | else |
@@ -4399,7 +4417,7 @@ static struct pipe *parse_stream(char **pstring, | |||
4399 | ) { | 4417 | ) { |
4400 | o_free(&dest); | 4418 | o_free(&dest); |
4401 | #if !BB_MMU | 4419 | #if !BB_MMU |
4402 | debug_printf_parse("as_string '%s'\n", ctx.as_string.data); | 4420 | debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data); |
4403 | if (pstring) | 4421 | if (pstring) |
4404 | *pstring = ctx.as_string.data; | 4422 | *pstring = ctx.as_string.data; |
4405 | else | 4423 | else |
@@ -4639,9 +4657,6 @@ static struct pipe *parse_stream(char **pstring, | |||
4639 | * with redirect_opt_num(), but bash doesn't do it. | 4657 | * with redirect_opt_num(), but bash doesn't do it. |
4640 | * "echo foo 2| cat" yields "foo 2". */ | 4658 | * "echo foo 2| cat" yields "foo 2". */ |
4641 | done_command(&ctx); | 4659 | done_command(&ctx); |
4642 | #if !BB_MMU | ||
4643 | o_reset_to_empty_unquoted(&ctx.as_string); | ||
4644 | #endif | ||
4645 | } | 4660 | } |
4646 | goto new_cmd; | 4661 | goto new_cmd; |
4647 | case '(': | 4662 | case '(': |
diff --git a/shell/hush_test/hush-misc/nommu3.right b/shell/hush_test/hush-misc/nommu3.right new file mode 100644 index 000000000..da1534bef --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.right | |||
@@ -0,0 +1,2 @@ | |||
1 | Ok | ||
2 | 0 | ||
diff --git a/shell/hush_test/hush-misc/nommu3.tests b/shell/hush_test/hush-misc/nommu3.tests new file mode 100755 index 000000000..0aca67a67 --- /dev/null +++ b/shell/hush_test/hush-misc/nommu3.tests | |||
@@ -0,0 +1,15 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | func() | ||
4 | { | ||
5 | while read p; do echo "$p"; done | ||
6 | } | ||
7 | |||
8 | pipe_to_func() | ||
9 | { | ||
10 | # We had a NOMMU bug which caused "echo Ok |" part ot be lost | ||
11 | echo Ok | func | ||
12 | } | ||
13 | |||
14 | pipe_to_func | cat | ||
15 | echo $? | ||