LDD ch4補充,seq file的介紹

2021-07-09 02:59:22 字數 3620 閱讀 4258

總結自linux下的seq_file.txt的document。

虛擬檔案系統如procfs,debugfs等在建立虛擬檔案的時候,都要設計到虛擬檔案的操作。

使用虛擬檔案的時候比較挑戰的一點在於,當虛擬檔案相當大的時候,操作虛擬檔案需要一些技巧,在多次讀寫的時候要小心的操作檔案的position,當虛擬檔案的使用越來越廣泛的時候,這樣的操作**也越來越多,因此在2.6核心中加入了一組函式來方便實現虛擬檔案的操作,這就是seq_file。

seq_file宣告在

希望使用seq_file介面的模組都必須要要實現iterator物件來遍歷虛擬檔案的資料。

iterator介面包含4個函式需要實現用於遍歷:

struct seq_operations ;
1.1.1 start介面

start介面接受乙個pos作為起始位置,並且返回乙個iterator指標。對於乙個順序訪問的虛擬檔案來說,最簡單的start函式可能如下:

static void *ct_seq_start(struct seq_file *s, loff_t *pos)

對於順序訪問的檔案來說,只需要乙個loff_t來記錄虛擬檔案的當前訪問位置即可,這個loff_t就是iterator物件。

對於複雜的應用場景,seq_file中的private可以用來記錄資訊。

當start的pos為0的時候,start函式可以有乙個特殊的返回值seq_start_token,這個值從來讓show介面了解到當前正在起始位置從而輸出header資訊。

1.1.2 next介面

next介面用於將虛擬檔案位置移動pos個位置,引數v就是start介面中返回的iterator。

next介面會返回更新後的iterator,或者在沒有資料的時候返回null。

static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)

1.1.3 stop介面

stop介面是做iterator物件的cleanup動作,主要就是釋放在start中申請的iterator物件。

static

void ct_seq_stop(struct seq_file *s, void *v)

1.1.4 show介面

show函式,將iterator指向的位置的物件進行格式化輸出。

static

int ct_seq_show(struct seq_file *s, void *v)

show函式正常都應該返回0,負數是表明發生了某些錯誤。

show函式可以返回seq_skip,表明當前的item會被skip,如果之前show已經產生過輸出,那麼這整個輸出都會被丟棄掉。

1.1.5 小結

seq_file在設計的時候,start()和stop()之間是不會sleep的,所以在start和stop之間持有乙個鎖是很合理的,除此之外,不會持有其他的鎖。

seq_file的主要功能就是管理虛擬檔案的位置,最終將輸出傳遞給使用者使用者。核心中提供了一組函式,用來幫助輸出內容。

int seq_printf(struct seq_file *m, const char *f, ...)
最常用的輸出函式是seq_printf,函式和printk類似,輸出內容儲存在seq_file的buffer中。

1.2.2 直接的字元輸出

int seq_putc(struct seq_file *m, char c);

int seq_puts(struct seq_file *m, const

char *s);

int seq_escape(struct seq_file *m, const

char *s, const

char *esc);

seq_putc和seq_puts很簡單,就是將乙個字元/字串輸入到seq_file中去。

seq_escape是在seq_puts的基礎上,將esc字串中所包含的字元都轉為用8進製的顯示。

在虛擬檔案中使用seq_file,需要實現一組file_operation,seq_file也提供給了一組可用的函式。

int seq_open(struct file *file, const

struct seq_operations *op);

seq_open中會使用seq_operations建立seq_file物件,並將其賦值給到file->private_data。seq_open常用來實現open操作,下面就是乙個最簡單的示例:

static

int ct_open(struct inode *inode, struct file *file)

對於read,lseek,release操作,seq_file中已經提供直接可用的函式:

ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos);

loff_t seq_lseek(struct file *file, loff_t offset, int whence);

int seq_release(struct inode *inode, struct file *file);

簡單的例子如下:

static const struct file_operations ct_file_ops = ;
對於極端簡單的例子,可以使用乙個早期的介面single_open,

int single_open(struct file *file, int (*show)(struct seq_file *, void *),

void *data)

single_open完成的工作和seq_open類似,只是不需要編寫完整的seq_operation,只需要實現其中的show介面即可,其他介面會有預設的實現

和single_open配套的release函式是single_release

int single_release(struct inode *inode, struct file *file);
如果虛擬檔案被組織成list的形式,那麼下面的seq_list的函式會比較有用,方便實現對應的seq_operation操作。

struct list_head *seq_list_start(struct list_head *head,

loff_t pos);

struct list_head *seq_list_start_head(struct list_head *head,

loff_t pos);

struct list_head *seq_list_next(void *v, struct list_head *head,

loff_t *ppos);

補充閱讀程式 4

03.檔名稱 text.cpp 05.完成日期 2016年5月9日 06.版本號 vc 6.0 07.includeusing namespace std class a class b public a class b virtual public a class c public a class...

rt thread隨筆4補充 雙向鍊錶

typedef struct dnode dnode,doublelist 1 struct rt list node 2 6typedef struct rt list node rt list t rt list t 型別的節點裡面有兩個 rt list t 型別的節點指標 next 和 pre...

linux基礎學習 14 2 命令補充 4

1 userdel 刪除使用者 注釋引數 r 刪除使用者及使用者家目錄 2 groupadd 新增乙個使用者組 3 usermod 修改使用者資訊 u g g s m e c d l u l 小寫字母l 4 chage 專門修改使用者密碼資訊 引數 l 小寫字母l e m w m i 大寫字母i 5...