diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 2bad1384950c..f772456171c6 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -883,7 +883,6 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) #ifdef DEBUG trputs("normal command: "); trargs(argv); #endif - clearredir(); redirect(cmd->ncmd.redirect, 0); for (sp = varlist.list ; sp ; sp = sp->next) setvareq(sp->text, VEXPORT|VSTACK); diff --git a/bin/sh/redir.c b/bin/sh/redir.c index 08878f6beac3..2239b9f2e14b 100644 --- a/bin/sh/redir.c +++ b/bin/sh/redir.c @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #define EMPTY -2 /* marks an unused slot in redirtab */ +#define CLOSED -1 /* fd was not open before redir */ #define PIPESIZE 4096 /* amount of buffering in a pipe */ @@ -101,7 +102,6 @@ redirect(union node *redir, int flags) struct redirtab *sv = NULL; int i; int fd; - int try; char memory[10]; /* file descriptors to write to memory */ for (i = 10 ; --i >= 0 ; ) @@ -116,38 +116,30 @@ redirect(union node *redir, int flags) } for (n = redir ; n ; n = n->nfile.next) { fd = n->nfile.fd; - try = 0; if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && n->ndup.dupfd == fd) continue; /* redirect from/to same file descriptor */ if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) { INTOFF; -again: if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { switch (errno) { case EBADF: - if (!try) { - openredirect(n, memory); - try++; - goto again; - } - /* FALLTHROUGH*/ + i = CLOSED; + break; default: INTON; error("%d: %s", fd, strerror(errno)); break; } - } - if (!try) { - sv->renamed[fd] = i; - } + } else + (void)fcntl(i, F_SETFD, FD_CLOEXEC); + sv->renamed[fd] = i; INTON; } if (fd == 0) fd0_redirected++; - if (!try) - openredirect(n, memory); + openredirect(n, memory); } if (memory[1]) out1 = &memout; diff --git a/tools/regression/bin/sh/execution/redir1.0 b/tools/regression/bin/sh/execution/redir1.0 new file mode 100644 index 000000000000..cc5cc49318fe --- /dev/null +++ b/tools/regression/bin/sh/execution/redir1.0 @@ -0,0 +1,27 @@ +# $FreeBSD$ +trap ': $((brokenpipe+=1))' pipe + +P=${TMPDIR:-/tmp} +cd $P +T=$(mktemp -d sh-test.XXXXXX) +cd $T + +brokenpipe=0 +mkfifo fifo1 fifo2 +read dummy >fifo2 fifo2 +} 3fifo1 +if [ $brokenpipe -ne 0 ]; then + rc=3 +fi +wait +echo dummy >&4 +if [ $brokenpipe -eq 1 ]; then + : ${rc:=0} +fi + +rm fifo1 fifo2 +rmdir ${P}/${T} +exit ${rc:-3} diff --git a/tools/regression/bin/sh/execution/redir2.0 b/tools/regression/bin/sh/execution/redir2.0 new file mode 100644 index 000000000000..079ee82f533d --- /dev/null +++ b/tools/regression/bin/sh/execution/redir2.0 @@ -0,0 +1,29 @@ +# $FreeBSD$ +trap ': $((brokenpipe+=1))' pipe + +P=${TMPDIR:-/tmp} +cd $P +T=$(mktemp -d sh-test.XXXXXX) +cd $T + +brokenpipe=0 +mkfifo fifo1 fifo2 +{ + { + exec sh -c 'exec fifo2 +exec 3>fifo1 +echo dummy >&4 +if [ $brokenpipe -eq 1 ]; then + : ${rc:=0} +fi +echo dummy >&3 +wait + +rm fifo1 fifo2 +rmdir ${P}/${T} +exit ${rc:-3}