TTY 结构体

struct tty_struct 由 TTY 层在 TTY 设备的第一次打开时分配,并在最后一次关闭后释放。 TTY 层将此结构传递给 struct tty_operation 的大多数钩子。 tty_struct 的成员记录在底部的TTY 结构体参考中。

初始化

void tty_init_termios(struct tty_struct *tty)

termios 设置的助手

参数

struct tty_struct *tty

要设置的 tty

描述

初始化此 tty 的 termios 结构。 这当前在 tty_mutex 下运行,因此我们可以放松对排序的要求。

名称

const char *tty_name(const struct tty_struct *tty)

返回 tty 命名

参数

const struct tty_struct *tty

tty 结构体

描述

将 tty 结构转换为名称。 该名称反映了内核命名策略,如果正在使用 udev,则可能无法反映用户空间

锁定:无

引用计数

struct tty_struct *tty_kref_get(struct tty_struct *tty)

获取 tty 引用

参数

struct tty_struct *tty

tty 设备

返回

对 tty 对象的新引用

描述

锁定:调用者必须持有足够的锁/计数以确保其现有引用不会消失。

void tty_kref_put(struct tty_struct *tty)

释放 tty kref

参数

struct tty_struct *tty

tty 设备

描述

释放对 tty 设备的引用,并在需要时让 kref 层为我们销毁该对象。

安装

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

通常的 tty->ops->install

参数

struct tty_driver *driver

tty 的驱动程序

struct tty_struct *tty

tty

描述

如果 driver 覆盖了 tty->ops->install,它仍然可以调用此函数来执行标准安装操作。

读 & 写

int tty_put_char(struct tty_struct *tty, u8 ch)

将一个字符写入 tty

参数

struct tty_struct *tty

tty

u8 ch

要写入的字符

描述

如果存在,使用提供的 tty->ops->put_char() 方法将一个字节写入 tty

注意

驱动程序层中的特定 put_char 操作可能很快就会消失。 不要直接调用它,请使用此方法

返回

成功输出的字符数。

启动 & 停止

void stop_tty(struct tty_struct *tty)

传播流量控制

参数

struct tty_struct *tty

要停止的 tty

描述

对驱动程序执行流量控制。 可以在已经停止的设备上调用,并且不会重新调用 tty_driver->stop() 方法。

此功能由线路规程用于停止传入流量,并由驱动程序使用。 因此,它可以在任何上下文中调用,可能在 tty atomic_write_lock 下,但并非总是如此。

锁定

flow.lock

void start_tty(struct tty_struct *tty)

传播流量控制

参数

struct tty_struct *tty

要启动的 tty

描述

如果可能,启动已停止的 tty。 如果先前已停止的 tty 现在正在启动,则调用 tty_driver->start() 方法并唤醒线路规程。

锁定

flow.lock

唤醒

void tty_wakeup(struct tty_struct *tty)

请求更多数据

参数

struct tty_struct *tty

终端

描述

tty 唤醒的内部和外部助手。 此函数通知线路规程(如果存在),该驱动程序已准备好接收更多输出数据。

挂断

void tty_hangup(struct tty_struct *tty)

触发挂断事件

参数

struct tty_struct *tty

要挂断的 tty

描述

tty 上发生了载波丢失(虚拟或其他)。 安排在此事件之后运行的挂断序列。

void tty_vhangup(struct tty_struct *tty)

处理 vhangup

参数

struct tty_struct *tty

要挂断的 tty

描述

用户已通过系统调用要求挂断终端。 我们同步执行此操作,以便系统调用返回时,该过程完成。 这种保证对于安全原因来说是必要的。

int tty_hung_up_p(struct file *filp)

tty 是否挂断

参数

struct file *filp

tty 的文件指针

返回

如果 tty 已经受到 vhangup 或载波丢失,则为 true

其他

int tty_do_resize(struct tty_struct *tty, struct winsize *ws)

resize 事件

参数

struct tty_struct *tty

正在调整大小的 tty

struct winsize *ws

新尺寸

描述

更新 termios 变量并发送必要的信号以正确执行终端大小调整。

TTY 结构体标志

enum tty_struct_flags

TTY 结构体标志

常量

TTY_THROTTLED

驱动程序输入已节流。 ldisc 应调用 tty_driver.unthrottle(),以便在准备好处理更多数据时(在最小阈值时)恢复接收。

TTY_IO_ERROR

如果设置,会导致 tty 上的所有后续用户空间读/写调用失败,并返回 -EIO。(可能也没有 ldisc。)

TTY_OTHER_CLOSED

设备是一个 pty,另一侧已关闭。

TTY_EXCLUSIVE

独占打开模式(单个打开者)。

TTY_DO_WRITE_WAKEUP

如果设置,会导致驱动程序调用 tty_ldisc_ops.write_wakeup() 方法,以便在它可以接受更多数据进行传输时恢复传输。

TTY_LDISC_OPEN

指示线路规程已打开。 仅用于调试目的。

TTY_PTY_LOCK

pty 代码的私有标志,用于实现 TIOCSPTLCK/TIOCGPTLCK 逻辑。

TTY_NO_WRITE_SPLIT

防止驱动程序将写入拆分为更小的块(将写入边界保留给驱动程序)。

TTY_HUPPED

TTY 已挂断。 这是在 tty_driver.hangup() 之后设置的。

TTY_HUPPING

TTY 正在挂断以中止潜在的读者。

TTY_LDISC_CHANGING

正在更改此 TTY 的线路规程。 设置此项时,I/O 不应阻塞。 使用 tty_io_nonblock() 进行检查。

TTY_LDISC_HALTED

此 TTY 的线路规程已停止。 不应将任何工作排队到此 ldisc。

描述

这些位在 tty_struct.flags 字段中使用。

为了使中断无法破坏队列,copy_to_cooked 必须相对于自身是原子的,tty->write 也必须如此。 因此,您必须使用内联函数 set_bit()clear_bit() 使其成为原子。

TTY结构体参考

struct tty_struct

与tty打开时相关的状态

定义:

struct tty_struct {
    struct kref kref;
    int index;
    struct device *dev;
    struct tty_driver *driver;
    struct tty_port *port;
    const struct tty_operations *ops;
    struct tty_ldisc *ldisc;
    struct ld_semaphore ldisc_sem;
    struct mutex atomic_write_lock;
    struct mutex legacy_mutex;
    struct mutex throttle_mutex;
    struct rw_semaphore termios_rwsem;
    struct mutex winsize_mutex;
    struct ktermios termios, termios_locked;
    char name[64];
    unsigned long flags;
    int count;
    unsigned int receive_room;
    struct winsize winsize;
    struct {
        spinlock_t lock;
        bool stopped;
        bool tco_stopped;
    } flow;
    struct {
        struct pid *pgrp;
        struct pid *session;
        spinlock_t lock;
        unsigned char pktstatus;
        bool packet;
    } ctrl;
    bool hw_stopped;
    bool closing;
    int flow_change;
    struct tty_struct *link;
    struct fasync_struct *fasync;
    wait_queue_head_t write_wait;
    wait_queue_head_t read_wait;
    struct work_struct hangup_work;
    void *disc_data;
    void *driver_data;
    spinlock_t files_lock;
    int write_cnt;
    u8 *write_buf;
    struct list_head tty_files;
    struct work_struct SAK_work;
};

成员

kref

通过 tty_kref_get()tty_kref_put() 进行引用计数,当达到零时释放该结构体

index

此tty的索引(例如,构造像tty12这样的 **name**)

dev

类设备或 NULL (例如,ptys, serdev)

driver

操作此tty的struct tty_driver

port

此设备的持久性存储(即 struct tty_port

ops

此tty的 driverstruct tty_operations (open,close等)

ldisc

此tty的当前线路规程(默认为n_tty)

ldisc_sem

保护线路规程更改(**ldisc**)-- 锁定tty而不是pty

atomic_write_lock

防止并发写入者,即锁定 **write_cnt**,**write_buf** 等

legacy_mutex

历史遗留(BKL -> BTM -> **legacy_mutex**),保护对此tty的几个操作

throttle_mutex

防止并发的 tty_throttle_safe()tty_unthrottle_safe() (但不是 tty_unthrottle())

termios_rwsem

保护 **termios** 和 **termios_locked**

winsize_mutex

保护 **winsize**

termios

当前tty的termios,从/到 **driver.termios** 复制

termios_locked

锁定的termios(通过 TIOCGLCKTRMIOSTIOCSLCKTRMIOS ioctl)

name

tty_line_name() 构造的tty的名称 (例如,ttyS3)

flags

TTY_THROTTLED, TTY_IO_ERROR 等的按位或

count

打开进程的计数,达到零会取消此tty的所有工作并删除一个 **kref**(但不会释放此tty)

receive_room

允许提供给 **ldisc** 而不会丢失的字节数

winsize

终端“窗口”的大小(参见 **winsize_mutex**)

flow

流设置分组在一起

flow.lock

**flow** 成员的锁

flow.stopped

stop_tty()/start_tty() 停止/启动的tty

flow.tco_stopped

TCOOFF/TCOON ioctl 停止/启动的tty(它优先于 **flow.stopped**)

ctrl

控制设置分组在一起

ctrl.pgrp

此tty的进程组(setpgrp(2))

ctrl.session

此tty的会话(setsid(2))。写入受 **ctrl.lock** 和 **legacy_mutex** 的保护,读取器必须至少使用其中一个。

ctrl.lock

**ctrl** 成员的锁

ctrl.pktstatus

数据包模式状态(TIOCPKT_ 常量的按位或)

ctrl.packet

已启用数据包模式

hw_stopped

不受tty层控制,在 **driver** 的控制下处理CTS

closing

在关闭期间设置时,n_tty仅处理START & STOP字符

flow_change

控制节流的行为,请参见 tty_throttle_safe()tty_unthrottle_safe()

link

链接到另一个pty(master -> slave 反之亦然)

fasync

O_ASYNC 的状态(对于 SIGIO); 由 fasync_helper() 管理

write_wait

并发的写入者在此队列中等待,直到允许他们写入

read_wait

读取者在此队列中等待数据

hangup_work

通常是执行挂起的工作(do_tty_hangup()); 在释放tty时,(重新)用于 release_one_tty()

disc_data

指向 **ldisc** 的私有数据的指针(例如,指向 struct n_tty_data

driver_data

指向 **driver** 的私有数据的指针(例如,struct uart_state

files_lock

保护 **tty_files** 列表

write_cnt

tty_write() 中写入到 **write_buf** 的字节数

write_buf

tty_write() 期间用于将用户数据复制到的临时缓冲区

tty_files

此tty的(重新)打开者的列表(即链接的 struct tty_file_private

SAK_work

如果tty有一个待处理的do_SAK,它将在此处排队

描述

与tty打开时相关的全部状态。tty设备的持久性存储在此处作为 **port** 引用,并在 struct tty_port 中进行文档化。