N_TTY

預設(和回退)TTY 行規程。 它嘗試按照 POSIX 的規定處理字元。

外部函式

void n_tty_inherit_ops(struct tty_ldisc_ops *ops)

繼承 N_TTY 方法

引數

struct tty_ldisc_ops *ops

struct tty_ldisc_ops 在哪裡儲存 N_TTY 方法

允許“子類”行規程“繼承”N_TTY 方法。

內部函式

void n_tty_kick_worker(const struct tty_struct *tty)

啟動輸入工作程序(如果需要)

引數

const struct tty_struct *tty

終端

描述

如果翻轉緩衝區工作可能已停止,則重新安排它。

鎖定
  • 呼叫者持有獨佔 termios_rwsem,或者

  • n_tty_read()/消費者路徑

    持有非獨佔 termios_rwsem

void n_tty_write_wakeup(struct tty_struct *tty)

非同步 I/O 通知器

引數

struct tty_struct *tty

tty 裝置

描述

ptys、序列驅動等需要它。因為附加到主裝置並依賴 ASYNC IO 的程序必須被喚醒。

void put_tty_queue(u8 c, struct n_tty_data *ldata)

將字元新增到 tty

引數

u8 c

字元

struct n_tty_data *ldata

n_tty 資料

描述

將字元新增到 tty read_buf 佇列。

鎖定
  • n_tty_receive_buf()/生產者路徑

    呼叫者持有非獨佔 termios_rwsem

void reset_buffer_flags(struct n_tty_data *ldata)

重置緩衝區狀態

引數

struct n_tty_data *ldata

要重置的行規程資料

描述

重置讀取緩衝區計數器並清除標誌。從 n_tty_open()n_tty_flush_buffer() 呼叫。

鎖定
  • 呼叫者持有獨佔 termios_rwsem,或者

  • (不需要鎖定)

void n_tty_flush_buffer(struct tty_struct *tty)

清除輸入佇列

引數

struct tty_struct *tty

終端裝置

描述

重新整理輸入緩衝區。當 tty 層想要重新整理緩衝區(例如在結束通話時)或者 N_TTY 行規程內部必須清除掛起的佇列(例如某些訊號)時呼叫。

持有 termios_rwsem 以排除生產者/消費者,同時重置緩衝區索引。

鎖定:ctrl.lock,獨佔 termios_rwsem

int is_utf8_continuation(u8 c)

utf8 多位元組檢查

引數

u8 c

要檢查的位元組

返回值

如果 utf8 字元 c 是多位元組延續字元,則為 true。 我們使用它來正確計算列印時字元的螢幕大小。

int is_continuation(u8 c, const struct tty_struct *tty)

多位元組檢查

引數

u8 c

要檢查的位元組

const struct tty_struct *tty

終端裝置

返回值

如果 utf8 字元 c 是多位元組延續字元並且終端處於 unicode 模式,則為 true。

int do_output_char(u8 c, struct tty_struct *tty, int space)

輸出一個字元

引數

u8 c

字元(或部分 unicode 符號)

struct tty_struct *tty

終端裝置

int space

tty 驅動程式寫入緩衝區中的可用空間

描述

這是一個輔助函式,用於處理一個輸出字元(包括 TAB、CR、LF 等特殊字元),進行 OPOST 處理並將結果放入 tty 驅動程式的寫入緩衝區。

請注意,Linux 目前忽略 TABDLY、CRDLY、VTDLY、FFDLY 和 NLDLY。 它們在今天的世界中根本不相關。 如果您需要它們,請在此處新增它們。

鎖定:應在 output_lock 下呼叫,以保護列狀態和緩衝區中的剩餘空間。

返回值

使用的緩衝區空間的位元組數,如果剩餘空間為 0,則為 -1。

int process_output(u8 c, struct tty_struct *tty)

輸出後處理器

引數

u8 c

字元(或部分 unicode 符號)

struct tty_struct *tty

終端裝置

描述

使用 OPOST 處理輸出一個字元。

鎖定:output_lock 用於保護列狀態和剩餘空間(此外,這是從 tty 層的寫入鎖下的 n_tty_write() 中呼叫的)。

返回值

當輸出裝置已滿且必須重試字元時為 -1。

ssize_t process_output_block(struct tty_struct *tty, const u8 *buf, unsigned int nr)

塊後處理器

引數

struct tty_struct *tty

終端裝置

const u8 *buf

字元緩衝區

unsigned int nr

要輸出的位元組數

描述

使用 OPOST 處理輸出一個字元塊。

此路徑用於加速塊控制檯寫入,以及在處理塊輸出資料時。 它僅處理通常發現的簡單情況,並有助於為控制檯驅動程式生成符號塊,從而提高效能。

鎖定:output_lock 用於保護列狀態和剩餘空間(此外,這是從 tty 層的寫入鎖下的 n_tty_write() 中呼叫的)。

返回值

輸出的字元數。

size_t __process_echoes(struct tty_struct *tty)

寫入掛起的回顯字元

引數

struct tty_struct *tty

終端裝置

描述

將先前緩衝的回顯(以及其他 ldisc 生成的)字元寫入 tty。

由 ldisc 生成的字元(包括回顯)需要緩衝,因為驅動程式的寫入緩衝區在大量程式輸出期間可能會被填滿。 在這些條件下,直接回顯到驅動程式通常會失敗,導致字元丟失並導致 ldisc 狀態資訊不匹配。

由於 ldisc 狀態必須表示寫入時實際傳送到驅動程式的字元,因此列狀態中的某些更改等操作也會儲存在緩衝區中並在此處執行。

使用迴圈 fifo 緩衝區,以便優先處理最近的字元。 此外,當使用帶有字首“^”的回顯控制字元時,該對會被原子處理,因此不會分開。

鎖定:呼叫者必須持有 output_lock

void add_echo_byte(u8 c, struct n_tty_data *ldata)

將位元組新增到回顯緩衝區

引數

u8 c

要回顯的 unicode 位元組

struct n_tty_data *ldata

n_tty 資料

描述

將字元或操作位元組新增到回顯緩衝區。

void echo_move_back_col(struct n_tty_data *ldata)

新增向後移動一列的操作

引數

struct n_tty_data *ldata

n_tty 資料

描述

新增一個操作到回顯緩衝區,向後移動一列。

void echo_set_canon_col(struct n_tty_data *ldata)

新增一個操作來設定規範列

引數

struct n_tty_data *ldata

n_tty 資料

描述

新增一個操作到回顯緩衝區,將規範列設定為當前列。

void echo_erase_tab(unsigned int num_chars, int after_tab, struct n_tty_data *ldata)

新增一個操作來擦除一個 tab

引數

unsigned int num_chars

已使用的字元列數

int after_tab

如果 num_chars 在先前的 tab 之後開始,則為 true

struct n_tty_data *ldata

n_tty 資料

描述

新增一個操作到回顯緩衝區,以擦除一個 tab。

由橡皮擦函式呼叫,該函式知道自先前的 tab 或輸入開始以來已使用了多少個字元列。 此資訊稍後將與規範列(如果適用)一起使用,以返回正確的列數。

void echo_char_raw(u8 c, struct n_tty_data *ldata)

原始回顯字元

引數

u8 c

要回顯的 unicode 位元組

struct n_tty_data *ldata

行規程資料

描述

將使用者輸入回顯到螢幕上。 只有當 L_ECHO(tty) 為 true 時才能呼叫此函式。 從 tty_driver.receive_buf() 路徑呼叫。

此變體不會特別處理控制字元。

void echo_char(u8 c, const struct tty_struct *tty)

回顯一個字元

引數

u8 c

要回顯的 unicode 位元組

const struct tty_struct *tty

終端裝置

描述

將使用者輸入回顯到螢幕上。 只有當 L_ECHO(tty) 為 true 時才能呼叫此函式。 從 tty_driver.receive_buf() 路徑呼叫。

此變體標記控制字元以回顯為“^X”(其中 X 是表示控制字元的字母)。

void finish_erasing(struct n_tty_data *ldata)

完成擦除

引數

struct n_tty_data *ldata

n_tty 資料

void eraser(u8 c, const struct tty_struct *tty)

處理擦除功能

引數

u8 c

字元輸入

const struct tty_struct *tty

終端裝置

描述

當來自驅動程式層的流中存在擦除字元時,執行擦除和必要的輸出。 處理 UTF-8 多位元組符號的複雜性。

鎖定:n_tty_receive_buf()/生產者路徑

呼叫者持有非獨佔 termios_rwsem

void isig(int sig, struct tty_struct *tty)

處理 ISIG 選項

引數

int sig

訊號

struct tty_struct *tty

終端

描述

當由於終端輸入而傳送訊號時呼叫。 從 tty_driver.receive_buf() 路徑呼叫,因此被序列化。

如果 !NOFLSH,則執行輸入和輸出重新整理。 在這種情況下,回顯緩衝區是“輸出”。 首先處理訊號,以提醒任何當前讀者或作者停止並退出他們的 i/o 迴圈。

鎖定:ctrl.lock

void n_tty_receive_break(struct tty_struct *tty)

處理中斷

引數

struct tty_struct *tty

終端

描述

在傳入的位元流中點選了 RS232 中斷事件。 根據 termios 設定,這可能會導致各種事件。

鎖定:n_tty_receive_buf()/生產者路徑

呼叫者持有非獨佔 termios_rwsem

注意

如果重新整理輸入緩衝區,則可能獲得獨佔 termios_rwsem

void n_tty_receive_overrun(const struct tty_struct *tty)

處理溢位報告

引數

const struct tty_struct *tty

終端

描述

資料到達的速度比我們處理的速度快。 雖然 tty 驅動程式已標記此問題,但錯過的位將永遠消失。

從 receive_buf 路徑呼叫,因此是單執行緒的。 不需要鎖定,因為 num_overrun 和 overrun_time 是函式私有的。

void n_tty_receive_parity_error(const struct tty_struct *tty, u8 c)

錯誤通知器

引數

const struct tty_struct *tty

終端裝置

u8 c

字元

描述

處理奇偶校驗錯誤並排隊正確的資料,以在必要時指示錯誤情況。

鎖定:n_tty_receive_buf()/生產者路徑

呼叫者持有非獨佔 termios_rwsem

bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, u8 c, bool lookahead_done)

接收流控制字元

引數

struct tty_struct *tty

終端裝置

u8 c

字元

bool lookahead_done

前瞻已經處理了這個字元

描述

接收和處理流控制字元操作。

如果流控制字元的前瞻已經在正常接收之前提前處理了該字元,則在正常接收期間會跳過這些操作。

如果 c 作為流控制字元被消耗,則返回 true,該字元不能被視為正常字元。

void n_tty_receive_char(struct tty_struct *tty, u8 c)

執行處理

引數

struct tty_struct *tty

終端裝置

u8 c

字元

描述

處理從驅動程式收到的輸入的單個字元。 透過上述驅動程式的規則,這會相對於自身進行序列化。

鎖定:n_tty_receive_buf()/生產者路徑

呼叫者持有非獨佔 termios_rwsem,如果規範模式處於活動狀態,則釋出 canon_head

size_t n_tty_receive_buf_common(struct tty_struct *tty, const u8 *cp, const u8 *fp, size_t count, bool flow)

處理輸入

引數

struct tty_struct *tty

裝置接收輸入

const u8 *cp

輸入字元

const u8 *fp

每個字元的標誌(如果 NULL,所有字元都是 TTY_NORMAL

size_t count

cp 中的輸入字元數

bool flow

啟用流量控制

描述

當收到字元塊時,由終端驅動程式呼叫。 必須從軟上下文中呼叫此函式,而不是從中斷上下文中呼叫。 驅動程式負責一次一個地按順序呼叫(或使用 flush_to_ldisc())。

在規範模式下,最大行長度為 4096 個字元(包括行終止字元); 長於 4096 個字元的行將被截斷。 在 4095 個字元之後,輸入資料仍然被處理但不儲存。 溢位處理確保 tty 始終可以接收更多輸入,直到至少可以讀取一行。

在非規範模式下,讀取緩衝區只會接受 4095 個字元; 如果輸入模式切換到規範模式,這將為換行符提供必要的空間。

請注意,在非規範模式下,讀取緩衝區可能會_包含_ 4096 個字元:當模式切換到非規範模式時,讀取緩衝區可能已經包含規範行的大值 4096 個字元。

鎖定:n_tty_receive_buf()/生產者路徑

宣告非獨佔 termios_rwsem 釋出 commit_head 或 canon_head

返回值

處理的來自 cp 的輸入字元數。

void n_tty_set_termios(struct tty_struct *tty, const struct ktermios *old)

termios 資料已更改

引數

struct tty_struct *tty

終端

const struct ktermios *old

先前的資料

描述

當用戶更改 termios 標誌時,tty 層會呼叫此函式,以便行規程可以提前計劃。 此函式無法休眠,並且受 tty 層的保護,免於重新進入。 使用者可以保證,當 ldisc 關閉時,此函式不會被重新進入或正在進行中。

鎖定:呼叫者持有 tty->termios_rwsem

void n_tty_close(struct tty_struct *tty)

關閉此 tty 的 ldisc

引數

struct tty_struct *tty

裝置

描述

當由於關閉或紀律變更而關閉此行規程時,從終端層呼叫。 當其他 ldisc 方法正在進行時,不會呼叫該函式。

int n_tty_open(struct tty_struct *tty)

開啟 ldisc

引數

struct tty_struct *tty

要開啟的終端

描述

當此行規程附加到終端裝置時呼叫。 可以休眠。 序列呼叫,以便不會並行發生其他事件。 在關閉之前不會發生進一步的開啟。

bool copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, size_t *nr)

直接複製讀取資料

引數

const struct tty_struct *tty

終端裝置

u8 **kbp

資料

size_t *nr

資料大小

描述

輔助函式,用於加速 n_tty_read()。僅當 ICANON 關閉時呼叫;它直接從 tty 佇列複製字元。

鎖定
  • ldata->atomic_read_lock sem 下呼叫

  • n_tty_read()/消費者路徑

    呼叫者持有非獨佔的 termios_rwsem;read_tail 已釋出

返回值

如果成功複製了資料,但仍有更多資料可以獲取,則為 true。

bool canon_copy_from_read_buf(const struct tty_struct *tty, u8 **kbp, size_t *nr)

以規範模式複製讀取資料

引數

const struct tty_struct *tty

終端裝置

u8 **kbp

資料

size_t *nr

資料大小

描述

用於 n_tty_read() 的輔助函式。僅當 ICANON 開啟時呼叫;它將一行輸入(包括行分隔符)複製到結果緩衝區中。

鎖定
  • atomic_read_lock 互斥鎖下呼叫

  • n_tty_read()/消費者路徑

    呼叫者持有非獨佔的 termios_rwsem;read_tail 已釋出

注意

當 termios 從非規範模式更改為規範模式並且讀取緩衝區包含資料時,n_tty_set_termios() 模擬 EOF 推送(就像輸入 C-d 一樣),但緩衝區中 _沒有_ DISABLED_CHAR。這會導致已經作為輸入處理的資料立即可用作輸入,即使尚未收到換行符。

int job_control(struct tty_struct *tty, struct file *file)

檢查作業控制

引數

struct tty_struct *tty

tty

struct file *file

檔案控制代碼

描述

對此 file/tty 描述符執行作業控制管理檢查,如果適用,則傳送任何需要的訊號,如果應該採取操作,則返回負錯誤程式碼。

鎖定
  • 重定向寫入測試是安全的

  • current->signal->tty 檢查是安全的

  • ctrl.lock 用於安全地引用 tty->ctrl.pgrp

ssize_t n_tty_read(struct tty_struct *tty, struct file *file, u8 *kbuf, size_t nr, void **cookie, unsigned long offset)

tty 的讀取函式

引數

struct tty_struct *tty

tty 裝置

struct file *file

檔案物件

u8 *kbuf

核心空間緩衝區指標

size_t nr

I/O 大小

void **cookie

如果非 NULL,則這是一個繼續讀取

unsigned long offset

從哪裡繼續讀取(在 n_tty 中未使用)

描述

執行線路規程的讀取。我們保證線路規程不會在我們之下關閉,但我們可能會獲得多個並行讀取器,並且必須自己處理此問題。我們可能還會遇到結束通話。始終在使用者上下文中呼叫,可能會休眠。

此程式碼必須確保永遠不會在結束通話時休眠。

鎖定:n_tty_read()/consumer 路徑

宣告非獨佔的 termios_rwsem;釋出 read_tail

ssize_t n_tty_write(struct tty_struct *tty, struct file *file, const u8 *buf, size_t nr)

tty 的寫入函式

引數

struct tty_struct *tty

tty 裝置

struct file *file

檔案物件

const u8 *buf

使用者空間緩衝區指標

size_t nr

I/O 大小

描述

終端裝置的寫入函式。它與其他寫入呼叫者序列化,但不與 termios 更改、讀取和其他此類事件序列化。由於接收程式碼將回顯字元,從而呼叫驅動程式的寫入方法,因此 output_lock 在此處呼叫的輸出處理函式以及回顯處理函式中使用,以保護列狀態和緩衝區中剩餘的空間。

此程式碼必須確保永遠不會在結束通話時休眠。

鎖定:output_lock 用於保護列狀態和剩餘空間

(請注意,process_output*() 函式本身會獲取此鎖)

__poll_t n_tty_poll(struct tty_struct *tty, struct file *file, poll_table *wait)

N_TTY 的 poll 方法

引數

struct tty_struct *tty

終端裝置

struct file *file

訪問它的檔案

poll_table *wait

輪詢表

描述

當要求線路規程對資料或特殊事件進行 poll() 時呼叫。此程式碼與其他事件(儲存開啟/關閉)序列化。

此程式碼必須確保永遠不會在結束通話時休眠。

鎖定:在沒有核心鎖的情況下呼叫 -- 很好。