日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux tty core code,linux tty core 源码分析(7)

發布時間:2023/12/15 linux 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux tty core code,linux tty core 源码分析(7) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

套接字和終端通常都具有異步通知機制,即應用程序可以在數據可用的時候接收到一個信號SIGIO而不需要去輪詢關注的數據。但是當對于多個數據源時,應用不能區分SIGIO的來源。為了實現異步通知機制,應用程序需要為數據源設置一個屬主進程即用fcntl的F_SETOWN來設置屬主進程,以及用fcntl的F_SETFL設置FASYNC標志來開啟文件的異步通知機制。

終端設備是tty設備的一種,其異步通知機制的實現在驅動中是分布的:

1)首先在F_SETOWN被調用時對filp->owner賦值。

2)文件打開時默認FASYNC標志是清除的,當設置這個標志式調用fasync方法。fasync方法依賴于struct fasync_struct 結構和fasync_helper函數。下面具體分析該函數:

static DEFINE_RWLOCK(fasync_lock);

static struct kmem_cache *fasync_cache __read_mostly;

/*

* fasync_helper() is used by some character device drivers (mainly mice)

* to set up the fasync queue. It returns negative on error, 0 if it did

* no changes and positive if it added/deleted the entry.

*/

//fasync_helper從相關的進程列表中增加或刪除文件,on為0表示刪除,非0表示增加int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)

{

struct fasync_struct *fa, **fp;

struct fasync_struct *new = NULL;

int result = 0;

//若在進程列表中增加文件則從后備高速緩存中分配一個struct fasync_struct 結構

if (on) {

new = kmem_cache_alloc(fasync_cache, GFP_KERNEL);

if (!new)

return -ENOMEM;

}

write_lock_irq(&fasync_lock);

//遍歷進程的異步通知文件列表,若存在相關文件且為增加則刪除前面分配的fasync_struct 對象,若為刪除則刪除文件對應

//的fasync_struct對象 for (fp = fapp; (fa = *fp) != NULL; fp = &fa->fa_next) {

if (fa->fa_file == filp) {

if(on) {

fa->fa_fd = fd;

kmem_cache_free(fasync_cache, new);

} else {

*fp = fa->fa_next;

kmem_cache_free(fasync_cache, fa);

result = 1;

}

goto out;

}

}

//列表中不存在相關文件則初始化faync_struct 對象并加入到列表頭

if (on) {

new->magic = FASYNC_MAGIC;

new->fa_file = filp;

new->fa_fd = fd;

new->fa_next = *fapp;

*fapp = new;

result = 1;

}

out:

write_unlock_irq(&fasync_lock);

return result;

}

//下面再來看看tty核心中fasync方法tty_fasync函數

static int tty_fasync(int fd, struct file *filp, int on)

{

struct tty_struct *tty;

unsigned long flags;

int retval = 0;

lock_kernel();

tty = (struct tty_struct *)filp->private_data;

if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))

goto out;

retval = fasync_helper(fd, filp, on, &tty->fasync); //增加或刪除文件到進程列表 if (retval <= 0)

goto out;

if (on) {

enum pid_type type;

struct pid *pid;

if (!waitqueue_active(&tty->read_wait))

tty->minimum_to_wake = 1;

spin_lock_irqsave(&tty->ctrl_lock, flags);

if (tty->pgrp) {

pid = tty->pgrp;

type = PIDTYPE_PGID;

} else {

pid = task_pid(current);

type = PIDTYPE_PID;

}

spin_unlock_irqrestore(&tty->ctrl_lock, flags);

retval = __f_setown(filp, pid, type, 0); //設置文件的屬主? if (retval)

goto out;

} else {

if (!tty->fasync && !waitqueue_active(&tty->read_wait))

tty->minimum_to_wake = N_TTY_BUF_SIZE;

}

retval = 0;

out:

unlock_kernel();

return retval;

}

3)上面的步驟完成后就是當數據到達時給應用程序發送SIGIO信號,這一步是一般分布在數據的讀寫操作中,我們具體分析內核中的輔助函數kill_fasync其作用是當數據到達時通知所有相關進程

//sig表示要發送的信號,band表示模式讀為POLL_IN 寫為POLL_OUT

void kill_fasync(struct fasync_struct **fp, int sig, int band)

{

/* First a quick test without locking: usually

* the list is empty.

*/

if (*fp) {

read_lock(&fasync_lock);

/* reread *fp after obtaining the lock */

__kill_fasync(*fp, sig, band);

read_unlock(&fasync_lock);

}

}

//遍歷struct fasync_struct 鏈表并對相關進程發送信號

void __kill_fasync(struct fasync_struct *fa, int sig, int band)

{

while (fa) {

struct fown_struct * fown;

if (fa->magic != FASYNC_MAGIC) {

printk(KERN_ERR "kill_fasync: bad magic number in "

"fasync_struct!/n");

return;

}

fown = &fa->fa_file->f_owner;

/* Don't send SIGURG to processes which have not set a

queued signum: SIGURG has its own default signalling

mechanism. */

if (!(sig == SIGURG && fown->signum == 0))

send_sigio(fown, fa->fa_fd, band);

fa = fa->fa_next;

}

}

4)最好在關閉進程時再把文件從進程列表中清除即tty_fysnc(-1,flip,0);

因為異步通知機制是分散的這節中就主要分析其實現機制,實現源碼比較容易理解就沒有列舉出全部源碼

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的linux tty core code,linux tty core 源码分析(7)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。