/dev/tty implemented as /dev/fd/3

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Wed Oct 31 20:08:00 AEST 1990


Submitted-by: brnstnd at kramden.acf.nyu.edu (Dan Bernstein)

In article <14162 at cs.utexas.edu> ske at pkmab.se (Kristoffer Eriksson) writes:
> [ I don't quite understand why the submittor wants to split this from the
> thread of Re: File system name space, but let's give it a try and see what
> happens, eh?  -mod ]

It is a different issue. There are objective advantages to eliminating
/dev/tty, kernel controlling terminals, and POSIX sessions: the kernel
becomes noticeably smaller, the POSIX standard becomes several pages
thinner and a lot easier to implement, programmers no longer have to
worry about special system calls to manipulate the tty fd, non-orphaned
processes in orphaned process groups are not killed off unnecessarily,
etc.

Neither SunOS 4.1 nor Ultrix 4.0 correctly implements POSIX sessions.
In particular, both systems chop off access to the original /dev/tty
after a process setsid()s and opens a different controlling terminal.
This is clearly contrary to the intent of POSIX, as expressed in
B.7.1.1.4. It can be proven to be a violation of the standard, as this
removal of access is not defined by either implementation. Note that it
happens only with /dev/tty, not with the actual terminal file; so both
systems are also clearly in violation of the ctermid() definition.

The bugs I just described are solely responsible for the failure of my
pty program under SunOS 4.1 and Ultrix 4.0. (I will post a stopgap patch
by Friday.) If ctermid(), controlling terminals, and POSIX sessions were
not mandated by P1003.1, the Sun and DEC programmers wouldn't have
introduced these bugs into their latest operating systems. Isn't it
obvious that the tty system is a fruitful source of bugs? Shouldn't we
make every effort to simplify this area of UNIX?

v9 could easily adopt fd 3 because it is not a commercial operating
system. It will take a lot more care to introduce similar changes into,
e.g., BSD. I propose the following plan of action:

  1. In the next P1003.1 revision, add a feature test macro for cttys.
     Take *every single sentence in the standard* talking about POSIX
     sessions, cttys, or ctermid(), and make it conditional upon the
     system's optional support for cttys.

  2. Also change the definitions of ``foreground process group'' and
     ``background process group'' in case cttys are not supported. In
     BSD, those terms are relative to the tty you're trying to access.
     In POSIX, they are constant; a process is either in the foreground
     or in the background, depending only on its controlling terminal.
     The new definition would be the same as the old BSD definition.

  3. Add a new device, /dev/stdtty. Opening this device is equivalent to
     dup()ing fd 3. Notice the name ``standard tty''; this is to avoid
     confusion with ``controlling tty.'' stdio should support stdtty as
     well, though (unlike stdin/out/err) stdtty may by convention be
     closed.

  4. Change the few necessary programs (e.g., getty) to support the fd 3
     stdtty convention. In fact, my pty program already supports this
     convention, and the pty package includes patches for telnetd to
     support pty. Adding similar support to getty, rlogind, etc. will be
     just as easy. 

  5. Add a new device, /dev/ctty, equivalent to the current /dev/tty.

  6. Switch /dev/tty to be /dev/stdtty rather than /dev/ctty. See if
     anyone notices.

  7. Turn off the ctty feature, to remain compliant with POSIX.
     Eliminate controlling ttys, POSIX sessions, and so on from the
     kernel. Preserve the old behavior of ps by having it glance at fd 3
     inside the process u area---it already looks around enough in
     kernel memory.

> In article <14103 at cs.utexas.edu> arnold at audiofax.com writes:
> >In general, unless someone went to the trouble, fd 3 will be attached to the
> >terminal, so opening /dev/tty is pretty safe.  Nothing's foolproof; [...]
> >You're no worse off than before when /dev/tty was built into the kernel.
> If you have a program that closes only fd 3, this implementation will behave
> differently from the old /dev/tty device implementation, won't it?

Yes, it will. So what?

> You will
> not be able to reach the controlling terminal by a guaranteed route, in spite
> of the fact that it is still available on other fd-s.

Who cares?

There has not been a ``guaranteed route'' to reach the controlling
terminal, ever since BSD introduced TIOCEXCL. Opening /dev/tty and
sending a TIOCNOTTY down it is not reliable, because /dev/tty may not be
openable. That's right: there is *no* guaranteed way to dissociate from
your controlling terminal. close(3) is a better solution.

Where is this glaring need for a process to find its controlling tty?
Why shouldn't it be easy for the user to control, using the same fd
mechanisms as any other redirection? The argument that ``passwd needs to
talk to the user's tty, reliably'' has been moot ever since pseudo-ttys
appeared.

What is wrong with the concept of a standard tty?

> Or is the controlling
> terminal concept implemented in such a way that closing fd 3 is the same as
> disassociating from the controlling terminal (so you won't be bother with
> terminal interrupts and such) ?

Well, there's no logical association between closing fd 3 and changing
your process group. Dissociating from the controlling terminal takes two
system calls: close(3) and setpgrp(0,0). Attaching to a new one means
open()ing it into fd 3, and then setting process groups appropriately.
There's simply no reason that the ``controlling terminal'' of a process
(whatever that is) should affect the kernel's normal process group
handling.

---Dan

Volume-Number: Volume 22, Number 15



More information about the Comp.std.unix mailing list