seq_file接口创建可读写proc文件

学习笔记与个人理解,如有错误,欢迎指正。

温馨提示:建议跟着注释中的编号顺序阅读代码

测试方法: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");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值