[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

protecting shell fds



Es 0.7 introduced a mechanism for protecting file descriptors in use by
the shell, from the effects of dup2() following shell redirections.  As
written, it doesn't work, but part of that is due to an acknowledged bug.

Once the acknowledge bug is repaired, however, it still falls short of what
I had expected in view of the list discussion of the matter, leading me to
think that there has been some confusion over the matter.  I hope people
will pardon me for returning to this tedious discussion, and will have the
patience to read through this unfortunately lengthy message.  The short
version is: line 424 of input.c, "if (fd >= 3) {", should be deleted.

To recap my prior arguments on this, my feeling is that once the shell has
begun reading a stream of commands, that command stream should be invulnerable
to redirection from shell statements.  Es, and other conventional shells,
fail to protect their internal descriptors, so that any yet unbuffered input
will be read from whatever stream the file descriptor happens to point to.
For example, if we execute the following statements from the tty;

 $ es
 ;; cat > e3
 echo say this is e3
 ^D
 ;; exec {<[3] e3}
 ;; cat > e1
 exec {<[0=3]}			# bizarre but useful redirection in e1
 echo say this is e1
 ^D
 ;; . ./e1			# going into e1, tty is current command stream
 say this is e1
 ;; say this is e3		# on return from e1, e3 is now current
 ;; $				# on end of e3, shell exits.

The correct thing, in my mind, is for the shell to separate its command input
stream from the input stream that applications see.  The issue is principally
what happens when the command input stream is unit 0, since that's when the
potential for confusion arises.  When there's a need to redirect unit 0, then
the desired effect is clearly for applications invoked by the shell to see
the redirection.  Even if there were a desire to reach back into the command
stack and switch streams, it wouldn't work reliably because of buffering
effects.

We find, however, that the code in es 0.7 that would shuffle command file
descriptors in the event of a redirection, specifically excludes descriptors
0, 1, and 2, which for my purposes defeats the whole point.  I have in fact
a specific application for which I will need to use a hacked es, as long as
this pointless restriction is in place.  (Descriptors 1 and 2 are not an
issue for me - this shuffling of internal file descriptors is done for the
command input streams, and if command input streams are being opened on units
1 or 2 I believe that's probably an error anyway.)

As a real example, the application where I need this effect is a graphic
front end, that runs rc or es through a pipe.  An X front end was prototyped,
but the application went into production as a simple menu driven tty
interface.  The backend constructs the substance of a menu, writes the
menu to the frontend, which presents it to the user.  When an entry in the
menu is selected, the frontend writes the entry to the backend, which
executes it.

The frontend needs to read the tty, and the applications invoked by the
backend need to read the tty, but the command input stream for the backend
is of course the pipe.  (Also, the backend needs to be interactive, since
the prompts are a critical part of the communication - wish UNIX had some
way to notify the write end of a pipe when a read is blocking on the other
end, VMS has this.)

So, the backend is invoked with unit 0 reading the pipe, and it immediately
reconfigures itself so that 0 reads from the tty.  At present, and including
es 0.7, this requires a hack to the shell source, because the shell
mistakenly allows that redirection to clobber its command input stream.
I can do the hack, but it seems to me that there was general support for
the idea of conceptually separating command input from unit 0.

	Donn Cave, University Computing Services, University of Washington
	donn@cac.washington.edu