Linux下有一个神奇的目录/proc,经常会运行 cat /proc/cpuinfo 命令查看cpu信息,/proc下的确有cpuinfo文件,但是这个文件不是物理存在的,是软件虚拟出来的,与普通文件不同,该文件是动态的。通过/proc可以实现用户态与内核态之间的通信。在内核模式下,可以很方便的创建/proc子目录,并进行读写操作,只不过此时你需要实现文件读写接口,因为内核不知道如何处理该文件。

下面创建/proc/test目录,并新建log文件,进行读写操作。

一.系统API

extern struct proc_dir_entry proc_mkdir(const char *dir_name,struct proc_dir_entry *parent);

新建/proc子目录,如parent为NULL,则在/proc根下建立目录

extern struct proc_dir_entry proc_create_entry(const char *name,mode_t mode,struct proc_dir_entry *parent);

在/proc下新建虚拟文件

extern void *remove_proc_entry(const char *name,struct proc_dir_entry *parent);

删除新建的文件或目录

二.编码

C代码  
  1. #ifndef __KERNEL__
  2. #define __KERNEL__
  3. #endif  /* __KERNEL__ */
  4. #include <linux/module.h>
  5. #include <linux/kernel.h>
  6. #include <linux/init.h>
  7. #include <linux/types.h>
  8. #include <linux/netdevice.h>
  9. #include <linux/proc_fs.h>
  10. #include <linux/inet.h>
  11. #include <linux/vmalloc.h>
  12. #define MAX_COOKIE_LENGTH PAGE_SIZE
  13. static struct proc_dir_entry *test_proc_dir;
  14. static struct proc_dir_entry *log_proc_dir;
  15. static char *cookie_pot;     // 内核缓冲区,用于写数据
  16. static int tValue = 12;      // 显示值
  17. // 读取日志文件函数
  18. int ProcLogRead( char *buffer,
  19. char **start,
  20. off_t offset,
  21. int length,
  22. int *eof,
  23. void *data )
  24. {
  25. int len;
  26. if( offset > 0 )
  27. {
  28. *eof = 1;
  29. return 0;
  30. }
  31. len = sprintf(buffer, "number:%x\n",tValue);
  32. return len;
  33. }
  34. // 写日志文件函数
  35. int ProcLogWrite( struct file *filp,
  36. const char __user *buff,
  37. unsigned long len,
  38. void *data)
  39. {
  40. if( copy_from_user( cookie_pot,buff,len ) )  // 拷贝用户空间值至内核缓冲区
  41. {
  42. return -EFAULT;
  43. }
  44. sscanf(cookie_pot,"%d",&tValue);    // 保存至全局变量tValue
  45. printk(KERN_ALERT "%s len:%lu vl:%d\n",cookie_pot,len,tValue);
  46. return len;
  47. }
  48. static int __init testproc_init(void)
  49. {
  50. int ret = 0;
  51. printk(KERN_ALERT "proc test init\n");
  52. cookie_pot = (char*)vmalloc( MAX_COOKIE_LENGTH );   // 为内核缓冲区分配空间
  53. if(!cookie_pot)
  54. {
  55. ret = -ENOMEM;
  56. }
  57. else
  58. {
  59. memset(cookie_pot,0,MAX_COOKIE_LENGTH);
  60. test_proc_dir = proc_mkdir("test",init_net.proc_net);       // 新建/proc/net/test目录,注:2.6.32以上内核,用init_net.proc_net取代先前的pro_net
  61. log_proc_dir = create_proc_entry("log",0644,test_proc_dir);     // 新建文件 /proc/net/test/log
  62. if(test_proc_dir == NULL
  63. || log_proc_dir == NULL)
  64. {
  65. ret = -ENOMEM;
  66. vfree(cookie_pot);
  67. }
  68. else
  69. {
  70. // 注册读写函数
  71. log_proc_dir->read_proc = ProcLogRead;
  72. log_proc_dir->write_proc = ProcLogWrite;
  73. }
  74. }
  75. return 0;
  76. }
  77. static void __exit testproc_exit(void)
  78. {
  79. printk(KERN_ALERT "clean test proc\n");
  80. remove_proc_entry("log",test_proc_dir);     // 删除log文件
  81. remove_proc_entry("test",init_net.proc_net);    // 删除test目录
  82. vfree(cookie_pot);
  83. }
  84. module_init(testproc_init);
  85. module_exit(testproc_exit);
  86. MODULE_LICENSE("Dual BSD/GPL");
  87. MODULE_AUTHOR("kettas");
  88. MODULE_DESCRIPTION("proc test");
  89. MODULE_VERSION("1.0.0");
  90. MODULE_ALIAS("Proc 01");

三.编译运行

Shell代码  
  1. [scada@linux proc_test]$ sudo insmod proc_test.ko
  2. [scada@linux proc_test]$ ll /proc/net/test/
  3. 总用量 0
  4. -rw-r--r--. 1 root root 0 1月  11 22:14 log
  5. [scada@linux proc_test]$ cat /proc/net/test/log
  6. number:c

四.接口操作

上面用cat命令直接查看log文件,既然内核提供了通用的read(),write()文件访问接口,那试试。

C代码  
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <sys/types.h>
  4. #include <sys/stat.h>
  5. #include <fcntl.h>
  6. #include <assert.h>
  7. #include <string.h>
  8. int main(int argc,char **argv)
  9. {
  10. int fd = open("/proc/net/test/log",O_RDWR,0);
  11. assert(fd != -1);
  12. char *vl = "10";  // 此处为字符串
  13. // write
  14. int ret = write(fd,vl,strlen(vl));
  15. printf("ret:%d\n",ret);
  16. // read
  17. char buff[100] = {};
  18. ret = read(fd,buff,100);
  19. assert(ret != -1);
  20. printf("read:%s\n",buff);
  21. close(fd);
  22. return 0;
  23. }

运行:

Shell代码  
  1. [scada@linux proc_test]$ sudo ./write_test
  2. ret:2
  3. read:number:a

向/proc/net/test/log写入10后,显示了16进制结果a,测试OK

/proc 虚拟文件系统(实例)相关推荐

  1. oracle 截取字符串中指定位置_手撕虚拟内存(1)——字符串在虚拟内存中的段位置与/proc虚拟文件系统...

    原文:Hack The Virtual Memory: C strings & /proc - Holberton 翻译:RobotCode俱乐部 介绍 这是一系列关于虚拟内存的小文章/教程中 ...

  2. linux 创建 虚拟文件系统设备 文件节点 使用 proc_create 实例 简介

    proc虚拟文件系统也可以创建虚拟文件节点,实现用户空间与内核空间的交互.在驱动中创建节点,可以实现对硬件的控制.proc_create函数原型(在kernel-3.10/include/linux/ ...

  3. 虚拟文件系统(无持久存储的文件系统),以proc和sysfs为例

    对于现代操作系统,虚拟文件系统是一个几乎无处不见的功能,因此,要探究现代操作系统的运行机制,对其进行讨论是必然的. 本文使用的是Linux 2.6.x.x,这是一个变革性的版本,无论是内存管理,进程管 ...

  4. Linux虚拟文件系统vfs及proc详解

    /proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的,而是能够在整个系统范围的上下文中使用.可以使用的文件随系统配置的变化而变化.命令procinfo能够显示基于其中某些文件的多种系统信 ...

  5. ABP虚拟文件系统(VirtualFileSystem)实例------定制菜单栏显示用户姓名

    ABP默认的MVC启动模板在登录后, 右上角显示的是用户名: 如果想让它显示用户的姓名该如何做呢?这就需要用到ABP一个非常强大的功能------虚拟文件系统. 前期准备 使用ABP CLI创建一个名 ...

  6. linux VFS 虚拟文件系统 简介 super_block inode dentry file

    1.简介 1.Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等.通过使用同一套文件 I/O 系统 调用即可对 Linux 中的任意文件进行操作而无需考虑其所在的具体文 ...

  7. linux 文件系统_Linux 虚拟文件系统

    虚拟文件系统 为了支持各种本机文件系统,且同时允许访问其他操作系统的文件,Linux 内核在用户进程与实际文件系统实现之间引入了一个抽象层,该层称为虚拟文件系统.它的任务并不简单,一方面它要提供一套管 ...

  8. 《Linux内核设计与实现》读书笔记(十三)- 虚拟文件系统

    虚拟文件系统(VFS)是linux内核和具体I/O设备之间的封装的一层共通访问接口,通过这层接口,linux内核可以以同一的方式访问各种I/O设备. 虚拟文件系统本身是linux内核的一部分,是纯软件 ...

  9. Linux虚拟文件系统

    从文件 I/O 看 Linux 的虚拟文件系统 1 引言 Linux 中允许众多不同的文件系统共存,如 ext2, ext3, vfat 等.通过使用同一套文件 I/O 系统 调用即可对 Linux ...

最新文章

  1. 服务器中加速BIOS启动的方法
  2. java int byte数组_Java 中int与byte数组转换详解
  3. 1.25亿用户以后,Netflix总结的系统高可用经验
  4. 【阿里巴巴研发效能峰会】低代码与数智化分论坛在线预约中……
  5. Web Service简洁版调用公开手机api
  6. 前端、数据库、Django简单的练习
  7. javascript异步_JavaScript异步并在循环中等待
  8. ElasticSearch 索引基本操作_04
  9. 如何安装Linux操作系统
  10. 升级AndroidStudio3.4问题汇总
  11. SQLServer:执行计划
  12. sqlplus 乱码的资料
  13. [swift] LeetCode 215. Kth Largest Element in an Array
  14. 为什么不使用ipv6计算机网络,ipv6无网络访问权限解决教程
  15. win7卡在正在启动windows界面_Windows系统电脑卡在开机界面进不去系统解决方法
  16. 《前端框架开发技术》HTML+CSS+JavaScript 制作个人简历模板
  17. R语言绘制差异火山图示例
  18. 解决谷歌浏览器添加插件时显示程序包无效:CRX_HEADER_INVALID
  19. win10家庭版添加“本地安全策略”
  20. 笔记 android 知乎,字节跳动团队发布Android Framework笔记,知乎上已获万赞

热门文章

  1. 360浏览器兼容问题
  2. recovery编译问题汇总
  3. Spring MVC+Ant+Tomcat+Eclipse最简单的demo
  4. MySQL Show命令的使用
  5. mysql主从安装配置_如何安装和配置mysql主从同步
  6. python在线问卷调查系统源代码_基于Python 练习1情况的在线问卷
  7. 伸缩轨道_深度解析——伸缩喷漆房为什么这么受欢迎!
  8. oracle块空间的使用,Oracle管理存储架构(二)--Oracle管理数据块空间
  9. php ci 框架 扩展缓存类,CodeIgniter扩展核心类实例详解
  10. 软件测试bug文档模板,软件bug测试记录模板