TTY 内部结构

Kopen

这些函数用于从内核空间打开 TTY

void tty_kclose(struct tty_struct *tty)

关闭由 tty_kopen 打开的 tty

参数

struct tty_struct *tty

tty 设备

描述

执行释放和释放 tty 设备的最后步骤。 它与 tty_release_struct() 相同,只是它还在 tty->port 上重置 TTY_PORT_KOPENED 标志。

struct tty_struct *tty_kopen_exclusive(dev_t device)

为内核打开 tty 设备

参数

dev_t device

要打开的设备的 dev_t

描述

专门为内核打开 tty。 执行驱动程序查找,确保它尚未打开并执行首次 tty 初始化。

声明全局 tty_mutex 以序列化
  • 并发首次 tty 初始化

  • 并发 tty 驱动程序删除与查找

  • 并发从驱动程序表中删除 tty

返回值

锁定的初始化 tty_struct

struct tty_struct *tty_kopen_shared(dev_t device)

为内核内共享使用打开 tty 设备

参数

dev_t device

要打开的设备的 dev_t

描述

为内核内使用打开一个已经存在的 tty。 与上面的 tty_kopen_exclusive() 相比,它不确保是唯一用户。

锁定:与上面的 tty_kopen() 相同。


导出的内部函数

int tty_dev_name_to_number(const char *name, dev_t *number)

返回设备名称的 dev_t

参数

const char *name

用户空间中 /dev 下的设备名称

dev_t *number

指向此函数将填充的 dev_t 的指针

描述

此函数将设备名称(如 ttyS0 或 ttyUSB1)转换为 dev_t(如 (4, 64) 或 (188, 1))。 如果未注册相应的驱动程序,则该函数返回 -ENODEV

锁定:这会获取 tty_mutex 以保护 tty_drivers 列表免受

在我们遍历它时被修改,并确保在退出前释放它。

void tty_release_struct(struct tty_struct *tty, int idx)

释放 tty 结构

参数

struct tty_struct *tty

tty 设备

int idx

tty 的索引

描述

执行释放和释放 tty 设备的最后步骤。 它大致是 tty_init_dev() 的逆过程。

int tty_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount)

获取 tty 统计信息

参数

struct tty_struct *tty

tty 设备

struct serial_icounter_struct *icount

输出参数

描述

获取 tty 的 icount 统计信息的副本。

锁定:无(取决于驱动程序)


内部函数

void free_tty_struct(struct tty_struct *tty)

释放不再使用的 tty

参数

struct tty_struct *tty

要释放的 tty 结构

描述

释放写入缓冲区、tty 队列和 tty 内存本身。

锁定:无。 必须在 tty 确定未使用后调用

void tty_free_file(struct file *file)

释放 file->private_data

参数

struct file *file

要释放 private_data 的

描述

这应仅用于故障路径处理,当 tty_add_file 尚未调用时。

struct tty_driver *get_tty_driver(dev_t device, int *index)

查找 tty 的设备

参数

dev_t device

设备标识符

int *index

返回 tty 的索引

描述

此例程返回 tty 驱动程序结构,给定设备编号,并传回索引号。

锁定:调用方必须持有 tty_mutex

struct file *tty_release_redirect(struct tty_struct *tty)

如果存在,则释放 pty 上的重定向

参数

struct tty_struct *tty

tty 设备

描述

这适用于 pty 代码,因此如果主设备关闭,如果从设备是重定向,则它可以释放重定向。

void __tty_hangup(struct tty_struct *tty, int exit_session)

挂断事件的实际处理程序

参数

struct tty_struct *tty

tty 设备

int exit_session

如果非零,则向所有前台组进程发送信号

描述

这可以由“kworker”内核线程调用。 这是进程同步的,但不持有任何锁,因此我们需要确保我们拥有执行操作的相应锁。

挂断事件会清除挂断设备上的任何挂起的重定向。 它确保未来的写入将出错,并且它执行所需的行规程挂断和信号传递。 tty 对象本身保持不变。

锁定
  • BTM

  • 用于撤消重定向的重定向锁

  • 用于操作 tty 列表的文件列表锁

  • 来自调用函数的 tty_ldiscs_lock

  • termios_rwsem 重置 termios 数据

  • tasklist_lock 用于遍历挂断事件的任务列表

  • ->siglock 用于保护 ->signal/->sighand

void tty_vhangup_self(void)

为自己的 ctty 执行进程 vhangup

参数

void

无参数

描述

对当前控制 tty 执行 vhangup

void tty_vhangup_session(struct tty_struct *tty)

挂断会话领导者退出

参数

struct tty_struct *tty

要挂断的 tty

描述

会话领导者正在退出并挂断其控制终端。 前台进程组中的每个进程都会收到 SIGHUP 信号。

我们同步地执行此操作,以便当系统调用返回时,该进程已完成。 出于安全原因,此保证是必要的。

ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to)

tty 设备文件的读取方法

参数

struct kiocb *iocb

内核 I/O 控制块

struct iov_iter *to

读取数据的目标

描述

在此终端设备上执行读取系统调用函数。 在调用线路规程方法之前检查挂断的设备。

锁定

在需要时内部锁定线路规程。 多个读取调用可能会并行挂起。

void tty_write_message(struct tty_struct *tty, char *msg)

向某个 tty 写入消息,而不仅仅是控制台。

参数

struct tty_struct *tty

目标 tty_struct

char *msg

要写入的消息

描述

这用于需要重定向到特定 tty 的消息。 我们现在没有将其放入 syslog 队列,如果真的需要,可能会在将来放入。

目前我们仍然必须持有 BTM 并测试 CLOSING 标志。

此函数已弃用,请勿在新代码中使用。

ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)

tty 设备文件的写入方法

参数

struct kiocb *iocb

内核 I/O 控制块

struct iov_iter *from

带有要写入数据的 iov_iter

描述

通过线路规程将数据写入 tty 设备。

锁定

根据需要锁定线路规程。 对 tty 驱动程序的写入由 atomic_write_lock 序列化,然后以块的形式处理到设备。 对于每个设备,不会并行调用线路规程写入方法。

int tty_send_xchar(struct tty_struct *tty, u8 ch)

发送优先级字符

参数

struct tty_struct *tty

要发送到的 tty

u8 ch

要发送的 xchar

描述

即使已停止,也将高优先级字符发送到 tty。

锁定:xchar 方法没有锁定,write 方法有写入排序。

void pty_line_name(struct tty_driver *driver, int index, char *p)

生成 pty 的名称

参数

struct tty_driver *driver

使用的 tty 驱动程序

int index

次要数字

char *p

至少 6 个字节的输出缓冲区

描述

driver 引用生成一个名称并将其写入输出缓冲区 p

锁定:无

ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)

生成 tty 的名称

参数

struct tty_driver *driver

使用的 tty 驱动程序

int index

次要数字

char *p

至少 7 个字节的输出缓冲区

描述

driver 引用生成一个名称并将其写入输出缓冲区 p

锁定:无

struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, struct file *file, int idx)

查找现有的 tty(如果有)

参数

struct tty_driver *driver

tty 的驱动程序

struct file *file

文件对象

int idx

次要数字

返回值

tty(如果找到)。 如果未找到,则返回 NULLERR_PTR()(如果驱动程序的 lookup() 方法返回错误)。

描述

锁定:必须持有 tty_mutex。 如果找到 tty,则增加 tty kref。

int tty_driver_install_tty(struct tty_driver *driver, struct tty_struct *tty)

在驱动程序中安装 tty 条目

参数

struct tty_driver *driver

tty 的驱动程序

struct tty_struct *tty

tty

描述

将 tty 对象安装到驱动程序表中。 tty->index 字段将在调用此方法时设置。 此方法负责确保分配和配置任何需要的其他结构。

锁定:目前为 tty_mutex

void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty)

从驱动程序表中删除 tty

参数

struct tty_driver *driver

tty 的驱动程序

struct tty_struct *tty

要删除的 tty

描述

从驱动程序表中删除 tty 对象。 tty->index 字段将在调用此方法时设置。

锁定:目前为 tty_mutex

int tty_reopen(struct tty_struct *tty)

快速重新打开打开的 tty

参数

struct tty_struct *tty

要打开的 tty

描述

不允许在主 ptys 上重新打开,并返回 -EIO

锁定:调用方必须持有 tty_lock

返回值

成功时为 0,出错时为 -errno。

struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)

初始化 tty 设备

参数

struct tty_driver *driver

我们正在打开设备的 tty 驱动程序

int idx

设备索引

描述

准备 tty 设备。 这可能不是“新的”干净设备,也可能是活动设备。 pty 驱动程序需要特殊处理,因为这一点。

锁定

该函数在 tty_mutex 下调用,这可以保护我们免受 tty 结构或驱动程序本身消失的影响。

在退出时,tty 设备已连接线路规程,引用计数为 1。 如果为 pty/tty 用途创建了一个对,而另一个是对 pty 主设备,则它也具有 1 的引用计数。

WSH 06/09/97:重写以消除竞争并在打开失败后正确清理。 新代码使用互斥锁保护打开操作,因此非常简单。 对于重新打开 tty 的(最常见)情况,可以放宽互斥锁锁定。

返回值

新的 tty 结构

void tty_flush_works(struct tty_struct *tty)

刷新 tty/pty 对的所有工作

参数

struct tty_struct *tty

要刷新工作的 tty 设备(或 pty 对的任何一端)

描述

同步刷新属于 tty(以及“另一个”tty)的所有工作。

void release_one_tty(struct work_struct *work)

释放 tty 结构内存

参数

struct work_struct *work

我们正在删除的 tty 的工作

描述

释放与 tty 结构关联的内存,并清除驱动程序表槽。 当设备不再使用时,会调用此函数。 当设备的设置失败时,也会调用此函数。

锁定

在处理驱动程序保留的 tty 列表时,会在内部获取文件列表锁。

此方法从工作队列中调用,以便驱动程序专用清理操作可以休眠(至少 USB 需要这样做)

void release_tty(struct tty_struct *tty, int idx)

释放 tty 结构内存

参数

struct tty_struct *tty

tty 设备释放

int idx

tty 设备的索引释放

描述

释放 tty 和可能的链接伙伴(考虑 pty 对),并减少后备模块的引用计数。

锁定

tty_mutex 在处理驱动程序保留的 tty 列表时,会在内部获取文件列表锁。

int tty_release_checks(struct tty_struct *tty, int idx)

在真正释放 tty 之前进行检查

参数

struct tty_struct *tty

要检查的 tty

int idx

tty 的索引

描述

在真正释放 tty 之前执行一些偏执检查。除非定义了 TTY_PARANOIA_CHECK,否则这是一个空操作。

int tty_release(struct inode *inode, struct file *filp)

关闭的 vfs 回调

参数

struct inode *inode

tty 的 inode

struct file *filp

用于处理 tty 的文件指针

描述

每次关闭引用此 tty 的文件句柄时,都会最后一次调用此函数。但是,可能存在多个此类引用。

锁定

获取 BKL。请参阅 tty_release_dev()。

即使释放 tty 结构也是一件棘手的事情。我们必须非常小心,确保所有结构同时释放,否则中断可能会得到错误的指针。

WSH 09/09/97:重写以避免一些可能导致双重释放或释放仍在使用的内存的糟糕的竞争条件。

struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp)

获取当前任务的锁定 tty

参数

dev_t device

设备号

struct file *filp

指向 tty 的文件指针

返回值

仅当 device 是 /dev/tty 时,当前任务的锁定 tty

描述

执行当前任务的控制 tty 的重新打开。

我们无法像其他节点一样返回驱动程序和索引,因为 devpts 将无法工作。它期望 inode 来自 devpts FS。

struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, int *index)

查找给定设备文件的 tty 驱动程序

参数

dev_t device

设备号

struct file *filp

指向 tty 的文件指针

int *index

return 驱动程序中设备的索引

描述

如果返回值没有错误,则调用者有责任通过 tty_driver_kref_put() 来减少引用计数。

锁定:tty_mutex 保护 get_tty_driver()

返回值

此 inode 的驱动程序(引用计数增加)

struct tty_struct *tty_open_by_driver(dev_t device, struct file *filp)

打开 tty 设备

参数

dev_t device

要打开的设备的 dev_t

struct file *filp

指向 tty 的文件指针

描述

执行驱动程序查找,检查重新打开,或者执行首次 tty 初始化。

声明全局 tty_mutex 进行序列化
  • 并发首次 tty 初始化

  • 并发 tty 驱动程序删除与查找

  • 并发从驱动程序表中删除 tty

返回值

锁定初始化的或重新打开的 tty_struct

int tty_open(struct inode *inode, struct file *filp)

打开 tty 设备

参数

struct inode *inode

设备文件的 inode

struct file *filp

指向 tty 的文件指针

描述

tty_open()tty_release() 会保持 tty 计数,其中包含在 tty 上完成的打开次数。我们不能使用 inode 计数,因为不同的 inode 可能指向同一个 tty。

pty 主设备以及跟踪串行线路需要打开计数:当发生最后一次关闭时,DTR 会被丢弃。(现在不只是通过 tty->count 完成。 - Ted 1/27/92)

pty 的 termios 状态在第一次打开时被重置,以便设置不会跨重用而持续存在。

锁定

注意

由于 tty_mutex,没有引用的 tty_unlock/lock 情况才是安全的

__poll_t tty_poll(struct file *filp, poll_table *wait)

检查 tty 状态

参数

struct file *filp

正在轮询的文件

poll_table *wait

要更新的轮询等待结构

描述

调用线路规程轮询方法以获取设备的轮询状态。

锁定:锁定的线路规程,但其他调用者可以自由地重新进入 ldisc 轮询方法。

int tiocsti(struct tty_struct *tty, u8 __user *p)

伪造输入字符

参数

struct tty_struct *tty

伪造输入到 tty 中

u8 __user *p

指向字符的指针

描述

伪造到 tty 设备的输入。执行必要的锁定和输入管理。

FIXME:不遵守流量控制?

锁定
  • 调用的函数获取 tty_ldiscs_lock

  • current->signal->tty 检查在没有锁的情况下是安全的

int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)

实现窗口查询 ioctl

参数

struct tty_struct *tty

tty

struct winsize __user *arg

用于结果的用户缓冲区

描述

将窗口大小的内核概念复制到用户缓冲区中。

锁定:获取 tty->winsize_mutex 以确保 winsize 数据的一致性。

int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)

实现窗口大小设置 ioctl

参数

struct tty_struct *tty

tty 侧的 tty

struct winsize __user *arg

用于结果的用户缓冲区

描述

将用户对窗口大小的看法复制到内核。传统上,这只是咨询信息,但对于 Linux 控制台,它实际上具有驱动程序级别的含义并触发 VC 大小调整。

锁定

与驱动程序相关。默认的 do_resize 方法采用 tty termios 互斥锁和 ctrl.lock。控制台获取自己的锁,然后调用默认方法。

int tioccons(struct file *file)

允许管理员移动逻辑控制台

参数

struct file *file

要成为控制台的文件

描述

允许管理员移动重定向的控制台设备。

锁定:使用 redirect_lock 来保护重定向信息

int tiocsetd(struct tty_struct *tty, int __user *p)

设置线路规程

参数

struct tty_struct *tty

tty 设备

int __user *p

指向用户数据的指针

描述

根据用户请求设置线路规程。

锁定:请参阅 tty_set_ldisc(),此函数只是一个辅助函数

int tiocgetd(struct tty_struct *tty, int __user *p)

获取线路规程

参数

struct tty_struct *tty

tty 设备

int __user *p

指向用户数据的指针

描述

直接从 ldisc 中检索线路规程 ID。

锁定:等待 ldisc 引用(以防线路规程正在更改或 tty 正在挂断)

int send_break(struct tty_struct *tty, unsigned int duration)

执行的定时中断

参数

struct tty_struct *tty

要中断的设备

unsigned int duration

超时(毫秒)

描述

在缺乏自身驱动程序级别定时中断功能的硬件上执行定时中断。

锁定

tty->atomic_write_lock 序列化

int tty_tiocmget(struct tty_struct *tty, int __user *p)

获取调制解调器状态

参数

struct tty_struct *tty

tty 设备

int __user *p

指向结果的指针

描述

如果支持此功能,则从 tty 驱动程序获取调制解调器状态位。如果不可用,则返回 -ENOTTY

锁定:无(取决于驱动程序)

int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, unsigned __user *p)

设置调制解调器状态

参数

struct tty_struct *tty

tty 设备

unsigned int cmd

命令 - 清除位、设置位或设置所有位

unsigned __user *p

指向所需位的指针

描述

如果支持此功能,则从 tty 驱动程序设置调制解调器状态位。如果不可用,则返回 -ENOTTY

锁定:无(取决于驱动程序)

struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)

分配新的 tty

参数

struct tty_driver *driver

将处理返回的 tty 的驱动程序

int idx

tty 的次要设备号

描述

此子程序分配并初始化一个 tty 结构。

锁定:无 - 此刻不会公开相关 tty