Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Redirection Bug II -- It's Back
- X-seq: zsh-workers 331
- From: Zefram <A.Main@xxxxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx (Z Shell workers mailing list)
- Subject: Re: Redirection Bug II -- It's Back
- Date: Fri, 18 Aug 1995 01:58:09 +0100 (BST)
- In-reply-to: <1992.199508172108@xxxxxxxxxxxxxxxxxxxxxxxxxx> from "Zefram" at Aug 17, 95 10:08:22 pm
-----BEGIN PGP SIGNED MESSAGE-----
Here's the fix for the new redirection bug. The problem was that
dup'ing redirections (x>&y, x<&y) and closing redirections (x>&-, x<&-)
stomped all over any existing redirection, including the record of
which fd to use to restore the status quo after the redirected
command. I fixed this in a different way for each case: after the
patch, dup'ing redirections cooperate with multios, and closing
redirections fully close multios but don't overwrite the saved fd. I
also, necessarily, make addfd(), which sets up multios, make sure it
doesn't overwrite a record of a saved fd, so that additional
redirections after a closing redirection will work.
Another problem with dup'ing redirections and multios is that, in a
naive implementation,
% echo a 3>x >&3 3>y 3>z
would echo into x but not y or z, but
% echo b 3>x 3>y >&3 3>z
would echo into all three files. That happens because in the first
case fd 3 is a simple fd with no multio at the time of the dup, but in
the second case it's already a multio that gets added to after the
dup. There's some code in the patch below that `finalises' a multio
when it gets dup'ed, and then sets up the same multio as a multio again
so that it can continue to be added to.
After this patch, multios get beautifully, and intuitively, flexible:
% echo c >&1 >x
does a tee, and
% echo d >x >&1
sends *two copies* of the output into the file.
% echo e >&1 >&1 >&1
sends *four* copies of the output to stdout.
% { echo f; echo g >&3 } 3>x >&3 3>y
puts "f" into x, and "g" into x and y. You get the idea.
The patch to utils.c below fixes a little problem with movefd(), that
it would always move its argument, even if it was already >=10. The
first hunk of the patch to exec.c depends on my previous patch that
added the NO_MULTIOS option. If you haven't applied that patch, you'll
have to apply this hunk by hand.
-zefram
*** Src/exec.c.1.8 1995/07/24 11:52:50
--- Src/exec.c 1995/08/18 00:39:18
***************
*** 938,944 ****
if (!mfds[fd1] || isset(NOMULTIOS)) {
if(!mfds[fd1]) { /* starting a new multio */
mfds[fd1] = (struct multio *) alloc(sizeof(struct multio));
! if (!forked && fd1 != fd2 && fd1 < 10)
save[fd1] = movefd(fd1);
}
redup(fd2, fd1);
--- 938,944 ----
if (!mfds[fd1] || isset(NOMULTIOS)) {
if(!mfds[fd1]) { /* starting a new multio */
mfds[fd1] = (struct multio *) alloc(sizeof(struct multio));
! if (!forked && fd1 != fd2 && fd1 < 10 && save[fd1] == -1)
save[fd1] = movefd(fd1);
}
redup(fd2, fd1);
***************
*** 1323,1336 ****
if (nullexec && fn->fd1 == 0 && isset(SHINSTDIN) && interact)
init_io();
} else if (fn->type == CLOSE) {
! if (!forked && fn->fd1 < 10)
save[fn->fd1] = movefd(fn->fd1);
closemn(mfds, fn->fd1);
close(fn->fd1);
} else if (fn->type == MERGE || fn->type == MERGEOUT) {
if (fn->fd2 == FD_COPROC)
fn->fd2 = (fn->type == MERGEOUT) ? coprocout : coprocin;
! closemn(mfds, fn->fd1);
fil = dup(fn->fd2);
if (fil == -1) {
char fdstr[4];
--- 1323,1342 ----
if (nullexec && fn->fd1 == 0 && isset(SHINSTDIN) && interact)
init_io();
} else if (fn->type == CLOSE) {
! if (!forked && fn->fd1 < 10 && save[fn->fd1] == -1)
save[fn->fd1] = movefd(fn->fd1);
closemn(mfds, fn->fd1);
close(fn->fd1);
} else if (fn->type == MERGE || fn->type == MERGEOUT) {
if (fn->fd2 == FD_COPROC)
fn->fd2 = (fn->type == MERGEOUT) ? coprocout : coprocin;
! else if(mfds[fn->fd2] && mfds[fn->fd2]->ct > 1) {
! /* This code `knows' about the internals of multios. */
! int rf = mfds[fn->fd2]->rflag;
!
! closemn(mfds, fn->fd2);
! addfd(forked, save, mfds, fn->fd2, fn->fd2, rf);
! }
fil = dup(fn->fd2);
if (fil == -1) {
char fdstr[4];
*** Src/utils.c.1.7 1995/08/09 04:02:26
--- Src/utils.c 1995/08/17 23:42:28
***************
*** 874,886 ****
{
int fe;
! if (fd == -1)
return fd;
#ifdef F_DUPFD
fe = fcntl(fd, F_DUPFD, 10);
#else
! if ((fe = dup(fd)) < 10)
! fe = movefd(fe);
#endif
close(fd);
return fe;
--- 874,885 ----
{
int fe;
! if (fd == -1 || fd >= 10)
return fd;
#ifdef F_DUPFD
fe = fcntl(fd, F_DUPFD, 10);
#else
! fe = movefd(dup(fd));
#endif
close(fd);
return fe;
-----BEGIN PGP SIGNATURE-----
Version: 2.6.i
iQBVAgUBMDPk8GWJ8JfKi+e9AQEVcgH8DyOFwRZ+0xOzkRtYIK8vLiFwFHSuT+3l
zO4mJvKAXFrCjW0D8Ar6lTNoICtmRK6Nw/FLO0MEtrfr6e2d6ssAvQ==
=IwS7
-----END PGP SIGNATURE-----
Messages sorted by:
Reverse Date,
Date,
Thread,
Author