zsh-workers
 help / color / mirror / code / Atom feed
* Redirection Bug II -- It's Back
@ 1995-08-17 21:08 Zefram
  1995-08-18  0:58 ` Zefram
  0 siblings, 1 reply; 2+ messages in thread
From: Zefram @ 1995-08-17 21:08 UTC (permalink / raw)
  To: Z Shell workers mailing list

% echo x >x >&1

The redirection is into the file, one copy only, and is permanent.
"echo x >&1 >x", however, works, doing a normal multio.

I'm not sure what the redirection above ought to do, but it certainly
shouldn't be a permanent redirection.  I'm working on this bug right
now.

As a debugging tool, I'm doing something I did to solve the previous
redirection bug.  I'm using debugging macros in zsh.h that output
debugging information whenever a file-descriptor manipulating function
(e.g. redup) is called.  I find this more helpful than trying to
interpret a strace, particularly as it gives to location of each call.
Does anyone think it would be worth me doing this properly (with
wrapper functions etc., making it portable) and leaving the code
available and #ifdef'ed out?

-zefram


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Redirection Bug II -- It's Back
  1995-08-17 21:08 Redirection Bug II -- It's Back Zefram
@ 1995-08-18  0:58 ` Zefram
  0 siblings, 0 replies; 2+ messages in thread
From: Zefram @ 1995-08-18  0:58 UTC (permalink / raw)
  To: Z Shell workers mailing list

-----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-----


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1995-08-18  1:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1995-08-17 21:08 Redirection Bug II -- It's Back Zefram
1995-08-18  0:58 ` Zefram

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).