zsh-workers
 help / color / mirror / code / Atom feed
* All sorts of file-descriptor strangeness
@ 1999-10-05  9:45 Bart Schaefer
  1999-10-10  8:27 ` PATCH: 3.0.6/3.1.6: " Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 1999-10-05  9:45 UTC (permalink / raw)
  To: zsh-workers

A very long time ago, I wrote:

} From the PS1 prompt,
} 
}         read -eu0k1
} 
} reads a line from the terminal and echoes back the first character.
} However, if instead I redirect input to read like so:
} 
}         repeat 3 print x y z | read -eu0k1
} 
} then nothing is read.  I have to use
} 
}         repeat 3 print x y z | read -eu0k 1
} 
} to get the desired behavior.  Why does the source of the input affect
} the option parsing?

Of course the source of the input doesn't really affect the option parsing.
Rather, it affects whether a byte can be read from file descriptor 1.

Zsh's generic option parser grabs "-eu0k1" and sets values in the `ops'
array ops['e'], ops['u'], ops['0'], ops['k'], ops['1'].  The problem is,
it loses all the ordering information -- so when /bin/read comes along
and counts backwards from 9 checking ops['9'], ops['8'], and so on to
get the argument to the 'u' option, it finds ops['1'] before ops['0'].
The result is that "-eu0k1" is parsed as "-eu1k".  When stdin is the
terminal, stdout is a read/write descriptor and reading from it is the
same as reading stdin; but when stdin is the pipe, stdout is write-only,
and so read fails.

While thinking about what, if anything other than documentation, to do
about this, it occurred to me that -u can only refer to FDs 0 through 9,
because it depends on being able to use a single-character index into
ops[].  This sent me rambling into the parsing of >& and <& redirections,
and on a hunt through the ChangeLog, both of which produced startling
revelations.

For one thing, did you know that back in January of 1996, Zoltan added
the "&>" operator to zsh?  It is both undocumented and exceptionally
inconsistent in its behavior, and I'm still not precisely sure what it
is supposed to do.  If it's the first redirection after starting "zsh -f":

	zagzig% echo 1&>3
	1
	zagzig% 

This has now created an empty file named "3" and echoed "1\n" to stdout.
But if next I do this:

	zagzig% echo 22>&1
	22
	zagzig% echo 1&>3
	zagzig% 

Now suddenly the file "3" contains "1\n" -- completely ignoring noclobber,
I may add.  I don't know what's magic about the >&1, but from then on the
&> operator acts just like >|.

Let's talk about that 22>&1 for a moment.  The number on the left side of
an >& or <& must be a single digit, or zsh treats it as a separate word
and not as part of the redirection.  The number on the right, on the other
hand, can be as many digits long as you like, and can even have whitespace
in front of it, and still zsh happily converts it to an integer and tries
to dup() it.  This usually simply prints "bad file number" -- but if you
happen to hit one of the descriptors that movefd() has allocated, you can
produce some strange effects, usually ending with a sudden exit.

Finally, I'm pretty sure that it's something like this >&1 mystery that
causes the "coproc" descriptor leakage that I described in a previous
message to zsh-users.  Examining "ls -l /proc/$$/fd" I discovered that

	zagzig% echo >&1
	zagzig% coproc tr a-z A-Z

produces FOUR new descriptors: 3 (from "echo >&1"), 11, 13, and 14.  FD
11 is the coproc output, but both 13 and 14 are the coproc input!  From
this point forward, every time a coproc is created it gets an extra dup
of its input descriptor.  (There doesn't seem to be anything I can do
with 3; "echo >> /proc/$$/fd/3" produces "permission denied" and putting
3 on the right of an >& or <& produces "bad file descriptor".)

I'm pretty sure all this has something to do with addfd(), based on this
comment from exec.c (carats my emphasis):

/* Add a fd to an multio.  fd1 must be < 10, and may be in any state. *
 * fd2 must be open, and is `consumed' by this function.  Note that   *
 * fd1 == fd2 is possible, and indicates that fd1 was really closed.  *
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 * We effectively do `fd2 = movefd(fd2)' at the beginning of this     *
 * function, but in most cases we can avoid an extra dup by delaying  *
 * the movefd: we only >need< to move it if we're actually doing a    *
 * multiple redirection.                                              */

Note that >&1 is the same as 1>&1, which might cause addfd() to believe
that the descriptor was closed when really it has not been.  I haven't
stepped there with a debugger yet, and it's 2:30 AM here so I think I'm
going to give up for now; but I will say that it happens whether or not
the multios option is set.  (Same for the &> oddness.)

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-05  9:45 All sorts of file-descriptor strangeness Bart Schaefer
@ 1999-10-10  8:27 ` Bart Schaefer
  1999-10-10 13:35   ` Zefram
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 1999-10-10  8:27 UTC (permalink / raw)
  To: zsh-workers

On Oct 5,  9:45am, Bart Schaefer wrote:
} Subject: All sorts of file-descriptor strangeness
}
} For one thing, did you know that back in January of 1996, Zoltan added
} the "&>" operator to zsh?  It is both undocumented and exceptionally
} inconsistent in its behavior, and I'm still not precisely sure what it
} is supposed to do.

It's supposed to mean exactly the same thing as ">&" when no descriptor
numbers are provided; that is, both ">& foo" and "&> foo" are shorthand
for "> foo 2>&1", with the single difference that the right-hand-side of
"&>" is always treated as a file name, never as a descriptor number.  A
doc patch for this is below.

">& foo" is a csh-ism that zsh has always supported; I don't know where
"&>" came from (ksh?), but it appears that it has always been broken.

} If it's the first redirection after starting "zsh -f":
} 
} 	zagzig% echo 1&>3
} 	1
} 
} This has now created an empty file named "3" and echoed "1\n" to stdout.
} 
} 	zagzig% echo 22>&1
} 	22
} 	zagzig% echo 1&>3
} 	zagzig% 
} 
} Now suddenly the file "3" contains "1\n" -- completely ignoring noclobber,
} I may add.  I don't know what's magic about the >&1, but from then on the
} &> operator acts just like >|.

First, let me say that I was confused about noclobber.  It wasn't ignored,
it simply wasn't set in the first place.

Wiping the egg out of my eyes, I compared strace output before and after
"echo >&1" and discovered that the first "echo 1 &>3" was behaving as if
it were "echo 1 0>&3", while the second acted like "echo 1 1>&3".  Come
tiptoe through the lexer with me:  At the top of gettok(), on redirects
beginning with '>' or '<', the local `peekfd' is set to the number that
precedes the redirection as a single digit --

} Let's talk about that 22>&1 for a moment.  The number on the left side of
} an >& or <& must be a single digit, or zsh treats it as a separate word
} and not as part of the redirection.

-- and then later when the redirect operator has been lexed, the global
`tokfd' is set to `peekfd', which is -1 if there was no digit.  Over in
the parser, upon getting a redirection token, par_redir() is called to
copy `tokfd' into the `struct redir' that goes in the argument list.

None of this, however, happens for "&>", so `tokfd' has whatever value
was left over the last time a redirection operator was parsed!  Thus the
"real" meaning of &> is (was) to redirect both stderr _and_ whatever FD
had most recently been redirected (initally stdin!) to the file named on
the RHS.  As I'm relatively sure this is a bug, a patch is appended (the
lex.c hunk).

Returning to other redirections:

} The number on the right, on the other
} hand, can be as many digits long as you like, and can even have whitespace
} in front of it, and still zsh happily converts it to an integer and tries
} to dup() it.

The doc patch also changes "digit" to "number" in strategic spots to imply
this without calling much attention to it.

} This usually simply prints "bad file number" -- but if you
} happen to hit one of the descriptors that movefd() has allocated, you can
} produce some strange effects, usually ending with a sudden exit.

This turns out to be overstated.  You can produce strange effects, but they
don't inherently cause the shell any problems, because the dup-ing always
goes from the RHS to the LHS -- so although you can grab a copy of a one
of the internal file descriptors, the worst thing you can do with it is
clobber one or more of stdin/out/err with it.  So no fix is needed here.

} Finally, I'm pretty sure that it's something like this >&1 mystery that
} causes the "coproc" descriptor leakage that I described in a previous
} message to zsh-users.  [...]
} 
} I'm pretty sure all this has something to do with addfd(), based on this
} comment from exec.c (carats my emphasis):
} 
}  * fd1 == fd2 is possible, and indicates that fd1 was really closed.  *
}    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

This was a red herring.  The coproc input descriptor is _always_ leaked;
I'm puzzled as to why this doesn't always cause the coproc to fail to see
end-of-file; it's probably just that zsh sometimes stomps on the leaked
descriptor itself, because it doesn't know that it's still "in use."  It
is, however, a good idea to avoid descriptor leakage, so a patch for this
is also included (the exec.c hunk).

I can't find any reason why opipe[0] should not be closed at that point,
as zsh otherwise completely forgets that it exists.  Maybe some obscure
system has a bug that causes the coproc to get EOF premturely in that case?
If you know or find this to be true, please try to send us an appropriate
#ifdef and comment for this spot.

Off we go ... for 3.0.6, simply ignore the redirect.yo hunk.

Index: Doc/Zsh/redirect.yo
===================================================================
@@ -77,10 +77,10 @@
 Perform shell expansion on var(word) and pass the result
 to standard input.  This is known as a em(here-string).
 )
-xitem(tt(<&) var(digit))
-item(tt(>&) var(digit))(
+xitem(tt(<&) var(number))
+item(tt(>&) var(number))(
 The standard input/output is duplicated from file descriptor
-var(digit) (see manref(dup)(2)).
+var(number) (see manref(dup2)(2)).
 )
 xitem(tt(<& -))
 item(tt(>& -))(
@@ -90,8 +90,10 @@
 item(tt(>& p))(
 The input/output from/to the coprocess is moved to the standard input/output.
 )
-item(tt(>&) var(word))(
-Same as `tt(>) var(word) tt(2>&1)'.
+xitem(tt(>&) var(word))
+item(tt(&>) var(word))(
+Same as `tt(>) var(word) tt(2>&1)'.  Note that with tt(&>), var(word) is
+never interpreted as a file descriptor, even if it is a number.
 )
 item(tt(>>&) var(word))(
 Same as `tt(>>) var(word) tt(2>&1)'.
Index: Src/exec.c
===================================================================
@@ -877,8 +877,10 @@
     if (how & Z_ASYNC) {
 	lastwj = newjob;
 	jobtab[thisjob].stat |= STAT_NOSTTY;
-	if (l->flags & PFLAG_COPROC)
+	if (l->flags & PFLAG_COPROC) {
 	    zclose(ipipe[1]);
+	    zclose(opipe[0]);
+	}
 	if (how & Z_DISOWN) {
 	    deletejob(jobtab + thisjob);
 	    thisjob = -1;
Index: Src/lex.c
===================================================================
@@ -642,6 +642,7 @@
 	    }
 	    hungetc(d);
 	    lexstop = 0;
+	    tokfd = -1;
 	    return AMPOUTANG;
 	}
 	hungetc(d);

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-10  8:27 ` PATCH: 3.0.6/3.1.6: " Bart Schaefer
@ 1999-10-10 13:35   ` Zefram
  1999-10-10 15:54     ` Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Zefram @ 1999-10-10 13:35 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

Bart Schaefer wrote:
>                      that is, both ">& foo" and "&> foo" are shorthand
>for "> foo 2>&1",

Not the main topic of this thread, but that's not quite true.  It *used*
to be that way, until someone pointed out that this gave ">& foo" the
wrong behaviour with multios.  Now >& (and &>) are handled specially:
they redirect both stdout (or other specified fd) and stderr to the
specified file.  More precisely, ">& foo" has the behaviour of "9>
foo >&9 2>&9 9>&-", where "9" is any spare file descriptor.  You can
see the difference thus:

% { echo out; echo err >&2; } > foo >& bar

This puts "out" into foo and bar, but "err" into bar only.  Replacing ">&
bar" with "> bar 2>&1" gives you "out" and "err" in both files.

The documentation needs to be fixed (patch to follow).

>} The number on the right, on the other
>} hand, can be as many digits long as you like, and can even have whitespace
>} in front of it, and still zsh happily converts it to an integer and tries
>} to dup() it.
...
>                                so although you can grab a copy of a one
>of the internal file descriptors, the worst thing you can do with it is
>clobber one or more of stdin/out/err with it.  So no fix is needed here.

This is something I've always been dubious about.  One of the things I
planned to do in my CFT was to implement a syntax allowing redirection of
arbitrary file describtors, rather than just fds 0 to 9.  A consequential
requirement would be that the shell gets its private fds out of the way
whenever the user refers to a specific fd number, so this phenomenon
of the shell's fds becoming visible to the user would never occur.
I designed the Elate shell to do this from the very start -- it's not
hard -- but there are some nasty issues involved in retrofitting it to
a shell not designed that way.

I think it would be better to enforce a strict distinction between the
user's fds and the shell's.  Since the situation at the moment is that
fds 0 to 9 are the user's, I think fds on the RHS of a dup redirection
should be limited to this range.  (Patch to follow.)

-zefram


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

* PATCH: no more fd mixups
@ 1999-10-10 14:35 Zefram
  0 siblings, 0 replies; 10+ messages in thread
From: Zefram @ 1999-10-10 14:35 UTC (permalink / raw)
  To: zsh-workers

This patch prevents the user from duping the shell's private file
descriptors (deemed to be fds 10 and above).  I had to do a slight hack
to allow the coprocess file descriptors to be duped, but the extra logic
for that incidentally made it easy to improve the error message for
"<&p" where there is no coprocess.

-zefram

diff -cr ../zsh-/Src/exec.c Src/exec.c
*** ../zsh-/Src/exec.c	Sun Oct 10 14:38:24 1999
--- Src/exec.c	Sun Oct 10 15:21:05 1999
***************
*** 1907,1920 ****
  	    case MERGEOUT:
  		if(fn->fd2 < 10)
  		    closemn(mfds, fn->fd2);
! 		fil = dup(fn->fd2);
  		if (fil == -1) {
  		    char fdstr[4];
  
  		    closemnodes(mfds);
  		    fixfds(save);
! 		    sprintf(fdstr, "%d", fn->fd2);
! 		    zerr("%s: %e", fdstr, errno);
  		    execerr();
  		}
  		addfd(forked, save, mfds, fn->fd1, fil, fn->type == MERGEOUT);
--- 1907,1929 ----
  	    case MERGEOUT:
  		if(fn->fd2 < 10)
  		    closemn(mfds, fn->fd2);
! 		if(fn->fd2 > 9) {
! 		    fil = -1;
! 		    errno = EBADF;
! 		} else {
! 		    int fd = fn->fd2;
! 		    if(fd == -2)
! 			fd = (fn->type == MERGEOUT) ? coprocout : coprocin;
! 		    fil = dup(fd);
! 		}
  		if (fil == -1) {
  		    char fdstr[4];
  
  		    closemnodes(mfds);
  		    fixfds(save);
! 		    if(fn->fd2 != -2)
! 		    	sprintf(fdstr, "%d", fn->fd2);
! 		    zerr("%s: %e", fn->fd2 == -2 ? "coprocess" : fdstr, errno);
  		    execerr();
  		}
  		addfd(forked, save, mfds, fn->fd1, fil, fn->type == MERGEOUT);
diff -cr ../zsh-/Src/glob.c Src/glob.c
*** ../zsh-/Src/glob.c	Sun Oct 10 14:38:24 1999
--- Src/glob.c	Sun Oct 10 15:21:23 1999
***************
*** 1580,1586 ****
  	    if (s[0] == '-' && !s[1])
  		fn->type = CLOSE;
  	    else if (s[0] == 'p' && !s[1]) 
! 		fn->fd2 = (fn->type == MERGEOUT) ? coprocout : coprocin;
  	    else {
  		while (idigit(*s))
  		    s++;
--- 1580,1586 ----
  	    if (s[0] == '-' && !s[1])
  		fn->type = CLOSE;
  	    else if (s[0] == 'p' && !s[1]) 
! 		fn->fd2 = -2;
  	    else {
  		while (idigit(*s))
  		    s++;
END


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

* Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-10 13:35   ` Zefram
@ 1999-10-10 15:54     ` Bart Schaefer
  1999-10-10 16:39       ` PATCH: Re: PATCH: no more fd mixups Bart Schaefer
  1999-10-10 17:41       ` Zefram
  0 siblings, 2 replies; 10+ messages in thread
From: Bart Schaefer @ 1999-10-10 15:54 UTC (permalink / raw)
  To: Zefram; +Cc: zsh-workers

On Oct 10,  2:35pm, Zefram wrote:
} Subject: Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangen
}
} Bart Schaefer wrote:
} >} The number on the right, on the other hand, can be as many digits
} >} long as you like, and can even have whitespace in front of it, and
} >} still zsh happily converts it to an integer and tries to dup() it.
} 
} I think it would be better to enforce a strict distinction between the
} user's fds and the shell's.  Since the situation at the moment is that
} fds 0 to 9 are the user's, I think fds on the RHS of a dup redirection
} should be limited to this range.  (Patch to follow.)

I thought about this and was on the verge of adding it to the patch that
I sent, but it's tickling my memory that zsh did restrict RHS FDs to one
digit at some time in the distance past until someone pointed out exactly
this:

} > [...] although you can grab a copy of a one of the internal file
} >descriptors, the worst thing you can do with it is clobber one or
} >more of stdin/out/err with it.

At which point it was changed to allow arbitrary numbers, in case some
other process used to start up a shell script leaves open a FD outside
the 0-9 range that the shell script is supposed to grab for I/O.  (True,
this wouldn't work with any other shell, but it lets zsh stand in for a
compiled program in cases where other shells can't.)

Unfortunately whatever discussion there was about this predates the
existing zsh-workers archives.  Are the old zsh-list archives still on
the net anywhere, or did they get permanently clobbered when gatech
took down Richard's FTP site?

Anyway, I'm inclined to leave it as it is, with one possible change:

} A consequential requirement would be that the shell gets its private
} fds out of the way whenever the user refers to a specific fd number,
} so this phenomenon of the shell's fds becoming visible to the user
} would never occur.

If we continue to limit the FDs on the LHS to 0-9, then we can simply
report EBADF whenever one of the "private" FDs appears on the RHS.

I'd further point out that with the /proc/*/fd filesystem available, the
shell would have to go to nearly impossible lengths to prevent its private
FDs from becoming visible; the best it can do is to keep them from being
stomped on, which it already is doing.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* PATCH: Re: PATCH: no more fd mixups
  1999-10-10 15:54     ` Bart Schaefer
@ 1999-10-10 16:39       ` Bart Schaefer
  1999-10-10 17:53         ` Zefram
  1999-10-10 17:41       ` Zefram
  1 sibling, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 1999-10-10 16:39 UTC (permalink / raw)
  To: zsh-workers

On Oct 10,  3:35pm, Zefram wrote:
} Subject: PATCH: no more fd mixups
}
} This patch prevents the user from duping the shell's private file
} descriptors (deemed to be fds 10 and above).

On Oct 10,  3:54pm, Bart Schaefer wrote:
} Subject: Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangen
}
} If we continue to limit the FDs on the LHS to 0-9, then we can simply
} report EBADF whenever one of the "private" FDs appears on the RHS.

Here's a tweak to Zefram's patch to really limit the descriptors to those
in use by the shell.  The substantive change is only to throw in the test
that the descriptor is in the fdtable[] array, but I took the liberty of
changing some old no-space-between-`if'-and-`(' style to the style now in
wider use in the zsh code.

Index: Src/exec.c
===================================================================
RCS file: /extra/cvsroot/zsh/zsh-3.1/Src/exec.c,v
retrieving revision 1.62
diff -u -r1.62 exec.c
--- exec.c	1999/10/10 16:29:06	1.62
+++ exec.c	1999/10/10 16:29:56
@@ -1906,9 +1906,9 @@
 		break;
 	    case MERGEIN:
 	    case MERGEOUT:
-		if(fn->fd2 < 10)
+		if (fn->fd2 < 10)
 		    closemn(mfds, fn->fd2);
-		if(fn->fd2 > 9) {
+		if (fn->fd2 > 9 && fdtable[fn->fd2]) {
 		    fil = -1;
 		    errno = EBADF;
 		} else {
@@ -1922,7 +1922,7 @@
 
 		    closemnodes(mfds);
 		    fixfds(save);
-		    if(fn->fd2 != -2)
+		    if (fn->fd2 != -2)
 		    	sprintf(fdstr, "%d", fn->fd2);
 		    zerr("%s: %e", fn->fd2 == -2 ? "coprocess" : fdstr, errno);
 		    execerr();

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-10 15:54     ` Bart Schaefer
  1999-10-10 16:39       ` PATCH: Re: PATCH: no more fd mixups Bart Schaefer
@ 1999-10-10 17:41       ` Zefram
  1 sibling, 0 replies; 10+ messages in thread
From: Zefram @ 1999-10-10 17:41 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zefram, zsh-workers

Bart Schaefer wrote:
>If we continue to limit the FDs on the LHS to 0-9, then we can simply
>report EBADF whenever one of the "private" FDs appears on the RHS.

Ah yes, a neat solution.  This is definitely an improvement over my patch,
and doesn't require use to actually shuffle private fds around at all.

>I'd further point out that with the /proc/*/fd filesystem available, the
>shell would have to go to nearly impossible lengths to prevent its private
>FDs from becoming visible;

That's a slightly different matter.  The shell provides a view of a set
of fds which gets passed on to programs run from the shell; this is what
the redirections manipulate.  Conceptually it has no inherent connection
with the actual OS-level fd table of the shell process.  Anyone that
fiddles with /proc/*/fd for a process that they don't actually control
at the fd level is just asking for trouble.

-zefram


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

* Re: PATCH: Re: PATCH: no more fd mixups
  1999-10-10 16:39       ` PATCH: Re: PATCH: no more fd mixups Bart Schaefer
@ 1999-10-10 17:53         ` Zefram
  1999-10-10 21:11           ` PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness Bart Schaefer
  0 siblings, 1 reply; 10+ messages in thread
From: Zefram @ 1999-10-10 17:53 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

Bart Schaefer wrote:
>Here's a tweak to Zefram's patch to really limit the descriptors to those
>in use by the shell.  The substantive change is only to throw in the test
>that the descriptor is in the fdtable[] array,

OK.  One issue: coprocess file descriptors.  Should they (a) be
passed on to child processes, and (b) be dupable by number?  I think
they should be completely private (accessible obly via >&p and <&p),
but more importantly the answers for (a) and (b) should be the same.
At the moment, coprocess fds do not get passed on to children, but they
are explicitly marked as public in fdtable[], and hence after your patch
they are dupable by number.

I *think* all that needs to change is to remove the line

	fdtable[coprocin] = fdtable[coprocout] = 0;

from exec.c (where the coprocess is being opened), but I don't completely
follow the use of fdtable[], so I'll leave it to someone with more time
on their hands.

-zefram


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

* Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-10 17:53         ` Zefram
@ 1999-10-10 21:11           ` Bart Schaefer
  1999-10-11  8:12             ` Zefram
  0 siblings, 1 reply; 10+ messages in thread
From: Bart Schaefer @ 1999-10-10 21:11 UTC (permalink / raw)
  To: zsh-workers

On Oct 10,  6:53pm, Zefram wrote:
} Subject: Re: PATCH: Re: PATCH: no more fd mixups
}
} Bart Schaefer wrote:
} >Here's a tweak to Zefram's patch to [...] test
} >that the descriptor is in the fdtable[] array,
} 
} At the moment, coprocess fds do not get passed on to children, but they
} are explicitly marked as public in fdtable[], and hence after your patch
} they are dupable by number.

Yes, that's true.  While we're on the topic:

zagzig[21] coproc tr a-z A-Z
[1] 2510
zagzig[22] exec 5<&p
zagzig[23] ls -l /proc/self/fd
total 0
lrwx------   1 schaefer schaefer       64 Oct 10 13:48 0 -> [0301]:11232
lrwx------   1 schaefer schaefer       64 Oct 10 13:48 1 -> [0301]:11232
lrwx------   1 schaefer schaefer       64 Oct 10 13:48 2 -> [0301]:11232
lr-x------   1 schaefer schaefer       64 Oct 10 13:48 3 -> [0001]:164691976
lr-x------   1 schaefer schaefer       64 Oct 10 13:48 5 -> [0000]:12364629

Should descriptor 5 have been passed on to "ls" in this manner?  (Note
that /proc/self/fd are the fds of "ls" at that point, not of the shell.)

} I *think* all that needs to change is to remove the line
} 
} 	fdtable[coprocin] = fdtable[coprocout] = 0;

I'm concerned about that because there are other places where the fds with
nonzero entries in fdtable[] are either closed, or deliberately kept open,
in circumstances that may not apply to the coproc.  In particular, I think
it would break this:

    coproc foo
    bar <(baz <&p)
 
Probably it's better to just extend the test we've already tweaked twice
now, so that it explicitly tests the coproc fds as well.

Index: exec.c
===================================================================
@@ -1671,7 +1671,10 @@
 	    case MERGEOUT:
 		if (fn->fd2 < 10)
 		    closemn(mfds, fn->fd2);
-		if (fn->fd2 > 9 && fdtable[fn->fd2]) {
+		if (fn->fd2 > 9 &&
+		    (fdtable[fn->fd2] ||
+		     fn->fd2 == coprocin ||
+		     fn->fd2 == coprocout)) {
 		    fil = -1;
 		    errno = EBADF;
 		} else {

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


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

* Re: PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness
  1999-10-10 21:11           ` PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness Bart Schaefer
@ 1999-10-11  8:12             ` Zefram
  0 siblings, 0 replies; 10+ messages in thread
From: Zefram @ 1999-10-11  8:12 UTC (permalink / raw)
  To: Bart Schaefer; +Cc: zsh-workers

Bart Schaefer wrote:
>zagzig[21] coproc tr a-z A-Z
>[1] 2510
>zagzig[22] exec 5<&p
>zagzig[23] ls -l /proc/self/fd
...
>Should descriptor 5 have been passed on to "ls" in this manner?

Yes.  You explicitly opened fd 5; it should be passed on to child
processes that you create.

>                                                    In particular, I think
>it would break this:
>
>    coproc foo
>    bar <(baz <&p)

Ah.  It probably would.  The coprocess fds are more of a special case
than I realised.

-zefram


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

end of thread, other threads:[~1999-10-11  8:13 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-10-10 14:35 PATCH: no more fd mixups Zefram
  -- strict thread matches above, loose matches on Subject: below --
1999-10-05  9:45 All sorts of file-descriptor strangeness Bart Schaefer
1999-10-10  8:27 ` PATCH: 3.0.6/3.1.6: " Bart Schaefer
1999-10-10 13:35   ` Zefram
1999-10-10 15:54     ` Bart Schaefer
1999-10-10 16:39       ` PATCH: Re: PATCH: no more fd mixups Bart Schaefer
1999-10-10 17:53         ` Zefram
1999-10-10 21:11           ` PATCH: 3.0.6/3.1.6: Re: All sorts of file-descriptor strangeness Bart Schaefer
1999-10-11  8:12             ` Zefram
1999-10-10 17:41       ` 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).