linux内核seq操作
2016-02-04 17:17
211 查看
头文件linux/seq_file.h
seq相关函数的实现在fs/seq_file.c
start实现初始化工作,在遍历一个链接对象开始时调用
stop当所有链接对象遍历结束时调用,主要完成一些清理工作
next用来在遍历中寻找下一个链接对象,返回下一个对象或者NULL
show对遍历对象进行操作的函数主要是调用seq_printf, seq_puts之类的函数,打印出这个对象节点的信息。
整体看来,用户态调用一次读操作,seq_file流程为:该函数调用struct seq_operations结构提顺序为:start->show->next->show…->next->show->next->stop->start->stop来读取文件
seq相关函数的实现在fs/seq_file.c
struct seq_file { char *buf; size_t size; size_t from; size_t count; loff_t index; loff_t read_pos; u64 version; struct mutex lock; const struct seq_operations *op; int poll_event; void *private; };
struct seq_operations { void * (*start) (struct seq_file *m, loff_t *pos); void (*stop) (struct seq_file *m, void *v); void * (*next) (struct seq_file *m, void *v, loff_t *pos); int (*show) (struct seq_file *m, void *v); };
start实现初始化工作,在遍历一个链接对象开始时调用
stop当所有链接对象遍历结束时调用,主要完成一些清理工作
next用来在遍历中寻找下一个链接对象,返回下一个对象或者NULL
show对遍历对象进行操作的函数主要是调用seq_printf, seq_puts之类的函数,打印出这个对象节点的信息。
//seq操作包括以下一系列函数 int seq_open(struct file *, const struct seq_operations *); ssize_t seq_read(struct file *, char __user *, size_t, loff_t *); loff_t seq_lseek(struct file *, loff_t, int); int seq_release(struct inode *, struct file *);
实现例子
/* * Documentation/filesystem/seq_file.txt */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/mm.h> #include <linux/fs.h> #include <linux/slab.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> //#define DEBUG_SEQ #ifdef DEBUG_SEQ #define log_seq(...) printk(__VA_ARGS__) #else #define log_seq(...) #endif static void *ct_seq_start(struct seq_file *s, loff_t *pos) { int *count = s->private; log_seq("%s\n", __func__); if ((long long)*pos < *count) { printk("start pos %lld\n", (long long)*pos); return pos; } return NULL; } static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos) { int *count = s->private; log_seq("%s\n", __func__); ++*pos; if ((long long)*pos < *count) { printk("next pos %lld\n", (long long)*pos); return pos; } return NULL; } static void ct_seq_stop(struct seq_file *s, void *v) { log_seq("%s\n", __func__); } static int ct_seq_show(struct seq_file *s, void *v) { loff_t *pos = v; log_seq("%s\n", __func__); seq_printf(s, "%lld\n", (long long)*pos); return 0; } static const struct seq_operations ct_seq_ops = { .start = ct_seq_start, .next = ct_seq_next, .stop = ct_seq_stop, .show = ct_seq_show }; static int ct_open(struct inode *inode, struct file *file) { int ret; struct seq_file *s; ret = seq_open(file, &ct_seq_ops); s = file->private_data; s->private = (void *)kmalloc(sizeof(int), GFP_KERNEL); *((int *)s->private) = 5; return ret; } static int ct_close(struct inode *inode, struct file *file) { struct seq_file *s = file->private_data; kfree(s->private); return seq_release(inode, file); } static const struct file_operations ct_file_ops = { .owner = THIS_MODULE, .open = ct_open, .read = seq_read, // .write = seq_write, .llseek = seq_lseek, .release = ct_close }; static int __init ct_init(void) { struct proc_dir_entry *entry; entry = proc_create("sequence", 0, NULL, &ct_file_ops); return 0; } static void __exit ct_exit(void) { remove_proc_entry("sequence", NULL); } module_init(ct_init); module_exit(ct_exit);
整体看来,用户态调用一次读操作,seq_file流程为:该函数调用struct seq_operations结构提顺序为:start->show->next->show…->next->show->next->stop->start->stop来读取文件
参考文章
读取proc文件之seq_file参考资源
实现内核seq操作的例子相关文章推荐
- 【详细】如何将Java源码打包成可执行的jar文件(windows&linux系统都是可以执行的)
- Linux常用20条命令
- centos7的一些变化,firewalld替换iptables、systemctl 替换service
- linux解压
- Repoforge用在Redhat和CentOS中
- 文本文件和二进制文件的区别
- Linux文件列表权限
- Linux DM9000网卡驱动程序完全分析
- Linux 下安装svn服务器及错误集锦
- Linux 串口驱动设计二
- CentOS/RedHat和Ubuntu/Debian彻底修改主机名(hostname)的方法
- Linux 查看内存插槽数、最大容量和频率
- linux网卡驱动程序分析
- hyper-v 虚拟机 挂载硬盘
- Linux 下 sudoer文件的一些介绍
- Linux C打印IP地址信息
- Linux添加用户(user)到用户组(group)
- fastdfs集群配置
- linux快捷上传下载文件
- Linux下编译安装python3