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.