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...
┌───────────┬──────────────────────────────────────────────────────────────────┐ │ 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)
┌────────┬─────────────────────────────────────────────────────────────────────┐ │ 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*) │ └────────┴─────────────────────────────────────────────────────────────────────┘
┌─────────┬────────────────────────────────────────────────────────────────────┐ │ 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*) │ └─────────┴────────────────────────────────────────────────────────────────────┘
┌─────────┬────────────────────────────────────────────────────────────────────┐ │ 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. │ └─────────┴────────────────────────────────────────────────────────────────────┘
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**.
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.
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.
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:
--------------------