gem.snowgoons.ro

I've been fighting with Linux serial port programming lately, and one thing I've realised is that the Linux `termios` manpage is *terribly* formatted.

Here's a somewhat more nicely formatted quick reference.

In particular, in the standard man page it's really easy to miss which field a particular flag belongs in...

Input Flags = `c_iflag`

┌───────────┬──────────────────────────────────────────────────────────────────┐
│   Flag    │                             Meaning                              │
╞═══════════╪══════════════════════════════════════════════════════════════════╡
│ IGNBRK    │ Ignore BREAK condition on input.                                 │
├───────────┼──────────────────────────────────────────────────────────────────┤
│           │ If IGNBRK is set, a BREAK is ignored. If it is not set but       │
│           │ BRKINT is set, then a BREAK causes the input and output queues   │
│           │ to be flushed, and if the terminal is the controlling terminal   │
│ BRKINT    │ of a foreground process group, it will cause a SIGINT to be sent │
│           │ to this foreground process group. When neither IGNBRK nor BRKINT │
│           │ are set, a BREAK reads as a null byte ('\0'), except when PARMRK │
│           │ is set, in which case it reads as the sequence `\377\0\0`.       │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IGNPAR    │ Ignore framing errors and parity errors.                         │
├───────────┼──────────────────────────────────────────────────────────────────┤
│           │ If IGNPAR is not set, prefix a character with a parity error or  │
│ PARMRK    │ framing error with `\377\0`. If neither IGNPAR nor PARMRK is     │
│           │ set, read a character with a parity error or framing error as    │
│           │ `\0`.                                                            │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ INPCK     │ Enable input parity checking.                                    │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ ISTRIP    │ Strip off eighth bit.                                            │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ INLCR     │ Translate NL to CR on input.                                     │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IGNCR     │ Ignore carriage return on input.                                 │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ ICRNL     │ Translate carriage return to newline on input (unless IGNCR is   │
│           │ set).                                                            │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IUCLC     │ (not in POSIX) Map uppercase characters to lowercase on input.   │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IXON      │ Enable XON/XOFF flow control on output.                          │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IXANY     │ (XSI) Typing any character will restart stopped output. (The     │
│           │ default is to allow just the START character to restart output.) │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IXOFF     │ Enable XON/XOFF flow control on input.                           │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IMAXBEL   │ (not in POSIX) Ring bell when input queue is full. Linux does    │
│           │ not implement this bit, and acts as if it is always set.         │
├───────────┼──────────────────────────────────────────────────────────────────┤
│ IUTF8[^1] │ (not in POSIX) Input is UTF8; this allows character-erase to be  │
│           │ correctly performed in cooked mode.                              │
└───────────┴──────────────────────────────────────────────────────────────────┘

[^1]: (since Linux 2.6.4)

Output Flags = `c_oflag`

┌────────┬─────────────────────────────────────────────────────────────────────┐
│  Flag  │                               Meaning                               │
╞════════╪═════════════════════════════════════════════════════════════════════╡
│ OPOST  │ Enable implementation-defined output processing.                    │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ OLCUC  │ (not in POSIX) Map lowercase characters to uppercase on output.     │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ ONLCR  │ (XSI) Map NL to CR-NL on output.                                    │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ OCRNL  │ Map CR to NL on output.                                             │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ ONOCR  │ Don't output CR at column 0.                                        │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ ONLRET │ Don't output CR.                                                    │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ OFILL  │ Send fill characters for a delay, rather than using a timed delay.  │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ OFDEL  │ (not in POSIX) Fill character is ASCII DEL (0177). If unset, fill   │
│        │ character is ASCII NUL (`'\0'`). (Not implemented on Linux.)        │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ NLDLY  │ Newline delay mask. Values are NL0 and NL1. (*requires _BSD_SOURCE  │
│        │ or _SVID_SOURCE or _XOPEN_SOURCE*)                                  │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ CRDLY  │ Carriage return delay mask. Values are CR0, CR1, CR2, or CR3.       │
│        │ (*requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE*)           │
├────────┼─────────────────────────────────────────────────────────────────────┤
│        │ Horizontal tab delay mask. Values are TAB0, TAB1, TAB2, TAB3 (or    │
│ TABDLY │ XTABS). A value of TAB3, that is, XTABS, expands tabs to spaces     │
│        │ (with tab stops every eight columns). (*requires _BSD_SOURCE or     │
│        │ _SVID_SOURCE or _XOPEN_SOURCE*)                                     │
├────────┼─────────────────────────────────────────────────────────────────────┤
│        │ Backspace delay mask. Values are BS0 or BS1. (Has never been        │
│ BSDLY  │ implemented.) (*requires _BSD_SOURCE or _SVID_SOURCE or             │
│        │ _XOPEN_SOURCE*)                                                     │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ VTDLY  │ Vertical tab delay mask. Values are VT0 or VT1.                     │
├────────┼─────────────────────────────────────────────────────────────────────┤
│ FFDLY  │ Form feed delay mask. Values are FF0 or FF1. (*requires _BSD_SOURCE │
│        │ or _SVID_SOURCE or _XOPEN_SOURCE*)                                  │
└────────┴─────────────────────────────────────────────────────────────────────┘

Control Flags = `c_cflag`

┌─────────┬────────────────────────────────────────────────────────────────────┐
│  Flag   │                              Meaning                               │
╞═════════╪════════════════════════════════════════════════════════════════════╡
│ CBAUD   │ (not in POSIX) Baud speed mask (4+1 bits). (*requires _BSD_SOURCE  │
│         │ or _SVID_SOURCE*)                                                  │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) Extra baud speed mask (1 bit), included in CBAUD.   │
│         │ (*requires _BSD_SOURCE or _SVID_SOURCE.  (POSIX says that the baud │
│         │ speed is stored in the termios structure without specifying where  │
│ CBAUDEX │ precisely, and provides cfgetispeed() and cfsetispeed() for        │
│         │ getting at it. Some systems use bits selected by CBAUD in c_cflag, │
│         │ other systems use separate fields, for example, sg_ispeed and      │
│         │ sg_ospeed.)*)                                                      │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ CSIZE   │ Character size mask. Values are CS5, CS6, CS7, or CS8.             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ CSTOPB  │ Set two stop bits, rather than one.                                │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ CREAD   │ Enable receiver.                                                   │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ PARENB  │ Enable parity generation on output and parity checking for input.  │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ PARODD  │ If set, then parity for input and output is odd; otherwise even    │
│         │ parity is used.                                                    │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ HUPCL   │ Lower modem control lines after last process closes the device     │
│         │ (hang up).                                                         │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ CLOCAL  │ Ignore modem control lines.                                        │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ LOBLK   │ (not in POSIX) Block output from a noncurrent shell layer. For use │
│         │ by shl (shell layers). (Not implemented on Linux.)                 │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) Mask for input speeds. The values for the CIBAUD    │
│ CIBAUD  │ bits are the same as the values for the CBAUD bits, shifted left   │
│         │ IBSHIFT bits. (*requires _BSD_SOURCE or _SVID_SOURCE. (Not         │
│         │ implemented on Linux.)*)                                           │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) Use "stick" (mark/space) parity (supported on       │
│ CMSPAR  │ certain serial devices): if PARODD is set, the parity bit is       │
│         │ always 1; if PARODD is not set, then the parity bit is always 0).  │
│         │ (*requires _BSD_SOURCE or _SVID_SOURCE*)                           │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ CRTSCTS │ (not in POSIX) Enable RTS/CTS (hardware) flow control. (*requires  │
│         │ _BSD_SOURCE or _SVID_SOURCE*)                                      │
└─────────┴────────────────────────────────────────────────────────────────────┘

Local Modes = `c_lflag`

┌─────────┬────────────────────────────────────────────────────────────────────┐
│  Flag   │                              Meaning                               │
╞═════════╪════════════════════════════════════════════════════════════════════╡
│ ISIG    │ When any of the characters INTR, QUIT, SUSP, or DSUSP are          │
│         │ received, generate the corresponding signal.                       │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ ICANON  │ Enable canonical mode (described below).                           │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX; not supported under Linux) If ICANON is also set,   │
│         │ terminal is uppercase only. Input is converted to lowercase,       │
│ XCASE   │ except for characters preceded by . On output, uppercase           │
│         │ characters are preceded by \ and lowercase characters are          │
│         │ converted to uppercase. [requires _BSD_SOURCE or _SVID_SOURCE or   │
│         │ _XOPEN_SOURCE]                                                     │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ ECHO    │ Echo input characters.                                             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ ECHOE   │ If ICANON is also set, the ERASE character erases the preceding    │
│         │ input character, and WERASE erases the preceding word.             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ ECHOK   │ If ICANON is also set, the KILL character erases the current line. │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ ECHONL  │ If ICANON is also set, echo the NL character even if ECHO is not   │
│         │ set.                                                               │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) If ECHO is also set, terminal special characters    │
│         │ other than TAB, NL, START, and STOP are echoed as ^X, where X is   │
│ ECHOCTL │ the character with ASCII code 0x40 greater than the special        │
│         │ character. For example, character 0x08 (BS) is echoed as ^H.       │
│         │ [requires _BSD_SOURCE or _SVID_SOURCE]                             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) If ICANON and ECHO are also set, characters are     │
│ ECHOPRT │ printed as they are being erased. [requires _BSD_SOURCE or         │
│         │ _SVID_SOURCE]                                                      │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX) If ICANON is also set, KILL is echoed by erasing    │
│ ECHOKE  │ each character on the line, as specified by ECHOE and ECHOPRT.     │
│         │ [requires _BSD_SOURCE or _SVID_SOURCE]                             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ DEFECHO │ (not in POSIX) Echo only when a process is reading. (Not           │
│         │ implemented on Linux.)                                             │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX; not supported under Linux) Output is being flushed. │
│ FLUSHO  │ This flag is toggled by typing the DISCARD character. [requires    │
│         │ _BSD_SOURCE or _SVID_SOURCE]                                       │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ NOFLSH  │ Disable flushing the input and output queues when generating       │
│         │ signals for the INT, QUIT, and SUSP characters.                    │
├─────────┼────────────────────────────────────────────────────────────────────┤
│ TOSTOP  │ Send the SIGTTOU signal to the process group of a background       │
│         │ process which tries to write to its controlling terminal.          │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ (not in POSIX; not supported under Linux) All characters in the    │
│ PENDIN  │ input queue are reprinted when the next character is read.         │
│         │ (bash(1) handles typeahead this way.) [requires _BSD_SOURCE or     │
│         │ _SVID_SOURCE]                                                      │
├─────────┼────────────────────────────────────────────────────────────────────┤
│         │ Enable implementation-defined input processing. This flag, as well │
│ IEXTEN  │ as ICANON must be enabled for the special characters EOL2, LNEXT,  │
│         │ REPRINT, WERASE to be interpreted, and for the IUCLC flag to be    │
│         │ effective.                                                         │
└─────────┴────────────────────────────────────────────────────────────────────┘

Editorial Note

The `IEXTEN` flag would be better named the `IFUCKWITHYOUINUNDOCUMENTEDWAYS` flag. Reading the above might make you think it only has the effects described, and only when `ICANON` is enabled. This is *not true*. It does weird, implementation specific things, different from one serial adaptor to another, whether you are in Canonical mode or not. It also appears to be default-on.

For the sake of your sanity, **clear the `IEXTEN` bit**.

Special Character Processing

The `c_cc` array defines the terminal special characters. The symbolic indices (initial values) and meaning are:

┌──────────┬───────────────────────────────────────────────────────────────────┐
│  Index   │                              Meaning                              │
╞══════════╪═══════════════════════════════════════════════════════════════════╡
│          │ (not in POSIX; not supported under Linux; 017, SI, Ctrl-O)        │
│ VDISCARD │ Toggle: start/stop discarding pending output. Recognized when     │
│          │ IEXTEN is set, and then not passed as input.                      │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (not in POSIX; not supported under Linux; 031, EM, Ctrl-Y)        │
│          │ Delayed suspend character (DSUSP): send SIGTSTP signal when the   │
│ VDSUSP   │ character is read by the user program. Recognized when IEXTEN and │
│          │ ISIG are set, and the system supports job control, and then not   │
│          │ passed as input.                                                  │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (004, EOT, Ctrl-D) End-of-file character (EOF). More precisely:   │
│          │ this character causes the pending tty buffer to be sent to the    │
│ VEOF     │ waiting user program without waiting for end-of-line. If it is    │
│          │ the first character of the line, the read(2) in the user program  │
│          │ returns 0, which signifies end-of-file. Recognized when ICANON is │
│          │ set, and then not passed as input.                                │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VEOL     │ (0, NUL) Additional end-of-line character (EOL). Recognized when  │
│          │ ICANON is set.                                                    │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VEOL2    │ (not in POSIX; 0, NUL) Yet another end-of-line character (EOL2).  │
│          │ Recognized when ICANON is set.                                    │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) Erase          │
│ VERASE   │ character (ERASE). This erases the previous not-yet-erased        │
│          │ character, but does not erase past EOF or beginning-of-line.      │
│          │ Recognized when ICANON is set, and then not passed as input.      │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (003, ETX, Ctrl-C, or also 0177, DEL, rubout) Interrupt character │
│ VINTR    │ (INTR). Send a SIGINT signal. Recognized when ISIG is set, and    │
│          │ then not passed as input.                                         │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (025, NAK, Ctrl-U, or Ctrl-X, or also @) Kill character (KILL).   │
│ VKILL    │ This erases the input since the last EOF or beginning-of-line.    │
│          │ Recognized when ICANON is set, and then not passed as input.      │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (not in POSIX; 026, SYN, Ctrl-V) Literal next (LNEXT). Quotes the │
│ VLNEXT   │ next input character, depriving it of a possible special meaning. │
│          │ Recognized when IEXTEN is set, and then not passed as input.      │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VMIN     │ Minimum number of characters for noncanonical read (MIN).         │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VQUIT    │ (034, FS, Ctrl-) Quit character (QUIT). Send SIGQUIT signal.      │
│          │ Recognized when ISIG is set, and then not passed as input.        │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (not in POSIX; 022, DC2, Ctrl-R) Reprint unread characters        │
│ VREPRINT │ (REPRINT). Recognized when ICANON and IEXTEN are set, and then    │
│          │ not passed as input.                                              │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (021, DC1, Ctrl-Q) Start character (START). Restarts output       │
│ VSTART   │ stopped by the Stop character. Recognized when IXON is set, and   │
│          │ then not passed as input.                                         │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (not in POSIX; not supported under Linux; status request: 024,    │
│          │ DC4, Ctrl-T). Status character (STATUS). Display status           │
│ VSTATUS  │ information at terminal, including state of foreground process    │
│          │ and amount of CPU time it has consumed. Also sends a SIGINFO      │
│          │ signal (not supported on Linux) to the foreground process group.  │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (023, DC3, Ctrl-S) Stop character (STOP). Stop output until Start │
│ VSTOP    │ character typed. Recognized when IXON is set, and then not passed │
│          │ as input.                                                         │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VSUSP    │ (032, SUB, Ctrl-Z) Suspend character (SUSP). Send SIGTSTP signal. │
│          │ Recognized when ISIG is set, and then not passed as input.        │
├──────────┼───────────────────────────────────────────────────────────────────┤
│          │ (not in POSIX; not supported under Linux; 0, NUL) Switch          │
│ VSWTCH   │ character (SWTCH). Used in System V to switch shells in shell     │
│          │ layers, a predecessor to shell job control.                       │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VTIME    │ Timeout in deciseconds for noncanonical read (TIME).              │
├──────────┼───────────────────────────────────────────────────────────────────┤
│ VWERASE  │ (not in POSIX; 027, ETB, Ctrl-W) Word erase (WERASE). Recognized  │
│          │ when ICANON and IEXTEN are set, and then not passed as input.     │
└──────────┴───────────────────────────────────────────────────────────────────┘

An individual terminal special character can be disabled by setting the value of the corresponding `c_cc` element to `_POSIX_VDISABLE`.

The above symbolic subscript values are all different, except that `VTIME`, `VMIN` may have the same value as `VEOL`, `VEOF`, respectively.

In noncanonical mode the special character meaning is replaced by the timeout meaning. For an explanation of `VMIN` and `VTIME`, see the description of noncanonical mode below.

Canonical and noncanonical mode

The setting of the `ICANON` canon flag in `c_lflag` determines whether the terminal is operating in canonical mode (`ICANON` set) or noncanonical mode (`ICANON` unset). By default, `ICANON` set.

Canonical mode:

Noncanonical mode

In noncanonical mode input is available immediately (without the user having to type a line-delimiter character), no input processing is performed, and line editing is disabled. The settings of `MIN` (`c_cc[VMIN]`) and `TIME` (`c_cc[VTIME]`) determine the circumstances in which a `read()` completes; there are four distinct cases:

--------------------

Home - gem.snowgoons.ro