This lab is all about terminals and pseudo terminals. The chapter correponding to this lab is Chapter 15.
Let me preface this page by saying that dealing with terminals is a fairly low-level procedure, the kind of thing normally reserved for writing serial-line communication programs. There are some features of (pseudo)terminals that will likely be relevant to you for your projects, and that's what the programming assignment will be about.
A tty (p. 267) is an abbreviation for "terminal" (plural: "ttys"). The abbreviation hearkens back to the old days of TeleType paper-printouts. A terminal is typically interactive and and can be run locally, over a network, or over a serial line.
In the case of real terminals, one end is connected to hardware (such as a monitor or serial port) and the other end is connected to a program (such as a shell). In the case of pseudo terminals (or "ptys"), both ends are connected to software (such as a telnet / ssh setting). (see p. 308)
The terminal to which a session is related is called a controlling terminal (p. 269). Type tty to see. (Compare with the output of ps f.)
To view the active (pseudo)terminals, type who (or w) at the command line. To see the device files, type ls /dev/tty* and ls /dev/pty*. (The naming convention for ptys is explained on p. 309-310) Note that there is a virtual file system mounted on /dev/pts for keeping track of all the pseudo terminals.
There are numerous terminal settings that can be adjusted, including input, output, and data flow manipulation.
Before discussing terminal settings, you need to know that there are two modes that a terminal can run in (see bottom of p. 268): raw mode where no changes are made to the data flowing, and cooked mode which will modify data per your requests, including a limited line editor (described at top of p. 269). You can test the built-in limited line editor by typing cat > foo and typing the various keyboard and other control characters (backspace works, and Control-W will erase the last word).
To view all the settings for your terminal, type stty -a ("man stty"). Many of these should look familiar. You can change them using this same program. Example: typing stty -echo will turn off echoing. (You can turn it back on with stty echo.) For a listing of all of the settings you have changed, type stty with no arguments.
When good TTYs go bad: If you run a badly-behaved program that leaves your terminal in a weird state (not echoing, etc.) and you're not sure what all has happened, You can type stty sane to get some sane settings back. Typing reset is another option.
Page 267 in your book explains how historically Unix systems have had 3 terminal interfaces: sgtty (BSD), termio (SysV), and now termios (POSIX). (Third time's the charm, I guess.)
Page 270 (section 15.2 - "termios Overview") describes how the same changes made with stty above can be done in C code. Basically, you have a function tcgetattr that queries the current settings and fills a struct termios with the information. There is also a tcsetattr function that you can use to individually change settings. Note that tcsetattr will ignore arbitraty settings, i.e. those not supported by hardware (p. 271). If you want to make sure that you have successfully changed a setting, do another tcgetattr afterward to make sure that it took.
Example: readpass.c - This program saves the current terminal settings, then turns off character echoing (except for newline echoing) so a password can be read. (It also exibits some paranoia in checking to make sure that the requested changes were actually made.) After it is read, the original terminal settings are restored. We will look at this in the debugger in class. (FYI, there is a library function called "getpass" that does this same thing for you.)
Example: ptytest compiled with "gcc ptypair.c ptytest.c -o
ptytest" - This program opens a new pseudo terminal by iterating through
all the possible pseudo terminal devices on the system until it finds one that
is not being used (i.e. one it can open successfully). You will no
doubt find this program less than impressive when you first run it. Type
Example: robin.c - We will not be able to test this program in class, it is included just for the sake of example. This is a serial port communication program, much like minicom.
Please note that the following links are not required reading, simply additional reading if you want further explanation or a different point of view on these concepts.
Terminal I/O from the Unix Programming FAQ.
Low-Level Terminal Interface from the GNU glibc documentation. (Note that you must click Next -> Next -> Next to traverse the documentation.)
Serial Programming HOWTO from the Linux Documentation Project. Especially, these program examples
And of course, your book, Chapter 15
For this lab, I want you to report the size of the terminal window every time the terminal size changes. Basically, a run-time version of "stty size".
Make sure you put all the files for this lab in a lab8 directory.
Write a program that does the following:
Save this in a file called winsize.c. The whole file should be about 30 or so lines long (including whitespace and curlies). Be sure to have a Makefile as well.
The output from your program should look like this:
SIGWINCH: rows=32, cols=72 SIGWINCH: rows=37, cols=85 SIGWINCH: rows=23, cols=74 SIGWINCH: rows=25, cols=69 SIGWINCH: rows=25, cols=75 SIGWINCH: rows=22, cols=78 SIGWINCH: rows=26, cols=72 SIGWINCH: rows=31, cols=68 SIGWINCH: rows=35, cols=68
Note that each of the above lines is generated by resizing the terminal (Putty) window.
This kind of thing might be useful to you in your projects. Note that the w program (similar to the "who" program) will not run if the terminal size is too small.
Here is a list of the files created in this lab.
Please turn in just the winsize.c file with your name, lab # and class # at the top.