|
|
Flow control becomes a problem when a program that reads from a TTY device that cannot keep up with the number of characters that are coming into the TTY. If this happens, characters are over-written in the TTY input queue before they can be read by the program.
Conversely, when a program writes to a TTY, the device might not be able to keep up with the TTY. When this happens, characters that are written by a program to a TTY are not being seen by the appropriate device.
The termio facility provides a mechanism called software flow control to solve this problem. If a program cannot keep up with the characters coming into a TTY, the TTY sends a STOP character to the originator. The originator, upon receipt of the STOP character, stops sending characters to the TTY until it received a START character. The TTY sends the START character when the program has sufficiently emptied its input queue.
If a device cannot keep up with a TTY, the device sends a STOP character to the TTY. Upon receipt of the STOP character, the TTY stops sending characters to the terminal until it receives a START character. The terminal sends the START character when it has sufficiently emptied its input queue. The TTY then blocks writes to the TTY until the TTY's output has sufficiently emptied.
Three different options are provided for flow control: IXON, IXOFF, and IXANY. If IXOFF is set, then software flow control is enabled on the TTY's input queue. The TTY transmits a STOP character when the program cannot keep up with its input queue and transmits a START character when its input queue in nearly empty again.
If IXON is set, software flow control is enabled on the TTY's output queue. The TTY blocks writes by the program when the device to which it is connected cannot keep up with it. If IXANY is set, then any character received by the TTY from the device restarts the output that has been suspended.
The following function (see the following figure) sets the IXANY, IXOFF, and IXANY options for a TTY device that has previously been opened so that software flow control is enabled for both input and output.
1 #include <termio.h> 2 3 extern struct termio old_term; 4 5 setup3(fid) 6 int fid; 7 { 8 struct termio new_term; 9 10 if (ioctl(fid, TCGETA, &old_term) == -1) 11 { 12 printf("ioctl get failed.\n"); 13 exit(1); 14 } 15 16 new_term = old_term; 17 new_term.c_iflag |= IXON | IXOFF | IXANY; 18 19 if (ioctl(fid, TCSETA, &new_term) == -1) 20 { 21 printf("ioctl set failed.\n"); 22 exit(1); 23 } 24 }
Improving TTY performance - flow control
When you design programs that read and write for the TTY subsystem, remember to address buffer size, canonical/raw mode and flow control concerns to ensure programming efficiency. For further information, see termio(7), open(2), read(2), and ioctl(2).