Team BBL
Previous Page Next Page

18.3. Special Input Characters

POSIX.1 defines 11 characters that are handled specially on input. Implementations define additional special characters. Figure 18.9 summarizes these special characters.

Figure 18.9. Summary of special terminal input characters

Character

Description

c_cc subscript

Enabled by

Typical value

POSIX.1

FreeBSD 5.2.1

Linux 2.4.22

Mac OS X 10.3

Solaris 9

   

field

flag

      

CR

carriage return

(can't change)

c_lflag

ICANON

\r

DISCARD

discard output

VDISCARD

c_lflag

IEXTEN

^O

 

DSUSP

delayed suspend (SIGTSTP)

VDSUSP

c_lflag

ISIG

^Y

 

 

EOF

end of file

VEOF

c_lflag

ICANON

^D

EOL

end of line

VEOL

c_lflag

ICANON

 

EOL2

alternate end of line

VEOL2

c_lflag

ICANON

  

ERASE

backspace one character

VERASE

c_lflag

ICANON

^H, ^?

ERASE2

alternate backspace character

VERASE2

c_lflag

ICANON

^H, ^?

 

   

INTR

interrupt signal (SIGINT)

VINTR

c_lflag

ISIG

^?, ^C

KILL

erase line

VKILL

c_lflag

ICANON

^U

LNEXT

literal next

VLNEXT

c_lflag

IEXTEN

^V

 

NL

line feed (newline)

(can't change)

c_lflag

ICANON

\n

QUIT

quit signal (SIGQUIT)

VQUIT

c_lflag

ISIG

^\

REPRINT

reprint all input

VREPRINT

c_lflag

ICANON

^R

 

START

resume output

VSTART

c_iflag

IXON/IXOFF

^Q

STATUS

status request

VSTATUS

c_lflag

ICANON

^T

 

 

 

STOP

stop output

VSTOP

c_iflag

IXON/IXOFF

^S

SUSP

suspend signal (SIGTSTP)

VSUSP

c_lflag

ISIG

^Z

WERASE

backspace one word

VWERASE

c_lflag

ICANON

^W

 


Of the 11 POSIX.1 special characters, we can change 9 of them to almost any value that we like. The exceptions are the newline and carriage return characters (\n and \r, respectively) and perhaps the STOP and START characters (depends on the implementation). To do this, we modify the appropriate entry in the c_cc array of the termios structure. The elements in this array are referred to by name, with each name beginning with a V (the third column in Figure 18.9).

POSIX.1 allows us to disable these characters. If we set the value of an entry in the c_cc array to the value of _POSIX_VDISABLE, then we disable the corresponding special character.

In older versions of the Single UNIX Specification, support for _POSIX_VDISABLE was optional. It is now required.

All four platforms discussed in this text support this feature. Linux 2.4.22 and Solaris 9 define _POSIX_VDISABLE as 0; FreeBSD 5.2.1 and Mac OS X 10.3 define it as 0xff.

Some earlier UNIX systems disabled a feature if the corresponding special input character was 0.

Example

Before describing all the special characters in detail, let's look at a small program that changes them. The program in Figure 18.10 disables the interrupt character and sets the end-of-file character to Control-B.

Note the following in this program.

  • We modify the terminal characters only if standard input is a terminal device. We call isatty (Section 18.9) to check this.

  • We fetch the _POSIX_VDISABLE value using fpathconf.

  • The function tcgetattr (Section 18.4) fetches a termios structure from the kernel. After we've modified this structure, we call tcsetattr to set the attributes. The only attributes that change are the ones we specifically modified.

  • Disabling the interrupt key is different from ignoring the interrupt signal. The program in Figure 18.10 simply disables the special character that causes the terminal driver to generate SIGINT. We can still use the kill function to send the signal to the process.

Figure 18.10. Disable interrupt character and change end-of-file character
#include "apue.h"
#include <termios.h>

int
main(void)
{
    struct termios term;
    long           vdisable;

    if (isatty(STDIN_FILENO) == 0)
        err_quit("standard input is not a terminal device");

    if ((vdisable = fpathconf(STDIN_FILENO, _PC_VDISABLE)) < 0)
        err_quit("fpathconf error or _POSIX_VDISABLE not in effect");

    if (tcgetattr(STDIN_FILENO, &term) < 0) /* fetch tty state */
        err_sys("tcgetattr error");

    term.c_cc[VINTR] = vdisable;    /* disable INTR character */
    term.c_cc[VEOF]  = 2;           /* EOF is Control-B */

    if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term) < 0)
        err_sys("tcsetattr error");

    exit(0);
}

We now describe each of the special characters in more detail. We call these the special input characters, but two of the characters, STOP and START (Control-S and Control-Q), are also handled specially when output. Note that when recognized by the terminal driver and processed specially, most of these special characters are then discarded: they are not returned to the process in a read operation. The exceptions to this are the newline characters (NL, EOL, EOL2) and the carriage return (CR).

CR

The carriage return character. We cannot change this character. This character is recognized on input in canonical mode. When both ICANON (canonical mode) and ICRNL (map CR to NL) are set and IGNCR (ignore CR) is not set, the CR character is translated to NL and has the same effect as a NL character. This character is returned to the reading process (perhaps after being translated to a NL).

DISCARD

The discard character. This character, recognized on input in extended mode (IEXTEN), causes subsequent output to be discarded until another DISCARD character is entered or the discard condition is cleared (see the FLUSHO option). This character is discarded when processed (i.e., it is not passed to the process).

DSUSP

The delayed-suspend job-control character. This character is recognized on input in extended mode (IEXTEN) if job control is supported and if the ISIG flag is set. Like the SUSP character, this delayed-suspend character generates the SIGTSTP signal that is sent to all processes in the foreground process group (refer to Figure 9.7). But the delayed-suspend character generates a signal only when a process reads from the controlling terminal, not when the character is typed. This character is discarded when processed (i.e., it is not passed to the process).

EOF

The end-of-file character. This character is recognized on input in canonical mode (ICANON). When we type this character, all bytes waiting to be read are immediately passed to the reading process. If no bytes are waiting to be read, a count of 0 is returned. Entering an EOF character at the beginning of the line is the normal way to indicate an end of file to a program. This character is discarded when processed in canonical mode (i.e., it is not passed to the process).

EOL

The additional line delimiter character, like NL. This character is recognized on input in canonical mode (ICANON) and is returned to the reading process; however, this character is not normally used.

EOL2

Another line delimiter character, like NL. This character is treated identically to the EOL character.

ERASE

The erase character (backspace). This character is recognized on input in canonical mode (ICANON) and erases the previous character in the line, not erasing beyond the beginning of the line. This character is discarded when processed in canonical mode (i.e., it is not passed to the process).

ERASE2

The alternate erase character (backspace). This character is treated exactly like the erase character (ERASE).

INTR

The interrupt character. This character is recognized on input if the ISIG flag is set and generates the SIGINT signal that is sent to all processes in the foreground process group (refer to Figure 9.7). This character is discarded when processed (i.e., it is not passed to the process).

KILL

The kill character. (The name "kill" is overused; recall the kill function used to send a signal to a process. This character should be called the line-erase character; it has nothing to do with signals.) It is recognized on input in canonical mode (ICANON). It erases the entire line and is discarded when processed (i.e., it is not passed to the process).

LNEXT

The literal-next character. This character is recognized on input in extended mode (IEXTEN) and causes any special meaning of the next character to be ignored. This works for all special characters listed in this section. We can use this character to type any character to a program. The LNEXT character is discarded when processed, but the next character entered is passed to the process.

NL

The newline character, which is also called the line delimiter. We cannot change this character. This character is recognized on input in canonical mode (ICANON). This character is returned to the reading process.

QUIT

The quit character. This character is recognized on input if the ISIG flag is set. The quit character generates the SIGQUIT signal, which is sent to all processes in the foreground process group (refer to Figure 9.7). This character is discarded when processed (i.e., it is not passed to the process).

 

Recall from Figure 10.1 that the difference between INTR and QUIT is that the QUIT character not only terminates the process by default, but also generates a core file.

REPRINT

The reprint character. This character is recognized on input in extended, canonical mode (both IEXTEN and ICANON flags set) and causes all unread input to be output (reechoed). This character is discarded when processed (i.e., it is not passed to the process).

START

The start character. This character is recognized on input if the IXON flag is set and is automatically generated as output if the IXOFF flag is set. A received START character with IXON set causes stopped output (from a previously entered STOP character) to restart. In this case, the START character is discarded when processed (i.e., it is not passed to the process).

 

When IXOFF is set, the terminal driver automatically generates a START character to resume input that it had previously stopped, when the new input will not overflow the input buffer.

STATUS

The BSD status-request character. This character is recognized on input in extended, canonical mode (both IEXTEN and ICANON flags set) and generates the SIGINFO signal, which is sent to all processes in the foreground process group (refer to Figure 9.7). Additionally, if the NOKERNINFO flag is not set, status information on the foreground process group is also displayed on the terminal. This character is discarded when processed (i.e., it is not passed to the process).

STOP

The stop character. This character is recognized on input if the IXON flag is set and is automatically generated as output if the IXOFF flag is set. A received STOP character with IXON set stops the output. In this case, the STOP character is discarded when processed (i.e., it is not passed to the process). The stopped output is restarted when a START character is entered.

 

When IXOFF is set, the terminal driver automatically generates a STOP character to prevent the input buffer from overflowing.

SUSP

The suspend job-control character. This character is recognized on input if job control is supported and if the ISIG flag is set. The suspend character generates the SIGTSTP signal, which is sent to all processes in the foreground process group (refer to Figure 9.7). This character is discarded when processed (i.e., it is not passed to the process).

WERASE

The word-erase character. This character is recognized on input in extended, canonical mode (both IEXTEN and ICANON flags set) and causes the previous word to be erased. First, it skips backward over any white space (spaces or tabs), then backward over the previous token, leaving the cursor positioned where the first character of the previous token was located. Normally, the previous token ends when a white space character is encountered. We can change this, however, by setting the ALTWERASE flag. This flag causes the previous token to end when the first nonalphanumeric character is encountered. The word-erase character is discarded when processed (i.e., it is not passed to the process).


Another "character" that we need to define for terminal devices is the BREAK character. BREAK is not really a character, but rather a condition that occurs during asynchronous serial data transmission. A BREAK condition is signaled to the device driver in various ways, depending on the serial interface.

Most old serial terminals have a key labeled BREAK that generates the BREAK condition, which is why most people think of BREAK as a character. Some newer terminal keyboards don't have a BREAK key. On PCs, the break key might be mapped for other purpose. For example, the Windows command interpreter can be interrupted by typing Control-BREAK.

For asynchronous serial data transmission, a BREAK is a sequence of zero-valued bits that continues for longer than the time required to send one byte. The entire sequence of zero-valued bits is considered a single BREAK. In Section 18.8, we'll see how to send a BREAK with the tcsendbreak function.

    Team BBL
    Previous Page Next Page