Linux內核學習筆記之seq_file接口創建可讀寫proc文件


轉自:http://blog.csdn.net/mumufan05/article/details/45803219

 

學習筆記與個人理解,如有錯誤,歡迎指正。

溫馨提示:建議跟着注釋中的編號順序閱讀代碼

測試方法:cat /proc/abc_proc

                   echo 任意字符串 >/proc/abc_pro(需root權限)

 

 

[cpp]  view plain  copy
 
  1. /************************************************* 
  2.  使用seq_file接口實現可讀寫proc文件的例子 
  3.  適用於3.10以后的內核 
  4.  Author: ZhangN 
  5.  Date: 2015-5-17  
  6.  *************************************************/  
  7. #include <linux/module.h>  
  8. #include <linux/sched.h>  
  9. #include <linux/uaccess.h>  
  10. #include <linux/proc_fs.h>  
  11. #include <linux/fs.h>  
  12. #include <linux/seq_file.h>  
  13. #include <linux/slab.h>  
  14.   
  15. static char *str = NULL;  
  16.   
  17. /*5,實現show函數 
  18.   作用是將內核數據輸出到用戶空間 
  19.   將在proc file輸出時被調用*/  
  20. static int my_proc_show(struct seq_file *m, void *v)  
  21. {  
  22.     /*這里不能使用printfk之類的函數 
  23.       要使用seq_file輸出的一組特殊函數 
  24.       詳見ldd3的91頁*/  
  25.     seq_printf(m, "current kernel time is %ld\n", jiffies);  
  26.     seq_printf(m, "str is %s\n", str);  
  27.     return 0;  
  28. }  
  29.   
  30.   
  31.   
  32. /*3,實現open和write函數*/  
  33. static ssize_t my_proc_write(struct file *file, const char __user *buffer,  
  34.                              size_t count, loff_t *f_pos)  
  35. {  
  36.     char *tmp = kzalloc((count+1), GFP_KERNEL);  
  37.     if(!tmp)  
  38.         return -ENOMEM;  
  39.     if(copy_from_user(tmp, buffer, count))  
  40.     {  
  41.         kfree(tmp);  
  42.         return EFAULT;  
  43.     }  
  44.     kfree(str);  
  45.     str = tmp;  
  46.     return count;  
  47. }  
  48.   
  49. static int my_proc_open(struct inode *inode, struct file *file)  
  50. {  
  51.     /*4,在open函數中調用single_open綁定seq_show函數指針 
  52.       需要說明的是,ldd3中介紹的seq接口用該調用seq_open函數 
  53.       其調用形式如下: 
  54.       return sep_open(file, &scull_seq_ops); 
  55.       scull_seq_ops為struct seq_operations結構體 
  56.       在該結構體中綁定show函數指針 
  57.       需要准備seq_operations結構體 
  58.       而調用single_open函數只需直接指定show的函數指針即可 
  59.       個人猜測可能是在single_open函數中實現了seq_operations結構體 
  60.       至於是不是就不知道了,沒有查看具體實現 
  61.       有興趣的同學可以參考文檔:Documentation\filesystems\seq_file.txt 
  62.       關於第三個參數,其類型應為viod*, 
  63.       內核中有些地方傳入的NULL,有些地方傳入的inode->i_private,也有傳入其他值的 
  64.       來看看data在single_open函數中如何被使用的: 
  65.         if (!res) 
  66.          ((struct seq_file *)file->private_data)->private = data; 
  67.       data是seq_file結構體的private成員。 
  68.       那么data如何真正被使用的呢? 
  69.       發現show函數的第一個參數為seq_file類型,在show函數中, 
  70.       可以將seq_file的private成員轉換成對應的類型進行使用。 
  71.       也就是說,可以通過seq_file的private成員將data參數傳遞到show函數中*/  
  72.     return single_open(file, my_proc_show, NULL);  
  73. }  
  74.   
  75. /*2,填充proc_create函數中調用的flie_operations結構體 
  76.   其中my開頭的函數為自己實現的函數, 
  77.   seq和single開頭為內核實現好的函數,直接填充上就行 
  78.   open為必須填充函數 
  79.   這里詳見ldd3的93頁*/  
  80. static struct file_operations my_fops = {  
  81.     .owner   = THIS_MODULE,  
  82.     .open    = my_proc_open,  
  83.     .release = single_release,  
  84.     .read    = seq_read,  
  85.     .llseek  = seq_lseek,  
  86.     .write   = my_proc_write,  
  87. };  
  88.   
  89. static int __init my_init(void)  
  90. {  
  91.     struct proc_dri_entry *file;  
  92.     /*3.10以后內核的proc文件的新接口 
  93.       需要關聯file_operations*/  
  94.     /*1,首先要調用創建proc文件的函數,需要綁定flie_operations*/  
  95.     file = proc_create("abc_proc", 0644, NULL, &my_fops);  
  96.     if(!file)  
  97.         return -ENOMEM;  
  98.     return 0;  
  99. }  
  100.   
  101. /*6,刪除proc文件*/  
  102. static void __exit my_exit(void)  
  103. {  
  104.     remove_proc_entry("abc_proc", NULL);  
  105.     kfree(str);  
  106. }  
  107.   
  108. module_init(my_init);  
  109. module_exit(my_exit);  
  110. MODULE_LICENSE("GPL");  
  111. MODULE_AUTHOR("ZhangN");  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM