hush: fix and_or_and_backgrounding.tests failure
No binary (build failed)
—
(log yok)
| @@ -3373,12 +3373,47 @@ static void done_pipe(struct parse_context *ctx, pipe_style type) | |
| debug_printf_parse("done_pipe entered, followup %d\n", type); | |
| /* Close previous command */ | |
| not_null = done_command(ctx); | |
| - | ctx->pipe->followup = type; |
| #if HAS_KEYWORDS | |
| ctx->pipe->pi_inverted = ctx->ctx_inverted; | |
| ctx->ctx_inverted = 0; | |
| ctx->pipe->res_word = ctx->ctx_res_w; | |
| #endif | |
| + | if (type != PIPE_BG || ctx->list_head == ctx->pipe) { |
| + | no_conv: |
| + | ctx->pipe->followup = type; |
| + | } else { |
| + | /* Necessary since && and || have more precedence than &: |
| + | * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2, |
| + | * in a backgrounded subshell. |
| + | */ |
| + | struct pipe *pi; |
| + | struct command *command; |
| + | |
| + | /* Is this actually the case? */ |
| + | pi = ctx->list_head; |
| + | while (pi != ctx->pipe) { |
| + | if (pi->followup != PIPE_AND && pi->followup != PIPE_OR) |
| + | goto no_conv; |
| + | pi = pi->next; |
| + | } |
| + | |
| + | debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n"); |
| + | pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */ |
| + | pi = xzalloc(sizeof(*pi)); |
| + | pi->followup = PIPE_BG; |
| + | pi->num_cmds = 1; |
| + | pi->cmds = xzalloc(sizeof(pi->cmds[0])); |
| + | command = &pi->cmds[0]; |
| + | if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */ |
| + | command->cmd_type = CMD_NORMAL; |
| + | command->group = ctx->list_head; |
| + | #if !BB_MMU |
| + | //TODO: is this correct?! |
| + | command->group_as_string = xstrdup(ctx->as_string.data); |
| + | #endif |
| + | /* Replace all pipes in ctx with one newly created */ |
| + | ctx->list_head = ctx->pipe = pi; |
| + | } |
| /* Without this check, even just <enter> on command line generates | |
| * tree of three NOPs (!). Which is harmless but annoying. | |
| @@ -0,0 +1,4 @@ | |
| + | First |
| + | Second |
| + | Third |
| + | Done |
| @@ -0,0 +1,31 @@ | |
| + | # UNFIXED BUG: hush thinks that ; && || & have the same precedence. |
| + | # According to this doc, && || have higher precedence than ; &. |
| + | # See example below. |
| + | # Precedence of ; is not a problem in practice. Precedence of & is. |
| + | # |
| + | #http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html |
| + | # |
| + | #2.9.3 Lists |
| + | # |
| + | #An AND-OR list is a sequence of one or more pipelines separated by |
| + | #the operators "&&" and "||" . |
| + | # |
| + | #A list is a sequence of one or more AND-OR lists separated by the operators |
| + | #';' and '&' and optionally terminated by ';', '&', or <newline>. |
| + | # |
| + | #The operators "&&" and "||" shall have equal precedence and shall be |
| + | #evaluated with left associativity. For example, both of the following |
| + | #commands write solely bar to standard output: |
| + | # |
| + | # false && echo foo || echo bar |
| + | # true || echo foo && echo bar |
| + | # |
| + | #A ';' or <newline> terminator shall cause the preceding AND-OR list |
| + | #to be executed sequentially; an '&' shall cause asynchronous execution |
| + | #of the preceding AND-OR list. |
| + | |
| + | echo First && sleep 0.2 && echo Third & |
| + | sleep 0.1 |
| + | echo Second |
| + | wait |
| + | echo Done |