summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Schaefer <barts@users.sourceforge.net>2007-02-14 08:21:57 +0000
committerBart Schaefer <barts@users.sourceforge.net>2007-02-14 08:21:57 +0000
commitf35ee0d1a0f47710fec27f4055b716a5aafe3d6e (patch)
tree6add1a2af986b74e62474ab7fd1d2df2f0f9ef5d
parentbd6baa2ede23c152a9941c3312d93f1f0b1392e8 (diff)
downloadzsh-f35ee0d1a0f47710fec27f4055b716a5aafe3d6e.tar.gz
zsh-f35ee0d1a0f47710fec27f4055b716a5aafe3d6e.zip
23169 (tweaked): report error on failure to dup for multios
-rw-r--r--ChangeLog6
-rw-r--r--Src/exec.c44
2 files changed, 45 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 8df0fac2a..303fb68a7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2007-02-14 Barton E. Schaefer <schaefer@zsh.org>
+
+ * 23169 (tweaked): Src/exec.c: upon failure to duplicate file
+ descriptors when setting up multios, report error and unwind as
+ gracefully as possible.
+
2007-02-13 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 23172: Src/Zle/zle_tricky.c: typo fixing line wrapping
diff --git a/Src/exec.c b/Src/exec.c
index 1d07bffcf..cdd765113 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -1663,8 +1663,23 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
} else if (!mfds[fd1] || unset(MULTIOS)) {
if(!mfds[fd1]) { /* starting a new multio */
mfds[fd1] = (struct multio *) zhalloc(sizeof(struct multio));
- if (!forked && save[fd1] == -2)
- save[fd1] = (fd1 == fd2) ? -1 : movefd(fd1);
+ if (!forked && save[fd1] == -2) {
+ if (fd1 == fd2)
+ save[fd1] = -1;
+ else {
+ int fdN = movefd(fd1);
+ /*
+ * fd1 may already be closed here, so
+ * ignore bad file descriptor error
+ */
+ if (fdN < 0 && errno != EBADF) {
+ zerr("cannot duplicate fd %d: %e", fd1, errno);
+ closemnodes(mfds);
+ return;
+ }
+ save[fd1] = fdN;
+ }
+ }
}
if (!varid)
redup(fd2, fd1);
@@ -1674,22 +1689,41 @@ addfd(int forked, int *save, struct multio **mfds, int fd1, int fd2, int rflag,
} else {
if (mfds[fd1]->rflag != rflag) {
zerr("file mode mismatch on fd %d", fd1);
+ closemnodes(mfds);
return;
}
if (mfds[fd1]->ct == 1) { /* split the stream */
- mfds[fd1]->fds[0] = movefd(fd1);
- mfds[fd1]->fds[1] = movefd(fd2);
+ int fdN = movefd(fd1);
+ if (fdN < 0) {
+ zerr("multio failed for fd %d: %e", fd1, errno);
+ closemnodes(mfds);
+ return;
+ }
+ mfds[fd1]->fds[0] = fdN;
+ fdN = movefd(fd2);
+ if (fdN < 0) {
+ zerr("multio failed for fd %d: %e", fd2, errno);
+ closemnodes(mfds);
+ return;
+ }
+ mfds[fd1]->fds[1] = fdN;
mpipe(pipes);
mfds[fd1]->pipe = pipes[1 - rflag];
redup(pipes[rflag], fd1);
mfds[fd1]->ct = 2;
} else { /* add another fd to an already split stream */
+ int fdN;
if(!(mfds[fd1]->ct % MULTIOUNIT)) {
int new = sizeof(struct multio) + sizeof(int) * mfds[fd1]->ct;
int old = new - sizeof(int) * MULTIOUNIT;
mfds[fd1] = hrealloc((char *)mfds[fd1], old, new);
}
- mfds[fd1]->fds[mfds[fd1]->ct++] = movefd(fd2);
+ if ((fdN = movefd(fd2)) < 0) {
+ zerr("multio failed for fd %d: %e", fd2, errno);
+ closemnodes(mfds);
+ return;
+ }
+ mfds[fd1]->fds[mfds[fd1]->ct++] = fdN;
}
}
if (subsh_close >= 0 && fdtable[subsh_close] == FDT_UNUSED)