> 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/tty.4.md).

# tty.4

`tty` — 通用终端接口

## 名称

`tty`

## 概要

`#include <sys/ioctl.h>`

## 描述

本节描述系统中终端驱动程序的接口。

### 终端特殊文件

系统上的每个硬件终端端口在 **`/dev/`** 目录中都有多个与之关联的终端特殊设备文件（例如 **`/dev/tty03`** 和 **`/dev/cua03`**）。当用户通过这些硬件终端端口之一登录系统时，系统已经打开了关联的设备，并将线路准备为正常的交互使用（参见 getty(8)）。还有一种特殊情况，终端文件并不连接到硬件终端端口，而是连接到另一侧的另一个程序。这种特殊终端设备称为 *pty*，提供了必要的机制，使得用户通过网络登录时（例如使用 [telnet(1)](/man/man1/telnet.1.md)）能获得相同的系统接口。即使在这些情况下，终端文件如何打开和设置的细节也已由系统中的特殊软件处理。因此，用户通常无需担心这些线路如何打开或使用的细节。此外，这些线路通常用于从系统拨出（通过外呼调制解调器），但系统同样提供了隐藏访问这些终端特殊文件细节的程序（参见 tip(1)）。

当交互用户登录时，系统会将线路准备为以特定方式运行（称为 *线路规程*），其具体细节在命令层级的 stty(1) 和编程层级的 [termios(4)](/man/man4/termios.4.md) 中描述。用户可能需要更改与其特定登录终端相关的设置，对于常见情况应参考前述 man 页面。本 man 页面的其余部分涉及描述低层级使用和控制终端设备的细节，例如希望提供类似于系统所提供功能的程序可能需要的内容。

### 终端文件操作

以下所有操作都通过 ioctl(2) 系统调用发起。关于 *request* 和 *argp* 参数的描述，请参考该 man 页面。除这里定义的 ioctl *request* 外，当前生效的特定线路规程还会定义特定于它的其他 *request*（实际上 [termios(4)](/man/man4/termios.4.md) 将它们定义为函数调用，而非 ioctl *request*）。以下章节列出了可用的 ioctl request。列出了 request 的名称、用途描述以及带类型的 *argp* 参数（如果有）。例如，第一个条目为

> \*TIOCSPGRP int *tpgrp*

并通过以下代码片段在与文件描述符零关联的终端上调用：

```sh
	int pgrp;
	pgrp = getpgrp();
	ioctl(0, TIOCSPGRP, &pgrp);
```

### 终端文件 request 描述

`#include <sys/file.h>`

`#include <sys/ioctl.h>`

**TIOCM\_LE** 线路启用（Line Enable）。 **TIOCM\_DTR** 数据终端就绪（Data Terminal Ready）。 **TIOCM\_RTS** 请求发送（Request To Send）。 **TIOCM\_ST** 辅助发送（Secondary Transmit）。 **TIOCM\_SR** 辅助接收（Secondary Receive）。 **TIOCM\_CTS** 清除发送（Clear To Send）。 **TIOCM\_CAR** 载波检测（Carrier Detect）。 **TIOCM\_CD** 载波检测（同义词）。 **TIOCM\_RNG** 振铃指示（Ring Indication）。 **TIOCM\_RI** 振铃指示（同义词）。 **TIOCM\_DSR** 数据集就绪（Data Set Ready）。

**`TIOCSETD`** `int *ldisc` 此调用已弃用，但为兼容性而保留。在 FreeBSD 8.0 之前，它会切换到 `ldisc` 所指向的新线路规程。

**`TIOCGETD`** `int *ldisc` 在 `ldisc` 所指向的整数中返回当前线路规程。

**`TIOCSBRK`** `void` 将终端硬件设置为 BREAK 状态。

**`TIOCCBRK`** `void` 清除终端硬件的 BREAK 状态。

**`TIOCSDTR`** `void` 置位数据终端就绪（DTR）。

**`TIOCCDTR`** `void` 清除数据终端就绪（DTR）。

**`TIOCGPGRP`** `int *tpgrp` 在 `tpgrp` 所指向的整数中返回与终端关联的当前进程组。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcgetattr 调用的底层调用。

**`TIOCSPGRP`** `int *tpgrp` 将终端与 `tpgrp` 所指向的进程组（作为整数）关联。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcsetattr 调用的底层调用。

**`TIOCGETA`** `struct termios *term` 将与设备关联的 termios 状态的当前值放入 `term` 所指向的 termios 结构中。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcgetattr 调用的底层调用。

**`TIOCSETA`** `struct termios *term` 立即设置与设备关联的 termios 状态。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcsetattr 调用（带 `TCSANOW` 选项）的底层调用。

**`TIOCSETAW`** `struct termios *term` 首先等待任何输出完成，然后设置与设备关联的 termios 状态。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcsetattr 调用（带 `TCSADRAIN` 选项）的底层调用。

**`TIOCSETAF`** `struct termios *term` 首先等待任何输出完成，清除所有挂起的输入，然后设置与设备关联的 termios 状态。这是实现 [termios(4)](/man/man4/termios.4.md) Fn tcsetattr 调用（带 `TCSAFLUSH` 选项）的底层调用。

**`TIOCOUTQ`** `int *num` 将输出队列中的当前字符数放入 `num` 所指向的整数中。

**`TIOCSTI`** `char *cp` 模拟键入输入。假装终端接收到了 `cp` 所指向的字符。

**`TIOCNOTTY`** `void` 过去，当没有控制终端的进程（参见 [termios(4)](/man/man4/termios.4.md) 中的 *控制终端* 部分）首次打开终端设备时，它会将该终端作为其控制终端。对于某些程序来说这是一种隐患，因为它们根本不需要控制终端，而此调用提供了将控制终端与调用进程分离的机制。它*必须*通过打开文件 **`/dev/tty`** 并在该文件描述符上调用 `TIOCNOTTY` 来调用。当前系统不会在 Fn open 调用时为进程分配控制终端：有一个名为 `TIOCSCTTY` 的特定 ioctl 用于将终端设为控制终端。此外，程序可以 Fn fork 并调用 Fn setsid 系统调用，这会将进程置入其自己的会话中——效果是将其与控制终端分离。这是程序失去控制终端的新的、首选方法。但是，环境限制可能禁止进程 Fn fork 并调用 Fn setsid 系统调用以将其与控制终端分离。在这种情况下，必须使用 `TIOCNOTTY`。

**`TIOCSTOP`** `void` 停止终端上的输出（类似于在键盘上键入 ^S）。

**`TIOCSTART`** `void` 启动终端上的输出（类似于在键盘上键入 ^Q）。

**`TIOCSCTTY`** `void` 将终端设为该进程的控制终端（该进程当前必须没有控制终端）。

**`TIOCDRAIN`** `void` 等待直到所有输出排空，或直到排空等待超时到期。

**`TIOCGDRAINWAIT`** `int *timeout` 以秒为单位返回当前的排空等待超时。

**`TIOCSDRAINWAIT`** `int *timeout` 以秒为单位设置排空等待超时。值为零则禁用超时。默认的排空等待超时由可调的 [sysctl(8)](/man/man8/sysctl.8.md) OID `kern.tty_drainwait` 控制。

**`TIOCEXCL`** `void` 在终端上设置独占使用。不允许进一步打开，root 除外。当然，这意味着由 root（或 setuid）运行的程序不会遵守独占设置——这限制了此功能的实用性。

**`TIOCNXCL`** `void` 清除终端的独占使用。允许进一步打开。

**`TIOCFLUSH`** `int *what` 如果 `what` 所指向的 int 值包含 `FREAD` 位（如中定义），则清除输入队列中的所有字符。如果包含 `FWRITE` 位，则清除输出队列中的所有字符。如果该整数值为零，则行为如同同时设置了 `FREAD` 和 `FWRITE` 位（即清除两个队列）。

**`TIOCGWINSIZE`** `struct winsize *ws` 将与终端关联的窗口大小信息放入 `ws` 所指向的 `winsize` 结构中。窗口大小结构包含连接到终端的设备的行数和列数（以及像素数，如适用）。它由用户软件设置，是大多数面向全屏的程序确定屏幕大小的方式。`winsize` 结构由提供

**`TIOCSWINSZ`** `struct winsize *ws` 将与终端关联的窗口大小设置为 `ws` 所指向的 `winsize` 结构中的值（见上文）。

**`TIOCCONS`** `int *on` 如果 `on` 指向非零整数，则将内核控制台输出（内核 printf）重定向到此终端。如果 `on` 指向零整数，则将内核控制台输出重定向回正常控制台。这通常在工作站上用于将内核消息重定向到特定窗口。

**`TIOCMSET`** `int *state` `state` 所指向的整数包含与调制解调器状态对应的位。以下是已定义变量及其所代表调制解调器状态的列表：此调用将终端调制解调器状态设置为 `state` 所表示的状态。并非所有终端都支持此调用。

**`TIOCMGET`** `int *state` 在 `state` 所指向的整数中返回上述调制解调器线路的当前状态。

**`TIOCMBIS`** `int *state` `state` 所指向的整数中的位表示调制解调器状态（如上所述），但该状态会与当前状态进行 OR 操作。

**`TIOCMBIC`** `int *state` `state` 所指向的整数中的位表示调制解调器状态（如上所述），但 `state` 中开启的每一位在终端中都会被清除。

## 实现说明

通过所有终端设备的输入和输出字节总数可通过 `kern.tty_nin` 和 `kern.tty_nout` 只读 [sysctl(8)](/man/man8/sysctl.8.md) 变量获取。

## 参见

stty(1), ioctl(2), [ng\_tty(4)](/man/man4/ng_tty.4.md), [pts(4)](/man/man4/pts.4.md), [pty(4)](/man/man4/pty.4.md), [termios(4)](/man/man4/termios.4.md), [uart(4)](/man/man4/uart.4.md), getty(8)

## 历史

控制台打字机设备 **`/dev/tty`** 和异步通信接口 **`/dev/tty[0-5]`** 首次出现于 Version 1 AT\&T UNIX。

## 缺陷

在互联网出现之前，串口主要用于来自终端的入站连接（直接或通过调制解调器），如今串口主要用于到设备的出站连接，这一演变不幸地将相关文档分散在三个不同的 man 页面中：[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/tty.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.
