【Linux】proc_create的使用方法

proc_create的使用方法

proc文件系統是個有用的東東。
創建一個proc虛擬文件,應用層通過讀寫該文件,即可實現與內核的交互。
proc虛擬文件是如何創建的呢?

先看看比較簡單的,創建proc文件夾。
調用以下函數,即可實現proc文件夾的創建:
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent);
name就是要創建的文件夾名稱。
parent是要創建節點的父節點。也就是要在哪個文件夾之下創建新文件夾,需要將那個文件夾的proc_dir_entry傳入。
如果是在/proc目錄下創建文件夾,parent爲NULL。
例如:

struct proc_dir_entry *mytest_dir = proc_mkdir("mytest", NULL);

然後來看看proc文件的創建。
創建方法是調用以下函數:

static inline struct proc_dir_entry *proc_create(const char *name, mode_t mode, 
    struct proc_dir_entry *parent, const struct file_operations *proc_fops);

name就是要創建的文件名。
mode是文件的訪問權限,以UGO的模式表示。
parent與proc_mkdir中的parent類似。也是父文件夾的proc_dir_entry對象
proc_fops就是該文件的操作函數了。
例如:

struct proc_dir_entry *mytest_file = proc_create("mytest", 0x0644, mytest_dir, mytest_proc_fops);

還有一種方式:

struct proc_dir_entry *mytest_file = proc_create("mytest/mytest", 0x0644, NULL, mytest_proc_fops);

如果文件夾名稱和文件名定義爲常量:

#define MYTEST_PROC_DIR "mytest"
#define MYTEST_PROC_FILE "mytest"

第二種方式爲:

struct proc_dir_entry *mytest_file = 
    proc_create(MYTEST_PROC_DIR"/"MYTEST_PROC_FILE, 0x0644, NULL, mytest_proc_fops);

接下來看看mytest_proc_fops的定義。

static const struct file_operations mytest_proc_fops = {
 .open  = mytest_proc_open,
 .read  = seq_read,
 .write  = mytest_proc_write,
 .llseek  = seq_lseek,
 .release = single_release,
};

以seq_和single_爲前綴的函數都是kernel中現成的。
可以參考文檔:Documentation\filesystems\seq_file.txt
關於single_開頭的函數,有以下說明:

The extra-simple version

For extremely simple virtual files, there is an even easier interface.  A
module can define only the show() function, which should create all the
output that the virtual file will contain. The file's open() method then
calls:

 int single_open(struct file *file,
                 int (*show)(struct seq_file *m, void *p),
                 void *data);

When output time comes, the show() function will be called once. The data
value given to single_open() can be found in the private field of the
seq_file structure. When using single_open(), the programmer should use
single_release() instead of seq_release() in the file_operations structure
to avoid a memory leak.

根據以上這段說明,在mytest_proc_open函數中,只需要調用single_open函數,並傳入一個show函數即可。
例如:

static int mytest_proc_open(struct inode *inode, struct file *file)
{
 return single_open(file, mytest_proc_show, inode->i_private);
}

其中第三個參數,也就是single_open的data參數,內核中有些地方傳入的NULL,有些地方傳入的inode->i_private,也有傳入其他值的。
來看看data在single_open函數中如何被使用的:
  if (!res)
   ((struct seq_file *)file->private_data)->private = data;
這與前面的英文說明一致,data是seq_file結構體的private成員。
那麼data如何真正被使用的呢?
發現show函數的第一個參數爲seq_file類型,在show函數中,可以將seq_file的private成員轉換成對應的類型進行使用。

下面來看看mytest_proc_show函數如何實現。
傳遞給single_open的show函數指針,將在proc file輸出時被調用。
例如,cat /proc/mytest/mytest時,mytest_proc_show函數將會被調用。
假設我們的mytest只是記錄了一個標誌,內核中會根據該標準執行不同的操作。
來看看mytest_proc_show的實現:

static int task_lifecycle_proc_show(struct seq_file *seq, void *v)
{
 seq_puts(seq, mytest_flag ? "true\n" : "false\n");
 
 return 0;        
}

接下來再看看mytest_proc_write函數的實現。
顧名思義,mytest_proc_write函數會在寫mytest文件時被調用。
功能就是記錄寫入數據到mytest文件。
實現也不麻煩:

static ssize_t task_lifecycle_proc_write(struct file *file, const char __user *buffer,
        size_t count, loff_t *pos)
{
 char mode;
 
 if (count > 0) {
  if (get_user(mode, buffer))
   return -EFAULT;

   mytest_flag = (mode != '0');
 }

 return count;
}

至此,proc文件創建完畢。
通過讀寫mytest文件,即可實現對mytest_flag的控制。

 

轉自:https://www.cnblogs.com/Ph-one/p/5530320.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章