Controlling Terminals and Controlling Processes

All of the processes in a session may have a (single) controlling terminal. Upon creation, a session has no controlling terminal; the controlling terminal is established when the session leader first opens a terminal that is not already the controlling terminal for a session, unless the O_NOCTTY flag is specified when calling open(). A terminal may be the controlling terminal for at most one session.

Note

SUSv3 specifies the function tcgetsid(int fd) (prototyped in <termios.h>), which returns the ID of the session associated with the controlling terminal specified by fd. This function is provided in glibc (where it is implemented using the ioctl() TIOCGSID operation).

The controlling terminal is inherited by the child of a fork() and preserved across an exec().

When a session leader opens a controlling terminal, it simultaneously becomes the controlling process for the terminal. If a terminal disconnect subsequently occurs, the kernel sends the controlling process a SIGHUP signal to inform it of this event. We go into further detail on this point in SIGHUP and Termination of the Controlling Process.

If a process has a controlling terminal, opening the special file /dev/tty obtains a file descriptor for that terminal. This is useful if standard input and output are redirected, and a program wants to ensure that it is communicating with the controlling terminal. For example, the getpass() function described in Password Encryption and User Authentication opens /dev/tty for this purpose. If the process doesn’t have a controlling terminal, opening /dev/tty fails with the error ENXIO.

The ioctl(fd, TIOCNOTTY) operation can be used to remove a process’s association with its controlling terminal, specified via the file descriptor fd. After this call, attempts to open /dev/tty will fail. (Although not specified in SUSv3, the TIOCNOTTY operation is supported on most UNIX implementations.)

If the calling process is the controlling process for the terminal, then as for the termination of the controlling process (SIGHUP and Termination of the Controlling Process), the following steps occur:

  1. All processes in the session lose their association with the controlling terminal.

  2. The controlling terminal loses its association with the session, and can therefore be acquired as the controlling process by another session leader.

  3. The kernel sends a SIGHUP signal (and a SIGCONT signal) to all members of the foreground process group, to inform them of the loss of the controlling terminal.