From 8c64e033c0076196a6d7d30ddd922cd6feb15c13 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 20 Apr 2009 00:34:01 +0000 Subject: [PATCH] hush: fix stdin of backgrounded pipe function old new delta run_list 2450 2502 +52 --- shell/hush.c | 28 +++++++++++++++++--------- shell/hush_test/hush-misc/redir5.right | 4 ++++ shell/hush_test/hush-misc/redir5.tests | 13 ++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) create mode 100644 shell/hush_test/hush-misc/redir5.right create mode 100755 shell/hush_test/hush-misc/redir5.tests 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) static const char *const null_ptr = NULL; int i; int nextin; - int pipefds[2]; /* pipefds[0] is for reading */ struct command *command; char **argv_expanded; char **argv; @@ -3552,6 +3551,7 @@ static int run_pipe(struct pipe *pi) nextin = 0; for (i = 0; i < pi->num_cmds; i++) { + struct fd_pair pipefds; #if !BB_MMU volatile nommu_save_t nommu_save; nommu_save.new_env = NULL; @@ -3568,10 +3568,10 @@ static int run_pipe(struct pipe *pi) } /* pipes are inserted between pairs of commands */ - pipefds[0] = 0; - pipefds[1] = 1; + pipefds.rd = 0; + pipefds.wr = 1; if ((i + 1) < pi->num_cmds) - xpipe(pipefds); + xpiped_pair(pipefds); command->pid = BB_MMU ? fork() : vfork(); if (!command->pid) { /* child */ @@ -3592,10 +3592,18 @@ static int run_pipe(struct pipe *pi) } } #endif - xmove_fd(nextin, 0); - xmove_fd(pipefds[1], 1); /* write end */ - if (pipefds[0] > 1) - close(pipefds[0]); /* read end */ + if (pi->alive_cmds == 0 && pi->followup == PIPE_BG) { + /* 1st cmd in backgrounded pipe + * should have its stdin /dev/null'ed */ + close(0); + if (open(bb_dev_null, O_RDONLY)) + xopen("/", O_RDONLY); + } else { + xmove_fd(nextin, 0); + } + xmove_fd(pipefds.wr, 1); + if (pipefds.rd > 1) + close(pipefds.rd); /* Like bash, explicit redirects override pipes, * and the pipe fd is available for dup'ing. */ if (setup_redirects(command, NULL)) @@ -3640,9 +3648,9 @@ static int run_pipe(struct pipe *pi) if (i) close(nextin); if ((i + 1) < pi->num_cmds) - close(pipefds[1]); /* write end */ + close(pipefds.wr); /* Pass read (output) pipe end to next iteration */ - nextin = pipefds[0]; + nextin = pipefds.rd; } 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 @@ +Backgrounded pipes shall have their stdin redirected to /dev/null +Zero:0 +Zero:0 +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 @@ +echo "Backgrounded pipes shall have their stdin redirected to /dev/null" + +# 1. bash does not redirect stdin to /dev/null if it is interactive. +# hush does it always (this is allowed by standards). + +# 2. Failure will result in this script hanging + +cat & wait; echo Zero:$? + +# This does not work for bash! bash bug? +cat | cat & wait; echo Zero:$? + +echo Done