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 ;
}

接下来再看看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 > ) {
if (get_user(mode, buffer))
return -EFAULT; mytest_flag = (mode != '');
} return count;
}

至此,proc文件创建完毕。
通过读写mytest文件,即可实现对mytest_flag的控制。
更深层次的原理,即proc文件系统是如何实现的,就先不讨论了。
不然又成懒婆娘的裹脚了

proc_create的使用方法的更多相关文章

  1. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  2. ubuntu/linux mint 创建proc文件的三种方法(四)

    在做内核驱动开发的时候,能够使用/proc下的文件,获取对应的信息,以便调试. 大多数/proc下的文件是仅仅读的,但为了演示样例的完整性,都提供了写方法. 方法一:使用create_proc_ent ...

  3. ubuntu/linux mint 创建proc文件的三种方法(两)

    在这样做的内核驱动程序的开发时间.可以使用/proc下档.获取相应的信息.对于调试. 大多数/proc下的文件是仅仅读的.但为了演示样例的完整性.都提供了写方法. 方法一:使用create_proc_ ...

  4. mapreduce多文件输出的两方法

    mapreduce多文件输出的两方法   package duogemap;   import java.io.IOException;   import org.apache.hadoop.conf ...

  5. 【.net 深呼吸】细说CodeDom(6):方法参数

    本文老周就给大伙伴们介绍一下方法参数代码的生成. 在开始之前,先补充一下上一篇烂文的内容.在上一篇文章中,老周检讨了 MemberAttributes 枚举的用法,老周此前误以为该枚举不能进行按位操作 ...

  6. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  7. 多线程爬坑之路-Thread和Runable源码解析之基本方法的运用实例

    前面的文章:多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类) 多线程爬坑之路-Thread和Runable源码解析 前面 ...

  8. [C#] C# 基础回顾 - 匿名方法

    C# 基础回顾 - 匿名方法 目录 简介 匿名方法的参数使用范围 委托示例 简介 在 C# 2.0 之前的版本中,我们创建委托的唯一形式 -- 命名方法. 而 C# 2.0 -- 引进了匿名方法,在 ...

  9. ArcGIS 10.0紧凑型切片读写方法

    首先介绍一下ArcGIS10.0的缓存机制: 切片方案 切片方案包括缓存的比例级别.切片尺寸和切片原点.这些属性定义缓存边界的存在位置,在某些客户端中叠加缓存时匹配这些属性十分重要.图像格式和抗锯齿等 ...

随机推荐

  1. 学习shell脚本之乘法口诀

    脚本如下: #!/bin/bash for i in 'seq 1 9' do for j in 'seq 1 $i' do k=$[$i*$j] echo -ne "$j"&qu ...

  2. response.sendRedirect(location)与rd.forward()区别

    在Java Web开发中,经常会用到跳转页面的方法,一般有下面两种方法. HttpServletResponse response = new HttpServletResponse(); respo ...

  3. 征途(bzoj 4518)

    Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除第m天外,每一天晚上Pine都必须在休息站过夜 ...

  4. Linux上安装使用SSH

    參考博客:http://blog.csdn.net/xqhrs232/article/details/50960520 Ubuntu安装使用SSH ubuntu默认并没有安装ssh服务,如果通过ssh ...

  5. android 布局之LinearLayout(学习一)

    一,View localView = mRadioGroup_content.getChildAt(i);指定自定义菜单栏的点击格,如child3 其中:mRadioGroup_content = ( ...

  6. intellij idea springmvc web工程之helloworld

    1.新建java工程 2.设置项目 2.添加jar包 3.配置web.xml <?xml version="1.0" encoding="UTF-8"?& ...

  7. 在matlab中对中国地图中的不同省份按照高度进行渲染

    直接上优化后的代码和效果图 colour_totall=128; % 载入地图数据 --各省的多边形数据 shp_data=shaperead('maps/bou2_4p.shp', 'UseGeoC ...

  8. 【kotlin】基本语法when的使用,类似于java中的switch,但是又青出于蓝而胜于蓝

    when(要判断的参数){ 参数值为1 ->做这种事情 参数值为2 ->做另一种事情 else -> 类似于switch中的default } 扩展使用:https://www.cn ...

  9. win7安装ANT

    点击进入ant官网,找到下载选项.   选择下载安装文件.其余的源文件和手册的下载步骤完全相同.   可以下载官网上对应系统的最新版本.也可以在old ant 版本中选择自己需要的版本.笔者需要ant ...

  10. 大众车机天宝187A Hack笔记

    0×00前言 自从去年买了车,对汽车电子系统的兴趣就上来了.这不,前一阵子逛汽车论坛,发现了有网友将老版本的天宝车机被刷上了2017新帕萨特车机的系统,支持超级蓝牙和苹果CarPlay,百度CarLi ...