bernsten@phoenix.Princeton.EDU (Dan Bernstein) (05/04/89)
> Should file descriptor 3 be, by new convention, /dev/tty?
The survey results are in, and they send clear messages to AT&T and
to Berkeley:
AT&T: Why does v8/v9 have fd 3 as another name for /dev/tty? There is
very little interest in or use for it. Those few applications that want
/dev/tty can open it themselves. You might make some people happy by
having a ``standard command input'' instead.
BERKELEY: Programmers *expect* that /dev/tty can be opened at any time.
But some BSD changes make this untrue. Make sure that it is true in
future releases. (Start by letting /dev/tty be opened while EXCL is set.)
I received responses from 26 people. Apologies for any errors in this list.
pdb@SEI.CMU.EDU (Patrick Barron)
flee@shire.cs.psu.edu (Felix Lee)
haahr@bogey.princeton.edu (Paul Haahr)
mark%jhereg@src.honeywell.com (Mark Colburn)
bes%holin%mtune@att.att.com (Bradley Smith)
ficc!peter@uunet.UU.NET (Peter da Silva)
vlb@apple.com (Vicki Brown)
taux01!amos@nsc.nsc.com (Amos Shapir)
att!pegasus!hansen (Tony)
n3dmc!johnl@uunet.UU.NET (John Limpert)
att!cbosgd!alice!andrew
sneaky!gordon@texbell.swbt.com (Gordon Burditt)
ki4pv!cdis-1!tanner@ucf-cs.ucf.edu (T. Andrews)
tbl@apollo.com
@RELAY.CS.NET:andrew%frip.wv.tek.com@tektronix.tek.com (Andrew Klossner)
jfc@ATHENA.MIT.EDU (John Carr)
hznx@vax5.CCS.CORNELL.EDU (Dan Dulitz)
auspex!auspex.com!guy@uunet.UU.NET (Guy Harris)
gwyn@BRL.MIL (Doug Gwyn)
arnold@mathcs.emory.edu (Arnold Robbins)
talos!kjones@uunet.UU.NET (Kyle Jones)
sco!seanf@ucscc.UCSC.EDU (Sean Fagan)
jbuck@epimass.epi.com (Joe Buck)
bzs@bu-cs.BU.EDU (Barry Shein)
@pucc:brossard%litsun2.epfl.ch@CLSEPF51.bitnet (Alain Brossard)
nazgul@apollo.com (Kee Hinckley)
The responses can be broken down as follows:
3 It's already in AT&T's v8/v9
2 Yes, a standard command-input stream would be useful
1 Why not?
4 Why?
3 No, but a standard command-input stream would be useful
11 No
The basic problem here is that ``control terminal'' is a fundamental
part of a process state, deemed important enough to have an entry in
the u area but not important enough to have easy user-level access.
Rather than having ioctls doing the dirty work, there should be
explicit system calls to detach from, attach to, and gain a file
descriptor for control terminals. In general u area information is
accessible through system calls, and only non-process state information
is relegated to device drivers and ioctls; I don't see why ttys are
handled differently.
Soapbox aside, below is a discussion of each point brought up.
Parenthesized numbers indicate the frequency of each argument.
(5) What do you do with processes having no control terminal: The easy
answer is to have fd 3 be closed. When you reattach, you reopen fd 3.
(8) You can open /dev/tty in any case, and the extra effort necessary
is negligible: If it were always possible to open /dev/tty, this would
be a valid argument, but in current BSD releases many special features
(TIOCEXCL being the one where this most annoys me) eliminate the ability
to open /dev/tty. If this is fixed, then I'll agree that there's no
point of making fd 3 be /dev/tty.
(5) Many programs, and the SVID, assume that a program starts with
exactly fds 0, 1, and 2 open: This is a valid argument against
writing bad code and against the SVID. Seriously, any change that
breaks old programs (and standards) should be considered carefully.
Listen, AT&T!
(6) Having an extra file descriptor for ``command input'' would be
useful if it is redirectable: I agree completely and would love
the subsequent simplification in more, awk, make, etc. Under the
current one-input two-output model, it is simply impossible to
write a ``standard'' program to interleave two inputs. Changing
the standard model to two-input two-output is a potentially very
useful generalization.
(3) v8/v9 already has fd 3 as /dev/tty: Why? AT&T, if you want
to make this change, go all the way and accompany stdin, stdout,
and stderr with cmdin. Don't make a non-redirectable file descriptor
for what's already in the name space.
(2) Don't waste a file descriptor: Very few programs would suffer
from this waste.
(2) Use stderr for /dev/tty like some versions of more do: stderr
is redirected very often, and it may not be readable.
(1) Use stderr for cmdin, and make it readable: If stderr is
redirected, it is rarely to the same place as where you want
command input from. It doesn't make sense to force input and
output to be the same place.
(1) Since fd 3 can be redirected, it is insecure for programs like
passwd, su, etc. to trust fd 3 to be /dev/tty: Since the advent
of pseudo-terminals this argument has been moot.
(1) ``If fd 0 isn't a terminal the program shouldn't ask any more
questions'': Say goodbye to more.
(2) Standard errors could go anywhere, not just /dev/tty: The
two people who made this argument thought I was asking ``should fd 2
be /dev/tty?'' Nobody's proposing changing stderr.
In summary, *if* it is always possible to open /dev/tty, people don't
really need it as a file descriptor. It may be useful to change the
basic model of stdin-stdout-stderr to stdin-stdout-stderr-cmdin,
although that wasn't the original question.
---Dan Bernstein, bernsten@phoenix.princeton.edu
snoopy@sopwith.UUCP (Snoopy) (05/05/89)
In article <8123@phoenix.Princeton.EDU> bernsten@phoenix.Princeton.EDU (Dan Bernstein) writes: |(6) Having an extra file descriptor for ``command input'' would be |useful if it is redirectable: I agree completely and would love |the subsequent simplification in more, awk, make, etc. Under the |current one-input two-output model, it is simply impossible to |write a ``standard'' program to interleave two inputs. Changing |the standard model to two-input two-output is a potentially very |useful generalization. | |(3) v8/v9 already has fd 3 as /dev/tty: Why? AT&T, if you want |to make this change, go all the way and accompany stdin, stdout, |and stderr with cmdin. Don't make a non-redirectable file descriptor |for what's already in the name space. Can I insert my pet peeve here? There is also a need for a standard auxiliary output. stderr is often pressed into service for non-error output. I claim that this is a bad thing. It is a pain to scan through verbose output checking for error messages. There should be a standard place to send a 2nd data stream seperate from the error messages. I run into this problem much more frequently than the case of needing two input streams. A second input stream could be useful for other things besides commands, perhaps call it auxin? So, how about: stdin, auxin, stdout, stderr, and auxout ? _____ /_____\ Snoopy "My dot-matrix does Postscript." /_______\ |___| tekecs.gwd.tek.com!sopwith!snoopy qiclab!sopwith!snoopy |___| sun!nosun!illian!sopwith!snoopy parsely!sopwith!snoopy
bzs@bu-cs.BU.EDU (Barry Shein) (05/06/89)
>Can I insert my pet peeve here? There is also a need for a standard >auxiliary output. stderr is often pressed into service for non-error >output. I claim that this is a bad thing. It is a pain to scan through >verbose output checking for error messages. There should be a standard >place to send a 2nd data stream seperate from the error messages. >I run into this problem much more frequently than the case of needing >two input streams. I think we're missing the spirit here and getting too literal minded (ie. that some messages sent to stderr aren't errors, that isn't exactly why it was called stderr.) It would probably be better to just write programs to use some sort of character tag at the beginning so you could de-mux the different types of messages at the other end with grep rather than reworking all of Unix to solve this problem. Granted that doesn't help with previously written code you can't change. TWENEX used some sort of chars like % for informatory, # for error or some such thing (but, of course, they didn't have pipes or grep so it wasn't as handy as it might be in a unix program.) -- -Barry Shein, Software Tool & Die There's nothing more terrifying to hardware vendors than satisfied customers.
mike@thor.acc.stolaf.edu (Mike Haertel) (05/07/89)
>In article <8123@phoenix.Princeton.EDU> bernsten@phoenix.Princeton.EDU (Dan Bernstein) writes: >|(3) v8/v9 already has fd 3 as /dev/tty: Why? AT&T, if you want >|to make this change, go all the way and accompany stdin, stdout, >|and stderr with cmdin. Don't make a non-redirectable file descriptor >|for what's already in the name space. v9 has a /dev/tty which is just a link to /dev/fd/3. When v9 programs need to get at the terminal, I bet they just open /dev/tty like on any other version of Unix. One good reason to implement /dev/tty this way is that /dev/tty is a pretty weird device driver with an incestuous relationship to other data structures in the kernel. /dev/fd/ has a similar problem. By implementing /dev/tty as a link to /dev/fd/3 the v9 people were able to reduce the count of ugly incestuous drivers to 1. Another advantage is that one can redirect descriptor 3 to fool programs that stupidly insist on talking to /dev/tty. With streams you can even give them a working tty ioctl interface . . . -- Mike Haertel <mike@stolaf.edu> main() ??< printf("hello, world??/n"); ??>
andrew@alice.UUCP (Andrew Hume) (05/07/89)
give me a break. can't find the error messages in stderr because of all the other stuff? oh dear. why not put all the crap on some other file descriptor and let stderr be what it should be? that's why we have stdout and stderr; so we don't have to do this horseshit on stdout. luckily the solution for stdout works for stderr; don't multiplex.
dmr@alice.UUCP (05/07/89)
The survey for which Bernstein gives the results (8123@phoenix.Princeton.EDU) has slid off our netnews directory, but the answers seem to suggest misconceptions about the way /dev/tty works in the Ninth Edition system. Since our scheme seems to work conveniently, and differently from most other contemporary systems, I'll describe it. However, since I don't remember the question that was originally asked, this may not answer it. In V9, there are special files named /dev/fd/0, /dev/fd/1 etc. They do not have devices associated with them; instead opening one of them causes an internal dup(2) of the corresponding already-open file. For convenience, /dev/stdin is linked to /dev/fd/0 and so things like `cmd | cat hdr /dev/stdin trlr' can be used without having to put special conventions (like a `-' argument) into commands. /dev/tty is linked to /dev/fd/3, and the programs that create login sessions make file descriptor 3 refer to the terminal just like descriptors 0,1,2. (The standard such program is /etc/init, but there are also the network connection acceptors). Inheritance of file 3 takes place by the usual mechanism. The advantage of the scheme is that the notion of `controlling terminal' can be mostly removed from the kernel. By an explicit request, a process may ask that it become a process group leader, and that any signals generated by a particular stream should be sent to its process group. However, a process does not need to remember this stream. We keep it for convenience (it is printed by ps) but the information isn't used in the kernel. The notion of /dev/tty is a peculiar one, because programs are run in many environments, and programs have their own ideas of what they want. The essence is a way of getting to the user's terminal in spite of I/O redirection; for example, as a matter of policy, programs that read passwords should strongly encourage people to type them in directly rather than storing them in files. However, programs run in the background (for example with &, or via cron or at) may not have a terminal in any useful sense. Our scheme of making the descriptor for the terminal merely one of the several conventionally-available ones has, on balance, given rise to fewer surprises and misbehaviors than previous attempts that wired the notion into the kernel. Such surprises as do occur can be debugged and understood by tools and reasoning already familiar to users, and don't depend on special kernel algorithms that determine the meaning of /dev/tty. Many Unix variants exhibit peculiar behaviors when /dev/tty is tied to a special association of a control terminal and a process (for example, non-working signals when you reuse an incoming line with an old process on it, or a daemon process taking over your terminal line.) At the same time, we're aware that one can view this scheme as yet another step in an infinite regress--perhaps in a couple of years people will learn that file 3 can be redirected too, and we might need file 4 to really, REALLY refer to the terminal. The fact that file descriptor 3 was picked was a matter of choosing a convenient convention. Indeed, at first we used the largest permitted file descriptor. Because this varied, it seemed simpler to switch to the lowest free descriptor. Dennis Ritchie att!research!dmr dmr@research.att.com