COHERENT manpages
This page displays the COHERENT manpage for termio [General terminal interface].
List of available manpages
Index
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
<ctrl-U> 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:
INTR (<ctrl-C> 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().
QUIT (<ctrl-\> 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 core) into
the current working directory.
ERASE (<backspace> 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.
KILL (<ctrl-U> or ASCII NAK) deletes the entire line, as
delimited by a newline, EOF, or EOL character.
EOF (<ctrl-D> 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.
NL (ASCII LF) is the normal line delimiter. It cannot be changed or
escaped.
EOL (ASCII LF) is an additional line delimiter, like NL. It is not
normally used.
STOP (<ctrl-S> 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.
START (<ctrl-Q> 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 <termio.h>:
#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:
BRKINT Signal interrupt on break
IGNPAR Ignore characters with parity errors
INPCK Enable input parity check
ISTRIP Strip character
ICRNL Map CR to NL on input
IXON Enable start/stop output control
IXOFF 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:
OPOST Postprocess output.
OLCUC Map lower case to upper on output.
ONLCR 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:
CBAUD Baud rate
B0 Hang up
B50 50 baud
B75 75 baud
B110 110 baud
B134 134.5 baud
B150 150 baud
B200 200 baud
B300 300 baud
B600 600 baud
B1200 1200 baud
B1800 1800 baud
B2400 2400 baud
B4800 4800 baud
B9600 9600 baud
B19200 19200 baud
B38400 38400 baud
CREAD Enable receiver
PARENB Parity enable
PARODD Odd parity, else even
HUPCL Hang up on last close
CLOCAL 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:
ISIG Enable signals
ICANON Canonical input (erase and kill processing)
XCASE Canonical upper/lower presentation
ECHO Enable echo
ECHOE Echo erase character as BS-SP-BS
ECHOK Echo NL after kill character
ECHONL Echo NL
The following gives the meaning of each flag in detail:
ISIG 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).
ICANON
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:
1. If vmin is greater than zero and vtime equals zero, block until
vmin characters are received.
2. 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.
3. 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.
XCASE
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:
For: Use:
` \'
| \!
~ \^
{ \(
} \)
\ \\
For example, A is input as \a, \n as \\n, and \N as \\\n.
ECHO If this flag is set, characters are echoed as received. When ICANON
is set, the following echo functions are possible:
-> If ECHO and ECHOE are set, the erase character is echoed as ASCII
BS SP BS, which clears the last character from the screen.
-> If ECHOE is set and ECHO is not set, the erase character is echoed
as ASCII SP BS.
-> 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.
-> 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:
TCGETA Get the parameters associated with the terminal and store in the
termio structure referenced by arg.
TCSETA Set the parameters associated with the terminal from the
structure referenced by arg. The change is immediate.
TCSETAW Wait for the output to drain before setting the new parameters.
This form should be used when changing parameters that affect
output.
TCSETAF 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:
TCFLSH
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:
-> Set up keyboard input appropriately with the ioctls TCGETA and TCSETA.
-> Turn off ICANON.
-> Turn off the various versions of ECHO.
-> Use ISIG to disable keyboard interrupts.
-> 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
device drivers,
ioctl(),
stty,
terminal,
termio.h,
termios
POSIX Standard, §7.1
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.