aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-15 22:51:55 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-15 22:51:55 +0200
commitee553b929c81ae0051abfd54984aa0537f767d89 (patch)
tree3782b6d025493e7742012ba0dfaca07c11d85c20
parent2c8929c7af5c5618d5f2ed59053c53bac2304184 (diff)
downloadbusybox-w32-ee553b929c81ae0051abfd54984aa0537f767d89.tar.gz
busybox-w32-ee553b929c81ae0051abfd54984aa0537f767d89.tar.bz2
busybox-w32-ee553b929c81ae0051abfd54984aa0537f767d89.zip
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>
-rw-r--r--shell/ash_test/ash-parsing/and_or_and_backgrounding.right (renamed from shell/hush_test/hush-bugs/and_or_and_backgrounding.right)0
-rwxr-xr-xshell/ash_test/ash-parsing/and_or_and_backgrounding.tests (renamed from shell/hush_test/hush-bugs/and_or_and_backgrounding.tests)0
-rw-r--r--shell/hush.c37
-rw-r--r--shell/hush_test/hush-parsing/and_or_and_backgrounding.right4
-rwxr-xr-xshell/hush_test/hush-parsing/and_or_and_backgrounding.tests31
5 files changed, 71 insertions, 1 deletions
diff --git a/shell/hush_test/hush-bugs/and_or_and_backgrounding.right b/shell/ash_test/ash-parsing/and_or_and_backgrounding.right
index 90ce63e01..90ce63e01 100644
--- a/shell/hush_test/hush-bugs/and_or_and_backgrounding.right
+++ b/shell/ash_test/ash-parsing/and_or_and_backgrounding.right
diff --git a/shell/hush_test/hush-bugs/and_or_and_backgrounding.tests b/shell/ash_test/ash-parsing/and_or_and_backgrounding.tests
index 05acfb863..05acfb863 100755
--- a/shell/hush_test/hush-bugs/and_or_and_backgrounding.tests
+++ b/shell/ash_test/ash-parsing/and_or_and_backgrounding.tests
diff --git a/shell/hush.c b/shell/hush.c
index b76351fde..2a734f3de 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -3373,12 +3373,47 @@ static void done_pipe(struct parse_context *ctx, pipe_style type)
3373 debug_printf_parse("done_pipe entered, followup %d\n", type); 3373 debug_printf_parse("done_pipe entered, followup %d\n", type);
3374 /* Close previous command */ 3374 /* Close previous command */
3375 not_null = done_command(ctx); 3375 not_null = done_command(ctx);
3376 ctx->pipe->followup = type;
3377#if HAS_KEYWORDS 3376#if HAS_KEYWORDS
3378 ctx->pipe->pi_inverted = ctx->ctx_inverted; 3377 ctx->pipe->pi_inverted = ctx->ctx_inverted;
3379 ctx->ctx_inverted = 0; 3378 ctx->ctx_inverted = 0;
3380 ctx->pipe->res_word = ctx->ctx_res_w; 3379 ctx->pipe->res_word = ctx->ctx_res_w;
3381#endif 3380#endif
3381 if (type != PIPE_BG || ctx->list_head == ctx->pipe) {
3382 no_conv:
3383 ctx->pipe->followup = type;
3384 } else {
3385 /* Necessary since && and || have more precedence than &:
3386 * "cmd1 && cmd2 &" must spawn both cmds, not only cmd2,
3387 * in a backgrounded subshell.
3388 */
3389 struct pipe *pi;
3390 struct command *command;
3391
3392 /* Is this actually the case? */
3393 pi = ctx->list_head;
3394 while (pi != ctx->pipe) {
3395 if (pi->followup != PIPE_AND && pi->followup != PIPE_OR)
3396 goto no_conv;
3397 pi = pi->next;
3398 }
3399
3400 debug_printf_parse("BG with more than one pipe, converting to { p1 &&...pN; } &\n");
3401 pi->followup = PIPE_SEQ; /* close pN _not_ with "&"! */
3402 pi = xzalloc(sizeof(*pi));
3403 pi->followup = PIPE_BG;
3404 pi->num_cmds = 1;
3405 pi->cmds = xzalloc(sizeof(pi->cmds[0]));
3406 command = &pi->cmds[0];
3407 if (CMD_NORMAL != 0) /* "if xzalloc didn't do that already" */
3408 command->cmd_type = CMD_NORMAL;
3409 command->group = ctx->list_head;
3410#if !BB_MMU
3411//TODO: is this correct?!
3412 command->group_as_string = xstrdup(ctx->as_string.data);
3413#endif
3414 /* Replace all pipes in ctx with one newly created */
3415 ctx->list_head = ctx->pipe = pi;
3416 }
3382 3417
3383 /* Without this check, even just <enter> on command line generates 3418 /* Without this check, even just <enter> on command line generates
3384 * tree of three NOPs (!). Which is harmless but annoying. 3419 * tree of three NOPs (!). Which is harmless but annoying.
diff --git a/shell/hush_test/hush-parsing/and_or_and_backgrounding.right b/shell/hush_test/hush-parsing/and_or_and_backgrounding.right
new file mode 100644
index 000000000..90ce63e01
--- /dev/null
+++ b/shell/hush_test/hush-parsing/and_or_and_backgrounding.right
@@ -0,0 +1,4 @@
1First
2Second
3Third
4Done
diff --git a/shell/hush_test/hush-parsing/and_or_and_backgrounding.tests b/shell/hush_test/hush-parsing/and_or_and_backgrounding.tests
new file mode 100755
index 000000000..05acfb863
--- /dev/null
+++ b/shell/hush_test/hush-parsing/and_or_and_backgrounding.tests
@@ -0,0 +1,31 @@
1# UNFIXED BUG: hush thinks that ; && || & have the same precedence.
2# According to this doc, && || have higher precedence than ; &.
3# See example below.
4# Precedence of ; is not a problem in practice. Precedence of & is.
5#
6#http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html
7#
8#2.9.3 Lists
9#
10#An AND-OR list is a sequence of one or more pipelines separated by
11#the operators "&&" and "||" .
12#
13#A list is a sequence of one or more AND-OR lists separated by the operators
14#';' and '&' and optionally terminated by ';', '&', or <newline>.
15#
16#The operators "&&" and "||" shall have equal precedence and shall be
17#evaluated with left associativity. For example, both of the following
18#commands write solely bar to standard output:
19#
20# false && echo foo || echo bar
21# true || echo foo && echo bar
22#
23#A ';' or <newline> terminator shall cause the preceding AND-OR list
24#to be executed sequentially; an '&' shall cause asynchronous execution
25#of the preceding AND-OR list.
26
27echo First && sleep 0.2 && echo Third &
28sleep 0.1
29echo Second
30wait
31echo Done