> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/man4/termios.4.md).

# termios.4

`termios` — 通用终端线路规程

## 名称

`termios`

## 概要

`#include <termios.h>`

## 描述

本文档描述 tty 异步通信端口支持的通用终端线路规程。

### 打开终端设备文件

打开终端文件时，通常会导致进程等待直到连接建立。对于大多数硬件，硬件 `CARRIER` 线的断言指示连接存在。如果与终端文件关联的 termios 结构在 cflag 中设置了 `CLOCAL` 标志，或在 open(2) 调用中设置了 `O_NONBLOCK` 标志，则即使没有连接，open 也会成功。在实践中，应用程序很少打开这些文件；它们由特殊程序（如 getty(8)）打开，并成为应用程序的标准输入、输出和错误文件。

### 作业控制概要

每个进程都与特定的进程组和会话关联。这种分组是分层的：特定进程组的每个成员都是同一会话的成员。这种结构用于管理相关进程组以进行 *作业控制*；即从键盘（或从程序控制）同时停止或重新启动复杂命令（由一个或多个相关进程组成的命令）的能力。将进程分组到进程组中允许传递信号以整体停止或启动组，并仲裁哪个进程组有权访问单一控制终端。在更高层分组到会话是为了将作业控制相关信号和系统调用限制在由特定“登录”实例产生的进程内。通常，会话在用户登录时创建，登录终端被设置为控制终端；从该登录 shell 派生的所有进程都在同一会话中，并继承控制终端。

交互式运行的作业控制 shell（即从终端读取命令）通常通过将相关进程放入同一进程组来将它们分组。同一进程组中的一组进程统称为“作业”。当终端的前台进程组与特定作业的进程组相同时，称该作业在“前台”。当终端的进程组与作业的进程组不同（但仍是控制终端）时，称该作业在“后台”。通常 shell 读取命令并启动实现该命令的作业。如果命令要在前台启动（典型情况），它将终端的进程组设为已启动作业的进程组，等待作业完成，然后将终端的进程组设回自己的进程组（将自己置于前台）。如果作业要在后台启动（由 shell 操作符 “&” 表示），它从不更改终端的进程组，也不等待作业完成（即它立即尝试读取下一个命令）。如果作业在前台启动，用户可以键入一个键（通常是 `^Z`），生成终端停止信号（`SIGTSTP`），其效果是停止整个作业。shell 会注意到作业已停止，并在将自己置于前台后恢复运行。shell 还有命令可以将停止的作业置于后台，以及将停止或后台作业置于前台。

### 孤儿进程组

孤儿进程组指这样的进程组：其中没有进程的父进程位于不同的进程组中且属于同一会话。从概念上讲，即该进程组没有能够在其停止时采取行动的父进程。例如，初始登录 shell 通常在孤儿进程组中。孤儿进程组对键盘生成的停止信号和由于读取或写入控制终端产生的作业控制信号免疫。

### 控制终端

终端可以作为进程的控制终端属于该进程。具有控制终端的会话的每个进程都有相同的控制终端。一个终端最多只能是一个会话的控制终端。会话首进程通过发出 `TIOCSCTTY` ioctl 分配会话的控制终端。仅通过打开终端设备文件永远不会获得控制终端。当控制终端与会话关联时，其前台进程组被设为会话首进程的进程组。

控制终端在 fork(2) 函数调用期间由子进程继承。当进程通过 setsid(2) 函数创建新会话时，它放弃其控制终端；旧会话中剩余的、以该终端为控制终端的其他进程继续拥有它。如果其他进程继续打开控制终端，进程不会仅通过关闭与其关联的所有文件描述符而放弃控制终端。

当控制进程终止时，控制终端与当前会话解除关联，允许新会话首进程获取它。早期会话中的其他进程随后对终端的访问会被拒绝，对终端的访问尝试会被视为检测到调制解调器断开。

### 终端访问控制

如果进程在其控制终端的前台进程组中，则允许读取操作。后台进程组中的进程尝试从其控制终端读取会导致向该进程组发送 `SIGTTIN` 信号，除非以下特殊情况之一适用：如果读取进程忽略或阻塞 `SIGTTIN` 信号，或读取进程的进程组是孤儿，read(2) 返回 -1，`errno` 设为 Er EIO，且不发送信号。`SIGTTIN` 信号的默认动作是停止发送给它的进程。

如果进程在其控制终端的前台进程组中，则允许写入操作。后台进程组中的进程尝试写入其控制终端会导致向该进程组发送 `SIGTTOU` 信号，除非以下特殊情况之一适用：如果未设置 `TOSTOP`，或设置了 `TOSTOP` 且进程忽略或阻塞 `SIGTTOU` 信号，则允许进程写入终端且不发送 `SIGTTOU` 信号。如果设置了 `TOSTOP`，且写入进程的进程组是孤儿，且写入进程未忽略或阻塞 `SIGTTOU`，write(2) 返回 -1，errno 设为 Er EIO，且不发送信号。

某些设置终端参数的调用以与写入相同的方式处理，只是忽略 `TOSTOP`；即效果与设置 `TOSTOP` 时终端写入的效果相同。

### 输入处理和读取数据

与终端设备文件关联的终端设备可以全双工模式操作，因此即使在输出发生时数据也可能到达。每个终端设备文件都有一个关联的输入队列，系统在进程读取传入数据之前，将其存储在输入队列中。系统对输入队列中可存储的字节数施加限制 {`MAX_INPUT`}。当超过此限制时系统的行为取决于 termios `c_iflag` 中 `IMAXBEL` 标志的设置。如果设置了此标志，则在输入队列满时每次接收到字符时向终端发送 ASCII `BEL` 字符。否则，接收到字符时刷新输入队列。

有两种通用类型的输入处理，由终端设备文件是处于规范模式还是非规范模式决定。此外，输入字符根据 `c_iflag` 和 `c_lflag` 字段进行处理。这种处理可以包括回显，通常意味着从终端接收到输入字符时立即将其传回终端。这对可以全双工模式操作的终端很有用。

向从终端设备文件读取的进程提供数据的方式取决于终端设备文件处于规范还是非规范模式。

另一个依赖是 open(2) 或 fcntl(2) 是否设置了 `O_NONBLOCK` 标志。如果未设置 `O_NONBLOCK` 标志，则读取请求被阻塞直到数据可用或收到信号。如果设置了 `O_NONBLOCK` 标志，则读取请求以三种方式之一完成，不阻塞：

* 如果有足够数据满足整个请求，且读取成功完成，则返回读取的字节数。
* 如果没有足够数据满足整个请求，且读取成功完成，已读取尽可能多的数据，则返回读取的字节数。
* 如果没有数据可用，读取返回 -1，errno 设为 Er EAGAIN。

数据何时可用取决于输入处理模式是规范还是非规范。

### 规范模式输入处理

在规范模式输入处理中，终端输入以行为单位处理。一行由换行符 `en`、文件结束（`EOF`）字符或行结束（`EOL`）字符定界。参见 Sx 特殊字符 部分以获取有关 `EOF` 和 `EOL` 的更多信息。这意味着读取请求在输入完整行或收到信号之前不会返回。此外，无论读取调用中请求多少字节，最多返回一行。但是，不必一次读取整行；可以在读取中请求任意字节数，甚至一个字节，而不会丢失信息。

{`MAX_CANON`} 是行中字节数的限制。当超过此限制时系统的行为与超过输入队列限制 {`MAX_INPUT`} 时相同。

当接收到两个特殊字符 `ERASE` 和 `KILL` 之一（参见 Sx 特殊字符 部分）时，发生擦除和删除处理。此处理影响输入队列中尚未被换行符 `NL`、`EOF` 或 `EOL` 字符定界的数据。这些未定界数据构成当前行。`ERASE` 字符删除当前行中的最后一个字符（如果有）。`KILL` 字符删除当前行中的所有数据（如果有）。如果当前行中没有数据，`ERASE` 和 `KILL` 字符无效。`ERASE` 和 `KILL` 字符本身不放入输入队列。

### 非规范模式输入处理

在非规范模式输入处理中，输入字节不组装成行，且不发生擦除和删除处理。使用 `c_cc` 数组的 `VMIN` 和 `VTIME` 成员的值来确定如何处理接收到的字节。

`MIN` 表示 read(2) 函数成功返回时应接收的最小字节数。`TIME` 是 0.1 秒粒度的定时器，用于使突发和短期数据传输超时。如果 `MIN` 大于 {`MAX_INPUT`}，则对请求的响应未定义。`MIN` 和 `TIME` 的四个可能值及其交互如下所述。

### 情况 A：MIN > 0，TIME > 0

在这种情况下，`TIME` 用作字节间定时器，在接收到第一个字节后激活。由于它是字节间定时器，它在接收到字节后被重置。`MIN` 和 `TIME` 之间的交互如下：一旦接收到一个字节，字节间定时器启动。如果在字节间定时器到期之前接收到 `MIN` 字节（请记住定时器在接收到每个字节时重置），则读取请求得到满足。如果定时器在接收到 `MIN` 字节之前到期，则将到目前为止接收到的字符返回给用户。注意，如果 `TIME` 到期，至少返回一个字节，因为除非接收到字节，否则定时器不会被启用。在这种情况下（`MIN` > 0，`TIME` > 0），读取阻塞直到 `MIN` 和 `TIME` 机制被第一个字节的接收激活，或收到信号。如果 Fn read 时缓冲区中有数据，结果就像数据在 Fn read 之后立即接收到一样。

### 情况 B：MIN > 0，TIME = 0

在这种情况下，由于 `TIME` 的值为零，定时器不起作用，只有 `MIN` 有意义。挂起的读取请求在接收到 `MIN` 字节之前不会得到满足（即挂起的读取请求阻塞直到接收到 `MIN` 字节），或收到信号。使用此情况读取基于记录的终端 `I/O` 的程序可能在读取操作中无限期阻塞。

### 情况 C：MIN = 0，TIME > 0

在这种情况下，由于 `MIN` = 0，`TIME` 不再表示字节间定时器。它现在用作读取定时器，在读取函数处理后立即激活。读取请求在接收到单个字节或读取定时器到期时得到满足。注意，在这种情况下，如果定时器到期，不返回任何字节。如果定时器未到期，读取请求得到满足的唯一方式是接收到字节。在这种情况下，读取不会无限期阻塞等待字节；如果在读取启动后 `TIME`\*0.1 秒内未接收到字节，读取返回零值，不读取任何数据。如果读取时缓冲区中有数据，定时器启动就像数据在读取后立即接收到一样。

### 情况 D：MIN = 0，TIME = 0

返回请求字节数或当前可用字节数中的较小者，不等待更多字节输入。如果没有字符可用，读取返回零值，不读取任何数据。

### 写入数据和输出处理

当进程向终端设备文件写入一个或多个字节时，它们根据 `c_oflag` 字段处理（参见 Sx 输出模式 部分）。实现可以提供缓冲机制；因此，当 Fn write 调用完成时，所有写入的字节已被调度传输到设备，但传输不一定已完成。

### 特殊字符

某些字符在输入或输出或两者上具有特殊功能。这些功能总结如下：

**`INTR`** 输入上的特殊字符，如果启用了 `ISIG` 标志（参见 Sx 本地模式 部分）则被识别。生成 `SIGINT` 信号，发送到终端为其控制终端的前台进程组中的所有进程。如果设置了 `ISIG`，`INTR` 字符在处理时被丢弃。

**`QUIT`** 输入上的特殊字符，如果启用了 `ISIG` 标志则被识别。生成 `SIGQUIT` 信号，发送到终端为其控制终端的前台进程组中的所有进程。如果设置了 `ISIG`，`QUIT` 字符在处理时被丢弃。

**`ERASE`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。擦除当前行中的最后一个字符；参见 Sx 规范模式输入处理。它不会擦除超出由 `NL`、`EOF` 或 `EOL` 字符定界的行首。如果设置了 `ICANON`，`ERASE` 字符在处理时被丢弃。

**`KILL`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。删除由 `NL`、`EOF` 或 `EOL` 字符定界的整行。如果设置了 `ICANON`，`KILL` 字符在处理时被丢弃。

**`EOF`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。接收到时，所有等待读取的字节立即传递给进程，不等待换行符，`EOF` 被丢弃。因此，如果没有等待的字节（即 `EOF` 出现在行首），则从 Fn read 返回零字节计数，表示文件结束指示。如果设置了 `ICANON`，`EOF` 字符在处理时被丢弃。

**`NL`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。它是行定界符 `en`。

**`EOL`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。是额外的行定界符，类似 `NL`。

**`SUSP`** 如果启用了 `ISIG` 标志，接收到 `SUSP` 字符会导致 `SIGTSTP` 信号发送到终端为其控制终端的前台进程组中的所有进程，`SUSP` 字符在处理时被丢弃。

**`STOP`** 输入和输出上的特殊字符，如果设置了 `IXON`（输出控制）或 `IXOFF`（输入控制）标志则被识别。可用于暂时暂停输出。对于快速终端很有用，可防止输出在可读取之前消失。如果设置了 `IXON`，`STOP` 字符在处理时被丢弃。

**`START`** 输入和输出上的特殊字符，如果设置了 `IXON`（输出控制）或 `IXOFF`（输入控制）标志则被识别。可用于恢复被 `STOP` 字符暂停的输出。如果设置了 `IXON`，`START` 字符在处理时被丢弃。

**`CR`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别；它是 `er`，如 C 标准 {2} 中所示。当设置了 `ICANON` 和 `ICRNL` 且未设置 `IGNCR` 时，此字符转换为 `NL`，具有与 `NL` 字符相同的效果。

以下特殊字符是本系统定义的扩展，不是 IEEE Std 1003.1（“POSIX.1”）termios 的一部分。

**`EOL2`** 辅助 `EOL` 字符。功能与 `EOL` 相同。

**`WERASE`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。根据两种算法之一擦除当前行中的最后一个单词。如果未设置 `ALTWERASE` 标志，首先擦除任何前导空白，然后是最大非空白字符序列。如果设置了 `ALTWERASE`，首先擦除任何前导空白，然后是最大字母/下划线或非字母/下划线序列。作为第二种算法的特殊情况，在确定前一个单词是否是字母/下划线序列时，跳过第一个前导非空白字符。这听起来令人困惑，但实际非常实用。

**`REPRINT`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。导致当前输入编辑行被重新键入。

**`DSUSP`** 具有与 `SUSP` 字符类似的操作，只是当进程组中的一个进程向控制终端发出 Fn read 时才传递 `SIGTSTP` 信号。

**`LNEXT`** 输入上的特殊字符，如果设置了 `IEXTEN` 标志则被识别。接收到此字符导致下一个字符按字面意义接收。

**`DISCARD`** 输入上的特殊字符，如果设置了 `IEXTEN` 标志则被识别。接收到此字符切换终端输出刷新。

**`STATUS`** 输入上的特殊字符，如果设置了 `ICANON` 标志则被识别。接收到此字符导致向终端的前台进程组发送 `SIGINFO` 信号。此外，如果未设置 `NOKERNINFO` 标志，它导致内核向终端写入状态消息，显示当前负载平均值、前台命令名、其进程 ID、符号等待通道、使用的用户和系统秒数、进程获得的 CPU 百分比以及进程的常驻集大小。如果内核配置了 [stack(9)](/man/man9/stack.9.md) 支持且 [sysctl(8)](/man/man8/sysctl.8.md) 变量 `kern.tty_info_kstacks` 设为非零值，运行线程的内核栈会写入终端（例如用于调试目的）。

`NL` 和 `CR` 字符无法更改。所有其他字符的值可以设置，并在文档后文的特殊控制字符中描述。

与可更改的特殊控制字符关联的特殊字符功能可以单独禁用，方法是将其值设为 `{_POSIX_VDISABLE}`；参见 Sx 特殊控制字符。

如果两个或更多特殊字符具有相同的值，则接收到该字符时执行的功能未定义。

### 调制解调器断开

如果终端接口检测到控制终端的调制解调器断开，且终端的 `c_cflag` 字段中未设置 `CLOCAL`，则向与终端关联的控制进程发送 `SIGHUP` 信号。除非已做出其他安排，否则这会导致控制进程终止。对 Fn read 函数的任何后续调用返回零值，指示文件结束。因此，读取终端文件并测试文件结束的进程可以在断开后适当地终止。对终端设备的任何后续 Fn write 返回 -1，`errno` 设为 Er EIO，直到设备关闭。

## 通用终端接口

### 关闭终端设备文件

最后一个关闭终端设备文件的进程会将所有输出发送到设备并丢弃所有输入。然后，如果在控制模式中设置了 `HUPCL`，且通信端口支持断开功能，则终端设备执行断开。

### 可设置的参数

需要控制某些终端 I/O 特性的例程通过使用头文件中定义的 termios 结构来实现

`#include <termios.h>`

此结构最少包含四个位标志标量元素和一个特殊字符数组。标量标志元素命名为：`c_iflag`、`c_oflag`、`c_cflag` 和 `c_lflag`。字符数组命名为 `c_cc`，其最大索引为 `NCCS`。

### 输入模式

`c_iflag` 字段的值描述基本终端输入控制，由以下掩码组成：

**`IGNBRK`** /*忽略 BREAK 条件 / **`BRKINT`** / 将 BREAK 映射为 SIGINTR / **`IGNPAR`** / 忽略（丢弃）奇偶校验错误 / **`PARMRK`** / 标记奇偶校验和帧错误 / **`INPCK`** / 启用奇偶校验错误检查 / **`ISTRIP`** / 去除字符第 8 位 / **`INLCR`** / 将 NL 映射为 CR / **`IGNCR`** / 忽略 CR / **`ICRNL`** / 将 CR 映射为 NL（即 CRMOD） / **`IXON`** / 启用输出流控制 / **`IXOFF`** / 启用输入流控制 / **`IXANY`** / 任何字符将在停止后重新启动 / **`IMAXBEL`** / 输入队列满时响铃 / **`IUTF8`** / 假定输入为 UTF-8 编码*/

在异步串行数据传输的上下文中，中断条件定义为持续超过发送一个字节时间的零值位序列。整个零值位序列被解释为单个中断条件，即使它持续的时间相当于多个字节。在异步串行数据传输以外的上下文中，中断条件的定义由实现定义。

如果设置了 `IGNBRK`，则忽略在输入上检测到的中断条件，即不放入输入队列，因此不被任何进程读取。如果未设置 `IGNBRK` 但设置了 `BRKINT`，中断条件刷新输入和输出队列，且如果终端是前台进程组的控制终端，则中断条件向该前台进程组生成单个 `SIGINT` 信号。如果 `IGNBRK` 和 `BRKINT` 都未设置，中断条件作为单个 `e0` 读取，或如果设置了 `PARMRK`，则作为 `e377`、`e0`、`e0` 读取。

如果设置了 `IGNPAR`，则忽略有帧或奇偶校验错误（中断除外）的字节。

如果设置了 `PARMRK` 且未设置 `IGNPAR`，则有帧或奇偶校验错误（中断除外）的字节作为三字符序列 `e377`、`e0`、X 给应用程序，其中 `e377`、`e0` 是每个序列前的两字符标志，X 是接收错误字符的数据。为避免在此情况下的歧义，如果未设置 `ISTRIP`，有效字符 `e377` 作为 `e377`、`e377` 给应用程序。如果 `PARMRK` 和 `IGNPAR` 都未设置，帧或奇偶校验错误（中断除外）作为单个字符 `e0` 给应用程序。

如果设置了 `INPCK`，则启用输入奇偶校验检查。如果未设置 `INPCK`，则禁用输入奇偶校验检查，允许输出奇偶校验生成而不产生输入奇偶校验错误。注意，是否启用输入奇偶校验检查与是否启用奇偶校验检测无关（参见 Sx 控制模式）。如果启用了奇偶校验检测但禁用了输入奇偶校验检查，终端所连接的硬件识别奇偶校验位，但终端特殊文件不检查此位是否设置正确。

如果设置了 `ISTRIP`，有效输入字节首先会截断为 7 位，否则处理所有 8 位。

如果设置了 `INLCR`，接收到的 `NL` 字符转换为 `CR` 字符。如果设置了 `IGNCR`，接收到的 `CR` 字符被忽略（不读取）。如果未设置 `IGNCR` 但设置了 `ICRNL`，接收到的 `CR` 字符转换为 `NL` 字符。

如果设置了 `IXON`，启用启动/停止输出控制。接收到的 `STOP` 字符暂停输出，接收到的 `START` 字符重启输出。如果还设置了 `IXANY`，则任何字符都可以重启输出。当设置了 `IXON` 时，`START` 和 `STOP` 字符不被读取，仅执行流控制功能。当未设置 `IXON` 时，`START` 和 `STOP` 字符被读取。

如果设置了 `IXOFF`，启用启动/停止输入控制。系统将传输一个或多个 `STOP` 字符（旨在使终端设备停止传输数据）以防止输入队列溢出并导致 Sx 输入处理和读取数据 中描述的未定义行为，并将传输一个或多个 `START` 字符（旨在使终端设备恢复传输数据）一旦设备可以继续传输数据而不会导致输入队列溢出的风险。传输 `STOP` 和 `START` 字符的精确条件由实现定义。

如果设置了 `IMAXBEL` 且输入队列已满，后续输入将导致向输出队列传输 ASCII `BEL` 字符。

Fn open 后的初始输入控制值由实现定义。

### 输出模式

`c_oflag` 字段的值描述基本终端输出控制，由以下掩码组成：

**`OPOST`** /*启用以下输出处理 / **`ONLCR`** / 将 NL 映射为 CR-NL（即 `CRMOD`） / **`OCRNL`** / 将 CR 映射为 NL / **`TABDLY`** / 制表符延迟掩码 / **`TAB0`** / 无制表符延迟和扩展 / **`TAB3`** / 将制表符扩展为空格 / **`ONOEOT`** / 在输出时丢弃 `EOT` 的 `^D`） / **`ONOCR`** / 在第 0 列不传输 CR / **`ONLRET`** / 在终端上 NL 执行 CR 功能*/

如果设置了 `OPOST`，其余标志掩码解释如下；否则字符原样传输。

如果设置了 `ONLCR`，换行符转换为回车符、换行符。

如果设置了 `OCRNL`，回车符转换为换行符。

`TABDLY` 位指定制表符延迟。`c_oflag` 用 `TABDLY` 掩码并与值 `TAB0` 或 `TAB3` 比较。如果设置了 `TAB3`，制表符扩展为适当数量的空格（假设 8 列制表位）。

如果设置了 `ONOEOT`，输出时丢弃 ASCII `EOT`。

如果设置了 `ONOCR`，在第 0 列（第一个位置）时不传输 CR 字符。

如果设置了 `ONLRET`，假定 NL 字符执行回车功能；列指针将设为 0。

### 控制模式

`c_cflag` 字段的值描述基本终端硬件控制，由以下掩码组成。并非所有硬件都支持所有指定的值。

**`CSIZE`** /*字符大小掩码 / **`CS5`** / 5 位（伪） / **`CS6`** / 6 位 / **`CS7`** / 7 位 / **`CS8`** / 8 位 / **`CSTOPB`** / 发送 2 个停止位 / **`CREAD`** / 启用接收器 / **`PARENB`** / 启用奇偶校验 / **`PARODD`** / 奇校验，否则偶校验 / **`HUPCL`** / 最后关闭时挂断 / **`CLOCAL`** / 忽略调制解调器状态线 / **`CCTS_OFLOW`** / 输出的 `CTS` 流控制 / **`CRTSCTS`** / 同 `CCTS_OFLOW` / **`CRTS_IFLOW`** / 输入的 RTS 流控制 / **`MDMBUF`** / 通过 Carrier 的流控制输出 / **`CNO_RTSDTR`** / 不自动断言 RTS 或 DTR*/

`CSIZE` 位指定发送和接收的字节大小（位）。`c_cflag` 用 `CSIZE` 掩码并与值 `CS5`、`CS6`、`CS7` 或 `CS8` 比较。此大小不包括奇偶校验位（如果有）。如果设置了 `CSTOPB`，使用两个停止位，否则一个停止位。例如，在 110 波特时，通常使用两个停止位。

如果设置了 `CREAD`，则启用接收器。否则不接收任何字符。并非所有硬件都支持此位。实际上，此标志相当无意义，如果不是 `termios` 规范的一部分，本可省略它。

如果设置了 `PARENB`，则启用奇偶校验生成和检测，每个字符添加一个奇偶校验位。如果启用奇偶校验，`PARODD` 指定奇校验，否则使用偶校验。

如果设置了 `HUPCL`，当最后一个打开端口的进程关闭端口或进程终止时，端口的调制解调器控制线会降低。调制解调器连接断开。

如果设置了 `CLOCAL`，连接不依赖于调制解调器状态线的状态。如果未设置 `CLOCAL`，则监视调制解调器状态线。

在正常情况下，对 Fn open 函数的调用会等待调制解调器连接完成。但是，如果设置了 `O_NONBLOCK` 标志或已设置 `CLOCAL`，Fn open 函数会立即返回，不等待连接。

`CCTS_OFLOW`（`CRTSCTS`）标志当前未使用。

如果设置了 `MDMBUF`，则输出流控制由 Carrier Detect 的状态控制。

如果设置了 `CNO_RTSDTR`，则打开设备时不会断言 RTS 和 DTR 线。因此，此标志仅在初始状态设备上有用。

如果设置控制模式的对象不是异步串行连接，某些模式可能被忽略；例如，如果尝试在到另一主机上终端的网络连接上设置波特率，波特率可能设置也可能不设置在该终端与其直接连接的机器之间的连接上。

### 本地模式

`c_lflag` 字段的值描述各种功能的控制，由以下掩码组成。

**`ECHOKE`** /*行删除的视觉擦除 / **`ECHOE`** / 视觉擦除字符 / **`ECHO`** / 启用回显 / **`ECHONL`** / 即使 `ECHO` 关闭也回显 `NL` / **`ECHOPRT`** / 硬拷贝的视觉擦除模式 / **`ECHOCTL`** / 将控制字符回显为 ^(Char) / **`ISIG`** / 启用信号 `INTR`、`QUIT`、`[D]SUSP` / **`ICANON`** / 规范化输入行 / **`ALTWERASE`** / 使用替代 `WERASE` 算法 / **`IEXTEN`** / 启用 `DISCARD` 和 `LNEXT` / **`EXTPROC`** / 外部处理 / **`TOSTOP`** / 阻止后台作业输出 / **`FLUSHO`** / 输出正在刷新（状态） / **`NOKERNINFO`** / `VSTATUS` 无内核输出 / **`PENDIN`** / XXX 重新键入挂起的输入（状态） / **`NOFLSH`** / 中断后不刷新*/

如果设置了 `ECHO`，输入字符回显到终端。如果未设置 `ECHO`，输入字符不回显。

如果设置了 `ECHOE` 和 `ICANON`，`ERASE` 字符导致终端尽可能从显示中擦除当前行的最后一个字符。如果没有字符可擦除，实现可以回显此情况的指示或不做任何操作。

如果设置了 `ECHOK` 和 `ICANON`，`KILL` 字符会丢弃当前行，系统在 `KILL` 字符后回显 `en` 字符。

如果设置了 `ECHOKE` 和 `ICANON`，`KILL` 字符会丢弃当前行，系统使终端从显示中擦除该行。

如果设置了 `ECHOPRT` 和 `ICANON`，系统假定显示是打印设备，在处理 `ERASE` 字符时打印反斜杠和擦除的字符，后跟正斜杠。

如果设置了 `ECHOCTL`，系统使用插入符后跟控制字符以可见方式回显控制字符。

如果设置了 `ALTWERASE`，系统在处理 `WERASE` 字符时使用替代算法确定什么构成一个单词（参见 `WERASE`）。

如果设置了 `ECHONL` 和 `ICANON`，即使未设置 `ECHO`，`en` 字符也回显。

如果设置了 `ICANON`，则启用规范处理。这启用擦除和删除编辑功能，以及将输入字符组装成由 `NL`、`EOF` 和 `EOL` 定界的行，如 Sx 规范模式输入处理 中所述。

如果未设置 `ICANON`，读取请求直接从输入队列得到满足。读取请求在接收到至少 `MIN` 字节或字节之间超时值 `TIME` 到期之前不会得到满足。时间值表示十分之一秒。详见 Sx 非规范模式输入处理。

如果设置了 `ISIG`，每个输入字符与特殊控制字符 `INTR`、`QUIT` 和 `SUSP`（仅作业控制）比较。如果输入字符匹配这些控制字符之一，则执行与该字符关联的功能。如果未设置 `ISIG`，则不进行检查。因此，只有在设置了 `ISIG` 时才可能实现这些特殊输入功能。

如果设置了 `IEXTEN`，从输入数据中识别实现定义的功能。`IEXTEN` 设置如何与 `ICANON`、`ISIG`、`IXON` 或 `IXOFF` 交互由实现定义。如果未设置 `IEXTEN`，则不识别实现定义的功能，相应的输入字符不按 `ICANON`、`ISIG`、`IXON` 和 `IXOFF` 的描述处理。

如果设置了 `NOFLSH`，则不执行与 `INTR`、`QUIT` 和 `SUSP` 字符关联的输入和输出队列的常规刷新。

如果设置了 `TOSTOP`，则当尝试向其控制终端写入的进程不在该终端的前台进程组中时，向该进程的进程组发送 `SIGTTOU` 信号。默认情况下，此信号停止进程组的成员。否则，该进程生成的输出输出到当前输出流。阻塞或忽略 `SIGTTOU` 信号的进程例外，允许产生输出且不发送 `SIGTTOU` 信号。

如果设置了 `NOKERNINFO`，内核在处理 `STATUS` 字符时不产生状态消息（参见 `STATUS`）。

### 特殊控制字符

特殊控制字符值由数组 `c_cc` 定义。此表列出数组索引、相应的特殊字符和系统默认值。有关系统默认值的准确列表，请查阅头文件

`#include <sys/ttydefaults.h>`

| 索引名        | 特殊字符    | 默认值               |
| ---------- | ------- | ----------------- |
| `VEOF`     | EOF     | ^D                |
| `VEOL`     | EOL     | \_POSIX\_VDISABLE |
| `VEOL2`    | EOL2    | \_POSIX\_VDISABLE |
| `VERASE`   | ERASE   | ^? `e177`         |
| `VWERASE`  | WERASE  | ^W                |
| `VKILL`    | KILL    | ^U                |
| `VREPRINT` | REPRINT | ^R                |
| `VINTR`    | INTR    | ^C                |
| `VQUIT`    | QUIT    | ^ee `e34`         |
| `VSUSP`    | SUSP    | ^Z                |
| `VDSUSP`   | DSUSP   | ^Y                |
| `VSTART`   | START   | ^Q                |
| `VSTOP`    | STOP    | ^S                |
| `VLNEXT`   | LNEXT   | ^V                |
| `VDISCARD` | DISCARD | ^O                |
| `VMIN`     | ---     | 1                 |
| `VTIME`    | ---     | 0                 |
| `VSTATUS`  | STATUS  | ^T                |

如果可更改的特殊控制字符之一（参见 Sx 特殊字符）的值为 `{_POSIX_VDISABLE}`，则该功能被禁用；即没有输入数据被识别为禁用的特殊字符。如果未设置 `ICANON`，`{_POSIX_VDISABLE}` 的值对 `c_cc` 数组的 `VMIN` 和 `VTIME` 条目没有特殊含义。

Fn open 后标志和控制字符的初始值根据头文件中的值设置

`#include <sys/ttydefaults.h>`

## 参见

stty(1), tcgetsid(3), tcgetwinsize(3), tcsendbreak(3), tcsetattr(3), tcsetsid(3), [tty(4)](/man/man4/tty.4.md), [uart(4)](/man/man4/uart.4.md), [stack(9)](/man/man9/stack.9.md)

## 缺陷

在 Internet 出现之前，串行端口主要用于来自终端的入站连接，无论是直接还是通过调制解调器，如今串行端口主要用于到设备的出站连接，这一演变不幸地将相关文档分散到三个不同的手册页中：[termios(4)](/man/man4/termios.4.md)、[uart(4)](/man/man4/uart.4.md) [tty(4)](/man/man4/tty.4.md)。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/man4/termios.4.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
