termio" -- Device Driver" "

General terminal interface

COHERENT uses two methods for controlling terminals: sgtty and termio. To use sgtty, simply include the statement #include <sgtty.h> in your sources. To use termio, include the statement #include <termio.h>.

The rest of this article discusses the termio method of controlling terminals.

When a terminal file is opened, it normally causes the process to wait until a connection is established. In practice, users' programs seldom open these files: they are opened by the program getty and become a user's standard input, output, and error files. The very first terminal file opened by the process group leader of a terminal file not already associated with a process group becomes the control terminal for that process group. The control terminal plays a special role in handling quit and interrupt signals, as discussed below. The control terminal is inherited by a child process during a call to fork(). A process can break this association by changing its process group using setpgrp().

A terminal associated with one of these files ordinarily operates in full-duplex mode. Characters can be typed at any time, even while output is occurring, and are lost only when the system's input buffers become completely full, which is rare, or when the user has accumulated the maximum allowed number of input characters that have not yet been read by some program. Currently, this limit is 256 characters. When the input limit is reached, the system throws away all the saved characters without notice.

Normally, terminal input is processed in units of lines. A line is delimited by a newline character (ASCII LF), an end- of-file character (ASCII EOT), or an end-of-line character. This means that a program attempting to read will be suspended until an entire line has been typed. Also, no matter how many characters are requested in the read call, at most one line is returned. It is not, however, necessary to read a whole line at once; any number of characters may be requested in a read, even one, without losing information.

During input, the system normally processes erase and kill characters. By default, the backspace character erases the last character typed, except that it will not erase beyond the beginning of the line. By default, the &&lltt;;ccttrrll--UU&&ggtt;; kills (deletes) the entire input line, and optionally outputs a newline character. Both these characters operate on a keystroke-by-keystroke basis, independently of any backspacing or tabbing which may have been done. Both the erase and kill characters may be entered literally by preceding them with the escape character (\). You can change the erase and kill characters.

Certain characters have special functions on input. These functions and their default character values are summarized as follows:

IINNTTRR
(&&lltt;;ccttrrll--CC&&ggtt;; or ASCII ETX) generates an interrupt signal that is sent to all processes with the associated control terminal. Normally, each such process is forced to terminate, but arrangements may be made either to ignore the signal or to receive a trap to an agreed-upon location. For details and a table of legal signals, see the Lexicon entry for signal().

QQUUIITT
(&&lltt;;ccttrrll--\\&&ggtt;; or ASCII ES) generates a quit signal. Its treatment is identical to that of the interrupt signal except that, unless a receiving process has made other arrangements, it not only terminates but dumps a core image file (named ccoorree) into the current working directory.

EERRAASSEE
(&&lltt;;bbaacckkssppaaccee&&ggtt;; or ASCII BS) erases the preceding character. It does not erase beyond the start of a line, as delimited by a newline, EOF, or EOL character.

KKIILLLL
(&&lltt;;ccttrrll--UU&&ggtt;; or ASCII NAK) deletes the entire line, as delimited by a newline, EOF, or EOL character.

EEOOFF
(&&lltt;;ccttrrll--DD&&ggtt;; or ASCII EOT) generates an end-of-file character from a terminal. When received, all the characters waiting to be read are immediately passed to the program without waiting for a newline, and the EOF is discarded. Thus, if no characters are waiting, which is to say the EOF occurred at the beginning of a line, zero characters are passed back; this is the standard end-of-file indication.

NNLL
(ASCII LF) is the normal line delimiter. It cannot be changed or escaped.

EEOOLL
(ASCII LF) is an additional line delimiter, like NL. It is not normally used.

SSTTOOPP
(&&lltt;;ccttrrll--SS&&ggtt;; or ASCII DC3) can be used to suspend output. It is useful with CRT terminals to prevent output from disappearing before it can be read. While output is suspended, STOP characters are ignored and not read.

SSTTAARRTT
(&&lltt;;ccttrrll--QQ&&ggtt;; or ASCII DC1) resumes output that has been suspended by a STOP character. While output is not suspended, START characters are ignored and not read. The START/STOP characters cannot be changed or escaped.

You can change the character values for INTR, QUIT, ERASE, KILL, EOF, and EOL To suit your taste. The ERASE, KILL, and EOF character can be preceded by a `\' character, in which case the system ignores its special meaning.

When the carrier signal from the data-set drops, the system sends a hangup signal to all processes that have this terminal as their control terminal. Unless other arrangements have been made, this signal causes the process to terminate. If the hangup signal is ignored, any subsequent read returns EOF. Thus, programs that read a terminal and test for end-of-file can terminate appropriately when hung up on.

When one or more characters are written, they are transmitted to the terminal as soon as previously written characters have finished typing. Input characters are echoed by putting them into the output queue as they arrive. If a process produces characters more rapidly than they can be printed, it is suspended when its output queue exceeds a preset limit. When the queue has drained down to that threshold, the program resumes.

Several calls to ioctl() apply to terminal files. The primary calls use the following structure, defined in <tteerrmmiioo..hh>:

#define NCC 8
struct termio {
        unsigned short c_iflag;    /* input modes */
        unsigned short c_oflag;    /* output modes */
        unsigned short c_cflag;    /* control modes */
        unsigned short c_lflag;    /* local modes */
        char           c_line;     /* line discipline */
        unsigned char  c_cc[NCC];  /* control chars */
};

The special control characters are defined by the array c_cc. The relative positions and initial values for each function are as follows:

     0   INTR      ^C
     1   QUIT      ^\
     2   ERASE     \b
     3   KILL      ^U
     4   EOF       ^D
     5   EOL       \n
     6   reserved
     7   reserved

The field c_iflag describes the basic terminal input control:

BBRRKKIINNTT    Signal interrupt on break
IIGGNNPPAARR    Ignore characters with parity errors
IINNPPCCKK     Enable input parity check
IISSTTRRIIPP    Strip character
IICCRRNNLL     Map CR to NL on input
IIXXOONN      Enable start/stop output control
IIXXOOFFFF     Enable start/stop input control

If INPCK is set, input parity checking is enabled. If it is not set, then checking is disabled. This allows output parity generation without input parity errors.

If ISTRIP is set, valid input characters are stripped to seven bits before being processed; otherwise, all eight bits are processed.

If IXON is set, START/STOP output control is enabled. A received STOP character suspends output and a received START character restarts output. All start/stop characters are ignored and not read.

If IXOFF is set, the system transmits START/STOP characters when the input queue is nearly empty or nearly full.

The initial input control value is all bits clear.

The field c_oflag field specifies the system treatment of output: OOPPOOSSTT Postprocess output. OOLLCCUUCC Map lower case to upper on output. OONNLLCCRR Map NL to CR-NL on output.

If OPOST is set, output characters are post-processed as indicated by the remaining flags; otherwise, characters are transmitted without change.

If OLCUC is set, a lower-case alphabetic character is transmitted as the corresponding upper-case character. This function is often used with IUCLC.

If ONLCR is set, the NL character is transmitted as the CR-NL character pair.

The initial output control value is all bits clear.

The field c_cflag describes the hardware control of the terminal, as follows: CCBBAAUUDD Baud rate BB00 Hang up BB5500 50 baud BB7755 75 baud BB111100 110 baud BB113344 134.5 baud BB115500 150 baud BB220000 200 baud BB330000 300 baud BB660000 600 baud BB11220000 1200 baud BB11880000 1800 baud BB22440000 2400 baud BB44880000 4800 baud BB99660000 9600 baud BB1199220000 19200 baud BB3388440000 38400 baud CCRREEAADD Enable receiver PPAARREENNBB Parity enable PPAARROODDDD Odd parity, else even HHUUPPCCLL Hang up on last close CCLLOOCCAALL Local line, else dial-up

The CBAUD bits specify the baud rate. The zero-baud rate, B0, hangs up the connection. If B0 is specified, the data-terminal-ready signal is not asserted. Normally, this disconnects the line. For any particular hardware, the system ignores impossible changes to the speed.

If PARENB is set, parity generation and detection is enabled and a parity bit is added to each character. If parity is enabled, the PARODD flag specifies odd parity if set; otherwise, even parity is used.

If CREAD is set, the receiver is enabled. Otherwise, no characters will be received.

If HUPCL is set, COHERENT disconnects the line when the last process with the line open closes the line or terminates; that is, the data-terminal-ready signal is not asserted.

If CLOCAL is set, the system assumes that the line to be a local, direct connection with no modem control. Otherwise, it assumes modem control.

The line discipline uses the field c_lflag to control terminal functions. The basic line discipline (zero) provides the following:

     IISSIIGG      Enable signals
     IICCAANNOONN    Canonical input (erase and kill processing)
     XXCCAASSEE     Canonical upper/lower presentation
     EECCHHOO      Enable echo
     EECCHHOOEE     Echo erase character as BS-SP-BS
     EECCHHOOKK     Echo NL after kill character
     EECCHHOONNLL    Echo NL

The following gives the meaning of each flag in detail:

IISSIIGG
If this flag is set, the system checks each input character against the special control characters INTR and QUIT. If an input character matches one of these control characters, the system executes the function associated with that character. If it is not set is not set, the system performs no checking; thus, these special input functions are possible only if ISIG is set. You can disable these functions individually by changing the value of the control character to an unlikely or impossible value (e.g., 0377).

IICCAANNOONN
If this flag is set, the system enables canonical processing. This enables the erase and kill-edit functions, and limits the assembly of input characters into lines delimited by NL, EOF, and EOL. The system also interprets the vmin and vtime locations in the termio structure as c_cc[VEOF] and c_cc[VEOL], respectively.

When the ICANON bit is cleared, you must set c_cc[VMIN] and c_cc[VTIME] to appropriate vmin and vtime values. vmin is a number from 0 to 255 that gives the minimum number of characters required before any read operation completes. vtime is a number from 0 to 255 that specifies how long, in tenths of a second, to wait for completion of input. The following describes how termio processes the vmin and vtime values:

11..
If vmin is greater than zero and vtime equals zero, block until vmin characters are received.

22..
If both vmin and vtime are greater than zero, block until the first character is received, then return after vmin characters are received or vtime/10 seconds have elapsed since the last character was received, whichever occurs first.

33..
If vmin equals zero, return after first character is received or after vtime/10 seconds have passed, whichever occurs first. It may return a read count of zero -- but will return one character if it is available, even if vtime is zero.

You can use the command stty to reset the vmin and vtime values. The header file termio.h includes the constants VMIN and VTIME, which set default values for vmin and vtime, respectively.

XXCCAASSEE
If this flag is set, and if ICANON is set, an upper-case letter is accepted on input by preceding it with a `\' character, and is output preceded by a `\' character. In this mode, the following escape sequences are generated on output and accepted on input:
     _F_o_r_: _U_s_e_:

     `    \'
     |    \!
     ~    \^
     {    \(
     }    \)
     \    \\

For example, AA is input as \\aa, \\nn as \\\\nn, and \\NN as \\\\\\nn.

EECCHHOO
If this flag is set, characters are echoed as received. When ICANON is set, the following echo functions are possible:

+o
If ECHO and ECHOE are set, the erase character is echoed as ASCII BS SP BS, which clears the last character from the screen.

+o
If ECHOE is set and ECHO is not set, the erase character is echoed as ASCII SP BS.

+o
If ECHOK is set, the NL character is echoed after the kill character to emphasize that the line will be deleted. Note that an escape character preceding the erase or kill character removes any special function.

+o
If ECHONL is set, the NL character is echoed even if ECHO is not set. This is useful for terminals set to local echo (``half duplex'').

Unless escaped, the EOF character is not echoed. Because EOT is the default EOF character, this prevents terminals that respond to EOT from hanging up.

The initial line-discipline control value is all bits clear.

The primary calls to ioctl() have the following form:

ioctl( fildes, command, arg )
struct termio *arg;

The following commands use this form:

TTCCGGEETTAA
Get the parameters associated with the terminal and store in the termio structure referenced by arg.

TTCCSSEETTAA
Set the parameters associated with the terminal from the structure referenced by arg. The change is immediate.

TTCCSSEETTAAWW
Wait for the output to drain before setting the new parameters. This form should be used when changing parameters that affect output.

TTCCSSEETTAAFF
Wait for the output to drain, then flush the input queue and set the new parameters.

Additional calls to ioctl() have the following form:
ioctl( fildes, command, arg )
int arg;

The following command uses this form:

TTCCFFLLSSHH
Flush both the input and output queues.

Note that header <termio.h> defines other constants for purposes of portability. Features designated by these constants are unavailable in the current release of COHERENT 386.

Example

The following example gives some functions that let you perform a non-blocking read of the keyboard -- that is, a
     read(0, &c, sizeof(char));

that returns zero (failure) rather than waiting for input if there is no current typed character.

To do so, you must do the following:

+o
Set up keyboard input appropriately with the ioctls TCGETA and TCSETA.

+o
Turn off ICANON.

+o
Turn off the various versions of ECHO.

+o
Use ISIG to disable keyboard interrupts.

+o
Finally, set:
     termiob.c_cc[VMIN] = 0;
     termiob.c_cc[VTIME] = 0;

This lets read() return after reading zero bytes in .0 seconds.
#include <termio.h>
#include <stdlib.h>
void
ttyinit()
{
     struct    termio    termiob;
     ioctl(0, TCGETA, &termiob); /* get tty characteristics */
     termiob.c_cc[VMIN] = 0;
     termiob.c_cc[VTIME] = 0; /* non-blocking read */
     ioctl(0, TCSETA, &termiob); /* set new mode */
}
int
ttycheck()
{
     static int done = 0;
     char c;
     if (done)
          return 0;
     if (read(0, &c, 1) != 0) {
          if (c == 'a')
               return 0;
          else if (c != ' ') {
               ++done;
               return 0;
          }
          /* After <space>, pause until another character is typed */
          while (read(0, &c, 1) == 0)
               ;
     }
     return 1;
}
main()
{
     ttyinit();
     while (1) {
          printf("Still checking ...\n");
          if (!ttycheck())
               exit(EXIT_SUCCESS);
     }
}

For another example of how to manipulate the termio structure, see the entry for ioctl().

Files

/dev/tty*

See Also

Notes

The version of stty that is supplied with COHERENT 386 provides complete access to the System-V-style termio structure. This lets you specify and view any combination of the fields therein, including various delays. How these fields are processed, however, depends on the device in question. The settings of termio are processed by the kernel's in- line discipline and device-driver modules. In COHERENT 4.0.1, none of these modules pays attention to delay settings.