Add Book to My BookshelfPurchase This Book Online

Chapter 12 - Terminals

UNIX Systems Programming for SVR4
David A. Curry
 Copyright © 1996 O'Reilly & Associates, Inc.

Pre-POSIX Terminal Control
Depending on the program, porting code that manipulates terminal attributes from a pre-POSIX operating system to a POSIX platform may or may not be a simple task. In this section we examine the other two common interfaces to terminal input and output control, those of System V and BSD.
System V Terminal Control
POSIX terminal attribute control is based on the System V interface, and is almost identical to it from a data structure and flag name point of view. System V uses a struct termio instead of struct termios; this structure is defined as follows in the include file termio.h:
    struct termio {
        unsigned short    c_iflag;
        unsigned short    c_oflag;
        unsigned short    c_cflag;
        unsigned short    c_lflag;
        char              c_line;
        unsigned char     c_cc[NCC];
    };
The elements of this structure bear a one-to-one correspondence to their struct termios counterparts (the c_line element was for future expansion and never used). There are some differences in the attributes that can be stored in the flags; these are summarized in Table 12-1.
System V releases prior to SVR4 did not support job control or most of the other terminal driver features added by Berkeley. The list of special characters supported by these versions is much shorter: EOF, EOL, ERASE, INTR, KILL, QUIT, and SWTCH. (SWTCH was for System V's layers job control facility, which was abandoned by POSIX in favor of Berkeley-style job control.)
The biggest difference between the System V interface and the POSIX interface is that instead of using tcgetattr, tcsetattr, and the other functions described in the last section, the System V interface uses the ioctl system call:
    #include <unistd.h>
    #include <termio.h>
    int ioctl(int fd, int request, /* arg */ ...);
The ioctl function is the traditional UNIX system call for manipulating I/O devices. It performs some operation, defined by the value of request, on the device referenced by the open file descriptor fd. Each operation may have one argument, a pointer to which is provided as the third parameter to ioctl. The principal reason for POSIX's abandonment of this interface is that the third argument may be a pointer to different data types, depending on the value of request, making type checking impossible. (POSIX actually does offer an ioctl-based interface to terminal control, but its use is discouraged.)
In the case of the System V terminal interface, the third argument to ioctl is always the address of a struct termio structure. The legal values for request are:
TCGETA
The current terminal attributes are retrieved and stored in the struct termio structure pointed to by the third argument. This is like tcgetattr.
TCSETA
The current terminal attributes are set to those stored in the struct termio structure pointed to by the third argument. This is like tcsetattr with the TCSANOW action.
TCSETAW
The current terminal attributes are set to those stored in the struct termio structure pointed to by the third argument. The changes do not take effect until all characters written to the device have been transmitted. This is like tcsetattr with the TCSADRAIN action.
TCSETAF
The current terminal attributes are set to those stored in the struct termio structure pointed to by the third argument. The changes do not take effect until all characters written to the device have been transmitted and all input that has been received but not read is discarded. This is like tcsetattr with the TCSAFLUSH action.
BSD Terminal Control
The BSD terminal control interface is much less organized than the System V and POSIX interfaces, with five different data structures, each of which manipulates part of the interface. However, the functionality of the BSD interface is comparable to that of the other two.
The BSD interface, like the System V one, is based on the ioctl function. In all cases, the third argument is a pointer to one of the five data structures; which structure is obvious from the value of the request argument. There are also two older functions called gtty and stty; these functions work only with the struct sgttyb structure, and are left over from the early days when that was the only structure that described terminal attributes. These two functions can be emulated as follows:
    #include <sgtty.h>
    int gtty(int fd, struct sgttyb *arg)
    {
        return(ioctl(fd, TIOCGETP, arg));
    }
    int stty(int fd, struct sgttyb *arg)
    {
        return(ioctl(fd, TIOCSETP, arg));
    }
Line disciplines
Berkeley UNIX provides two line disciplines; essentially these are two different terminal drivers (although they are not implemented as such). The old line discipline resembles the original Version 7 terminal driver, and also the one provided by pre-SVR4 versions of System V. The new line discipline supports all the features added by Berkeley; most significantly job control. The new line discipline provides essentially the same set of features as the POSIX terminal driver.
To change between the two line disciplines, use the following ioctl actions:
TIOCGETD
Get the current line discipline and store it in the integer pointed to by the third argument.
TIOCSETD
Set the current line discipline to the value stored in the integer pointed to by the third argument.
The legal values for the line discipline are OTTYDISC for the old line discipline, and NTTYDISC for the new line discipline.
The struct sgttyb structure
The basic terminal driver modes, in both the old and new line disciplines, are set with a structure of type struct sgttyb, defined in the include file sgtty.h:
    struct sgttyb {
        char    sg_ispeed;
        char    sg_ospeed;
        char    sg_erase;
        char    sg_kill;
        char    sg_flags;
    };
The sg_ispeed and sg_ospeed elements contain the input and output baud rates, and values from the set B0...B9600. The sg_erase and sg_kill elements are the ERASE and KILL characters, respectively. The sg_flags element is a set of attribute flags that can be or ed together. These include:
ECHO
Enable character echo. This is identical to the POSIX ECHO.
CRMOD
Map carriage return to newline on input, and echo newline or carriage return as carriage return-newline on output. This is a mix of the POSIX ICRNL and ONLCR attributes.
RAW
Turn on raw mode, as described earlier. The POSIX equivalent of raw mode is described in the section on POSIX terminal control.
CBREAK
Turn on cbreak mode, as described earlier. The POSIX equivalent of cbreak mode is described in the section on POSIX terminal control.
The values of the ioctl request argument that take a pointer to a struct sgttyb structure are:
TIOCGETP
Get the current attributes and store them in the structure pointed to by the third argument.
TIOCSETP
Set the current attributes from the structure pointed to by the third argument. This does not take effect until queued output has drained, and it flushes pending input.
TIOCSETN
Set the current attributes from the structure pointed to by the third argument. Do not wait for output to drain, and do not flush input. (Input is always flushed when entering or leaving raw mode.)
TIOCFLUSH
Flush all pending input and output. The third argument is ignored. This can be replaced with the POSIX tcflush function.
TIOCHPCL
Enable or disable hangup-on-last-close mode, in which the last close of the device hangs up the terminal. If the integer pointed to by the third argument is non-zero, this mode is enabled; otherwise, it is disabled. This can be replaced by the POSIX HUPCL attribute.
FIONREAD
Place the number of characters pending on the input queue that have been received but not read by the program in the integer to which the third argument points. There is no replacement for this in POSIX, although the functionality can be obtained with the select or poll functions, described in Chapter 6, Special-Purpose File Operations.
The struct tchars structure
The struct tchars structure sets special characters in both the old and new line disciplines. It is defined as follows in the include file sys/ioctl.h :
    struct tchars {
        char    t_intrc;
        char    t_quitc;
        char    t_startc;
        char    t_stopc;
        char    t_eofc;
        char    t_brkc;
    };
These characters correspond to the POSIX INTR, QUIT, START, STOP, EOF, and EOL characters, respectively.
The values of the ioctl request argument that take a pointer to a struct tchars structure are:
TIOCGETC
Get the current set of characters and store them in the structure pointed to by the third argument.
TIOCSETC
Set the current set of characters from the structure pointed to by the third argument.
The local mode word
The local mode word is an integer containing attribute flags used by the new line discipline only. These attributes are set by or ing them into the mode word. These attributes include:
LPRTERA
Set printing terminal erase mode, like System V's ECHOPRT.
LCRTERA
Erase with backspace-space-backspace, like POSIX ECHOE.
LLITOUT
Suppress output translations, like turning off POSIX OPOST.
LTOSTOP
Send SIGTTOU to background programs attempting to write to the terminal, like POSIX TOSTOP.
LCRTKIL
Kill lines with backspace-space-backspace, like POSIX ECHOKE.
LPASS8
Pass all eight bits of each character through, like turning off POSIX ISTRIP.
LCTLECH
Echo control characters on input as “^X”; SVR4 (but not POSIX) offers this feature as ECHOCTL.
The values of the ioctl request argument that take a pointer to a local mode word integer are:
TIOCLGET
Get the current value of the local mode word and place it in the integer to which the third argument points.
TIOCLSET
Treat the third argument as a pointer to a mask of bits to replace the current contents of the local mode word.
TIOCLBIS
Treat the third argument as a pointer to a mask of bits to be set in the local mode word.
TIOCLBIC
Treat the third argument as a pointer to a mask of bits to be cleared in the local mode word.
The struct ltchars structure
The last structure used by the Berkeley terminal interface is the struct ltchars structure; this structure sets the additional special characters used by the new line discipline. It is defined in the include file sys/ioctl.h:
    struct ltchars {
        char    t_suspc;
        char    t_dsuspc;
        char    t_rprntc;
        char    t_flushc;
        char    t_werasc;
        char    t_lnextc;
    };
These elements correspond to the POSIX special characters SUSP, DSUSP, REPRINT, DISCARD, WERASE, and LNEXT, respectively.
The values of the ioctl request argument that take a pointer to a struct ltchars structure are:
TIOCGLTC
Get the current special characters and store them in the structure pointed to by the third argument.
TIOCSLTC
Set the current special characters to those stored in the structure pointed to by the third argument.

Previous SectionNext Section
Books24x7.com, Inc © 2000 –  Feedback