diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-20 00:34:01 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-20 00:34:01 +0000 |
commit | 8c64e033c0076196a6d7d30ddd922cd6feb15c13 (patch) | |
tree | 7ee7d4067090c924cbc17f92f6ac220645dc3790 /shell | |
parent | 11c17f75a7f29da47eae35a2f41d274a99a95760 (diff) | |
download | busybox-w32-8c64e033c0076196a6d7d30ddd922cd6feb15c13.tar.gz busybox-w32-8c64e033c0076196a6d7d30ddd922cd6feb15c13.tar.bz2 busybox-w32-8c64e033c0076196a6d7d30ddd922cd6feb15c13.zip |
hush: fix stdin of backgrounded pipe
function old new delta
run_list 2450 2502 +52
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 28 | ||||
-rw-r--r-- | shell/hush_test/hush-misc/redir5.right | 4 | ||||
-rwxr-xr-x | shell/hush_test/hush-misc/redir5.tests | 13 |
3 files changed, 35 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index 2c2750fc8..d08652656 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -3369,7 +3369,6 @@ static int run_pipe(struct pipe *pi) | |||
3369 | static const char *const null_ptr = NULL; | 3369 | static const char *const null_ptr = NULL; |
3370 | int i; | 3370 | int i; |
3371 | int nextin; | 3371 | int nextin; |
3372 | int pipefds[2]; /* pipefds[0] is for reading */ | ||
3373 | struct command *command; | 3372 | struct command *command; |
3374 | char **argv_expanded; | 3373 | char **argv_expanded; |
3375 | char **argv; | 3374 | char **argv; |
@@ -3552,6 +3551,7 @@ static int run_pipe(struct pipe *pi) | |||
3552 | nextin = 0; | 3551 | nextin = 0; |
3553 | 3552 | ||
3554 | for (i = 0; i < pi->num_cmds; i++) { | 3553 | for (i = 0; i < pi->num_cmds; i++) { |
3554 | struct fd_pair pipefds; | ||
3555 | #if !BB_MMU | 3555 | #if !BB_MMU |
3556 | volatile nommu_save_t nommu_save; | 3556 | volatile nommu_save_t nommu_save; |
3557 | nommu_save.new_env = NULL; | 3557 | nommu_save.new_env = NULL; |
@@ -3568,10 +3568,10 @@ static int run_pipe(struct pipe *pi) | |||
3568 | } | 3568 | } |
3569 | 3569 | ||
3570 | /* pipes are inserted between pairs of commands */ | 3570 | /* pipes are inserted between pairs of commands */ |
3571 | pipefds[0] = 0; | 3571 | pipefds.rd = 0; |
3572 | pipefds[1] = 1; | 3572 | pipefds.wr = 1; |
3573 | if ((i + 1) < pi->num_cmds) | 3573 | if ((i + 1) < pi->num_cmds) |
3574 | xpipe(pipefds); | 3574 | xpiped_pair(pipefds); |
3575 | 3575 | ||
3576 | command->pid = BB_MMU ? fork() : vfork(); | 3576 | command->pid = BB_MMU ? fork() : vfork(); |
3577 | if (!command->pid) { /* child */ | 3577 | if (!command->pid) { /* child */ |
@@ -3592,10 +3592,18 @@ static int run_pipe(struct pipe *pi) | |||
3592 | } | 3592 | } |
3593 | } | 3593 | } |
3594 | #endif | 3594 | #endif |
3595 | xmove_fd(nextin, 0); | 3595 | if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) { |
3596 | xmove_fd(pipefds[1], 1); /* write end */ | 3596 | /* 1st cmd in backgrounded pipe |
3597 | if (pipefds[0] > 1) | 3597 | * should have its stdin /dev/null'ed */ |
3598 | close(pipefds[0]); /* read end */ | 3598 | close(0); |
3599 | if (open(bb_dev_null, O_RDONLY)) | ||
3600 | xopen("/", O_RDONLY); | ||
3601 | } else { | ||
3602 | xmove_fd(nextin, 0); | ||
3603 | } | ||
3604 | xmove_fd(pipefds.wr, 1); | ||
3605 | if (pipefds.rd > 1) | ||
3606 | close(pipefds.rd); | ||
3599 | /* Like bash, explicit redirects override pipes, | 3607 | /* Like bash, explicit redirects override pipes, |
3600 | * and the pipe fd is available for dup'ing. */ | 3608 | * and the pipe fd is available for dup'ing. */ |
3601 | if (setup_redirects(command, NULL)) | 3609 | if (setup_redirects(command, NULL)) |
@@ -3640,9 +3648,9 @@ static int run_pipe(struct pipe *pi) | |||
3640 | if (i) | 3648 | if (i) |
3641 | close(nextin); | 3649 | close(nextin); |
3642 | if ((i + 1) < pi->num_cmds) | 3650 | if ((i + 1) < pi->num_cmds) |
3643 | close(pipefds[1]); /* write end */ | 3651 | close(pipefds.wr); |
3644 | /* Pass read (output) pipe end to next iteration */ | 3652 | /* Pass read (output) pipe end to next iteration */ |
3645 | nextin = pipefds[0]; | 3653 | nextin = pipefds.rd; |
3646 | } | 3654 | } |
3647 | 3655 | ||
3648 | if (!pi->alive_cmds) { | 3656 | if (!pi->alive_cmds) { |
diff --git a/shell/hush_test/hush-misc/redir5.right b/shell/hush_test/hush-misc/redir5.right new file mode 100644 index 000000000..52cce4feb --- /dev/null +++ b/shell/hush_test/hush-misc/redir5.right | |||
@@ -0,0 +1,4 @@ | |||
1 | Backgrounded pipes shall have their stdin redirected to /dev/null | ||
2 | Zero:0 | ||
3 | Zero:0 | ||
4 | Done | ||
diff --git a/shell/hush_test/hush-misc/redir5.tests b/shell/hush_test/hush-misc/redir5.tests new file mode 100755 index 000000000..957f9c81f --- /dev/null +++ b/shell/hush_test/hush-misc/redir5.tests | |||
@@ -0,0 +1,13 @@ | |||
1 | echo "Backgrounded pipes shall have their stdin redirected to /dev/null" | ||
2 | |||
3 | # 1. bash does not redirect stdin to /dev/null if it is interactive. | ||
4 | # hush does it always (this is allowed by standards). | ||
5 | |||
6 | # 2. Failure will result in this script hanging | ||
7 | |||
8 | cat & wait; echo Zero:$? | ||
9 | |||
10 | # This does not work for bash! bash bug? | ||
11 | cat | cat & wait; echo Zero:$? | ||
12 | |||
13 | echo Done | ||