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 中進行文件化。