hush: fix and_or_and_backgrounding.tests failure
function old new delta done_pipe 133 218 +85 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
2c8929c7af
commit
ee553b929c
37
shell/hush.c
37
shell/hush.c
@ -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
|
31
shell/hush_test/hush-parsing/and_or_and_backgrounding.tests
Executable file
31
shell/hush_test/hush-parsing/and_or_and_backgrounding.tests
Executable file
@ -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
|
Loading…
Reference in New Issue
Block a user