seq_file学习(1)—— single_open
span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }.cm-searching {background: #ffa; background: rgba(255, 255, 0, .4);}.cm-force-border { padding-right: .1px; }@media print { .CodeMirror div.CodeMirror-cursors {visibility: hidden;}}.cm-tab-wrap-hack:after { content: ""; }span.CodeMirror-selectedtext { background: none; }.CodeMirror-activeline-background, .CodeMirror-selected {transition: visibility 0ms 100ms;}.CodeMirror-blur .CodeMirror-activeline-background, .CodeMirror-blur .CodeMirror-selected {visibility:hidden;}.CodeMirror-blur .CodeMirror-matchingbracket {color:inherit !important;outline:none !important;text-decoration:none !important;}
-->
li {list-style-type:decimal;}ol.wiz-list-level2 > li {list-style-type:lower-latin;}ol.wiz-list-level3 > li {list-style-type:lower-roman;}blockquote {padding:0 12px;padding:0 0.75rem;}blockquote > :first-child {margin-top:0;}blockquote > :last-child {margin-bottom:0;}img {border:0;max-width:100%;height:auto !important;margin:2px 0;}table {border-collapse:collapse;border:1px solid #bbbbbb;}td, th {padding:4px 8px;border-collapse:collapse;border:1px solid #bbbbbb;min-height:28px;word-break:break-all;box-sizing: border-box;}.wiz-hide {display:none !important;}
-->
作者
平台
概述
正文
#include <linux/init.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/fs.h> static struct dentry *seq_file_demo_dir; static int seq_file_demo_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "Hello World\n");
return ;
} static int seq_file_demo_open(struct inode *inode, struct file *file)
{
return single_open(file, &seq_file_demo_show, NULL);
} static const struct file_operations seq_file_demo_fops = {
.owner = THIS_MODULE,
.open = seq_file_demo_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
}; static int __init seq_file_demo_init(void)
{
seq_file_demo_dir = debugfs_create_file("seq_file_demo", , NULL,
NULL, &seq_file_demo_fops);
return ;
} static void __exit seq_file_demo_exit(void)
{
if (seq_file_demo_dir)
debugfs_remove(seq_file_demo_dir);
} module_init(seq_file_demo_init);
module_exit(seq_file_demo_exit);
MODULE_LICENSE("GPL");
#define DEFINE_SHOW_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct file *file) \
{ \
return single_open(file, __name ## _show, inode->i_private); \
} \
\
static const struct file_operations __name ## _fops = { \
.owner = THIS_MODULE, \
.open = __name ## _open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
}
利用上面的宏可以对我们的驱动做进一步简化:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <linux/fs.h> static struct dentry *seq_file_demo_dir; static int seq_file_demo_show(struct seq_file *seq, void *v)
{
seq_printf(seq, "Hello World\n");
return ;
}
DEFINE_SHOW_ATTRIBUTE(seq_file_demo); static int __init seq_file_demo_init(void)
{
seq_file_demo_dir = debugfs_create_file("seq_file_demo", , NULL,
NULL, &seq_file_demo_fops);
return ;
} static void __exit seq_file_demo_exit(void)
{
if (seq_file_demo_dir)
debugfs_remove(seq_file_demo_dir);
} module_init(seq_file_demo_init);
module_exit(seq_file_demo_exit);
MODULE_LICENSE("GPL");
int single_open(struct file *file, int (*show)(struct seq_file *, void *),
void *data)
{
struct seq_operations *op = kmalloc(sizeof(*op), GFP_KERNEL);
int res = -ENOMEM; if (op) {
op->start = single_start;
op->next = single_next;
op->stop = single_stop;
op->show = show;
res = seq_open(file, op);
if (!res)
((struct seq_file *)file->private_data)->private = data;
else
kfree(op);
}
return res;
}
上面设置了single_xx的start、next以及stop回调函数,实现很简单:
static void *single_start(struct seq_file *p, loff_t *pos)
{
return NULL + (*pos == );
} static void *single_next(struct seq_file *p, void *v, loff_t *pos)
{
++*pos;
return NULL;
} static void single_stop(struct seq_file *p, void *v)
{
}
其中,*ops表示的是要输出的元素的索引编号,从0开始,依次递增;
seq_file学习(1)—— single_open的更多相关文章
- seq_file学习(2)—— seq_file
li {list-style-type:decimal;}ol.wiz-list-level2 > li {list-style-type:lower-latin;}ol.wiz-list-le ...
- Linux内核学习笔记之seq_file接口创建可读写proc文件
转自:http://blog.csdn.net/mumufan05/article/details/45803219 学习笔记与个人理解,如有错误,欢迎指正. 温馨提示:建议跟着注释中的编号顺序阅读代 ...
- linux内核数据结构学习总结
目录 . 进程相关数据结构 ) struct task_struct ) struct cred ) struct pid_link ) struct pid ) struct signal_stru ...
- Introduction the naive“scull” 《linux设备驱动》 学习笔记
Introduction the naive "scull" 首先.什么是scull? scull (Simple Character Utility for Loading Lo ...
- linux内核seq_file接口
seq相关头文件linux/seq_file.h,seq相关函数的实现在fs/seq_file.c.seq函数最早是在2001年就引入了,但以前内核中一直用得不多,而到了2.6内核后,许多/proc的 ...
- itop4412学习-超级块操作
1. 先看下超级块支持的函数列表,文件路径\4412_SCP精英版\Android源码\iTop4412_Kernel_3.0_20140521\iTop4412_Kernel_3.0\include ...
- LKM rootkit:Reptile学习
简介 Reptile是github上一个很火的linux lkm rootkit,最近学习了一些linux rootkit的内容,在这里记录一下. 主要是分析reptile的实现 Reptile的使用 ...
- 设备驱动基础学习--/proc下增加节点
在需要创建一个由一系列数据顺序组合而成的/proc虚拟文件或一个较大的/proc虚拟文件时,推荐使用seq_file接口. 数据结构struct seq_fille定义在include/linux/s ...
- Linux内核驱动学习(三)字符型设备驱动之初体验
Linux字符型设备驱动之初体验 文章目录 Linux字符型设备驱动之初体验 前言 框架 字符型设备 程序实现 cdev kobj owner file_operations dev_t 设备注册过程 ...
随机推荐
- kudu的读取数据流程
当客户端从Kudu的表中读取数据时,必须首先建立需要连接的系列tablet服务器. 通过执行tablet发现过程(如上所述)来确定包含要读取的主关键字范围的tablet的位置(读取不必在领导者tabl ...
- 事件(Event)(onclick,onchange,onload,onunload,onfocus,onblur,onselect,onmuse)【转载】
ylbtech-Event:事件(Event)对象 事件(Event) HTML 4.0 事件属性 onclick onchange onload onunload onselect onmouse ...
- 2018-03-11 20165235祁瑛《Java程序设计》第二周学习总结
2018-03-11 20165235祁瑛<Java程序设计>第二周学习总结 教材学习内容总结 第二章要点: 在这一章中我学到了很多东西: (1)布尔类型boolean,布尔类型的赋值只能 ...
- 关于thinkphp3自动完成的笔记
当我在前台传入的主键id与字段表的主键id值时,在更新时tp总是判断为新增的状态(解决办法:将前台的表单主键名保持和数据表主键id名一只,手动创建数据) create时是先获取主键id判断'$type ...
- GIT结合android studio使用总结
使用GIT前请阅读(有git基础可略过) git指引 :http://www.bootcss.com/p/git-guide/ 一. 下载git http://git-scm.com/downloa ...
- supervisor 监控redis & mongodb
安装 安装python brew install python 安装pipwget https://bootstrap.pypa.io/get-pip.pysudo python get-pip.py ...
- MySql与python交互
No1: 引入MySql:python2是Mysqldb,python3是pymysql No2: Connection对象 用于建立与数据库的连接 创建对象:调用connect()方法 conn=c ...
- POJ 3258 River Hopscotch (最大最小距离)【二分】
<题目链接> 题目大意:现在有起点和终点两个石块,这两个石块之间有N个石块,现在对这N个石块移除M个石块,使得这些石块之间的最短距离最大,注意,起点和终点这两个石块不能被移除. 解题分析: ...
- [ 中危 ] 发布处存在CSRF及CSRF设想
漏洞存在于菜品发布处,使用A账号在添加/发布菜品的时候拦截数据包,使用burpsuite构造 CSRF的POC,再用B账号打开该HTML POC ,生成菜品. 该CSRF400RMB,主要因为是核心业 ...
- 有关python 函数参数
# def foo(x):# print(x)### foo(1)# foo('a')# foo({'a':2}) #形参与实参:# def foo(x,y): #x=1,y=2# return x+ ...