Command Line TTY Devices

By | November 21, 2019

If you’re just joining us, this is the second article is a series of introductory articles to the command line. The beginning of the series starts with the article “The Command Line”.

This might seem like an odd place to start. Most articles would probably start with the shell, but the shell is a large subject with a lot of features that we’ll tackle later. Understanding TTY devices and how they are used will make a lot of these features easier to understand later down the line.

To understand how TTY devices are used lets look how they are used by programs. One of the jobs of the Unix operating system is to make everything look like a file. This includes all the computer hardware including TTY devices. From the command line we can find the actual file of the TTY device associated with the shell using the command tty.

$ tty
/dev/pts/0

tty shows in this example that the TTY device file is /dev/pts/0. The who command will show you all the TTY devices being used on the system.

To see how these TTY files are being used, lets look at a minimal program written in the C programming language.

int main(int argc, char *argv[]) {
  return EXIT_SUCCESS; // Return success
}

Although this program doesn’t do anything, there are a few things that are happening behind the scenes. First of all, the operating system opens three files automatically called standard in (STDIN), standard out (STDOUT) and standard error (STDERR). These three files are the entire interface to the terminal. Writing to STDOUT displays on the terminal, reading from STDIN reads from the keyboard and STDERR is usually the same file as STDOUT but not always. These files are the TTY device.

To put all this together, lets have a look at what happens when we open a terminal window like xterm.

  1. A terminal window is created.
  2. A new pseudo TTY device is asked to be created by the system, for example /dev/pts/0. Note that the terminal keeps one side, the master side, of the device.
  3. The shell is started, like bash, with its STDIN, STDOUT and STDERR set to the new TTY device.

The terminal and shell communicate through the TTY device. Anything written to the TTY device file from the shell will display in the terminal window and the terminal window will write keyboard events to the TTY to be later read by the shell. When the shell executes commands it also shares the TTY device file with all its child processes. To show this at work, let’s expand on our previous C program example by making it display “Hello World” and waiting for a key to be pressed using the open files STDIN and STDOUT.

Note, this isn’t how you’d typically write a program. There are a lot more convenient ways of doing this, but I wanted to show the raw writes and reads to and from the standard output and input.

#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  char in;

  // Write "Hello World" to STDOUT. This will display in the terminal.
  write(STDOUT_FILENO, "Hello World\n", 12);

  // Wait and read any key from STDIN when the terminal writes a key event
  // to the TTY device.
  read(STDIN_FILENO, &in, 1);

  return EXIT_SUCCESS; // Return success
}

If you’re feeling savvy, save the above example in a file called hello.c. It can then be compiled it into the program hello and run it as follows:

$ gcc hello.c -o hello
$ ./hello
Hello World

At this point, take a pause for a moment to digest how TTYs work. If things aren’t clear then I’d suggest re-reading this article from the beginning. The TTY is the glue between the shell and the terminal and from here on out it only gets more involved.

Hardware TTYs

When we looked at terminal software, it used a pseudo TTY device which are created by operating system software. If we were to use a dumb terminal or some other kind of physical terminal hardware there are a few differences.

The first difference is the TTY device files are created by hardware drivers and exist with or without the terminal hardware connected to it. All serial ports are an example of this with file names like /dev/ttyS1. More examples of hardware TTY device files are:

/dev/console
/dev/tty0
/dev/ttyS0
/dev/ttyUSB0

The next big differences is the physical hardware doesn’t start up the shell like the software terminal does and it also needs to be configured to match the physical terminal. This is all done with a getty program during start up. The getty program usually doesn’t start a shell right away but rather a login program, on the given TTY device, that will later start the shell on a successful login. The following example would get a login prompt on a dumb terminal connected to the first serial port.

$ agetty /dev/ttyS0 38600 vt100

A More Complicated Use of the TTY

From a terminal on our computer we’re going to look at logging into another computer with ssh. The ssh command connects to an ssh server, sshd, over the internet to another computer. Like a terminal window, sshd will create a pseudo TTY and start a new shell when ssh makes a new connection. Here’s a diagram of the setup.

SSH-TTY-Example.png

When the shell on the remote computer wants to display something in the terminal window it writes to the TTY device with STDOUT. At this point is goes to sshd that sends it to the ssh client over the internet. ssh then writes it to its TTY device which goes to the terminal.

The other way, when a key is pressed the terminal writes it to its TTY which goes to ssh. ssh then sends it to the sshd server that writes it to its TTY device. Now the shell can read the key from STDIN.

This might seem overly complicated, but it allows programs to remain very simple. Looking back at our hello example program, it can be used remotely with ssh with no network functionality added to it at all. Pseudo TTY devices can be used in all sorts of weird and wonderful ways to add functionality to the entire system.

It’s Not Always a TTY Device

The standard files of a program don’t have to be a TTY device file. This will become an important concept when we start looking at the shell. The standard files can be files found on the files system. This is known as redirection. Also the STDOUT of one program can be the STDIN of another programs. This is known as piping. This is how different programs can work together to accomplish almost anything.

You should now have a good grasp on the TTY devices and their uses, it’s now time to move on to “The Command Line Terminal”…

4 thoughts on “Command Line TTY Devices

  1. Pingback: The Command Line – Digital Combine

  2. Pingback: Command Line Terminals – Digital Combine

Comments are closed.