打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
seq_file源码分析

seq_file源码分析

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);};
seq_file的使用
struct file_operations exam_seq_file_ops = {.owner   = THIS_MODULE,.open    = exm_seq_open,.read    = seq_read,.llseek  = seq_lseek,.release = seq_release};
static int exam_seq_open(struct inode *inode, struct file *file){return seq_open(file, &exam_seq_ops);};

struct proc_dir_entry *entry;            entry = create_proc_entry("exam_seq_file", 0, NULL);            if (entry)            entry->proc_fops = &exam_seq_file_ops;


当用户态的程序打开这个对应的proc目录时,open->sysopen->exm_seq_open->seq_open(file,&exam_seq_ops),下面我们主要来看下seq_open函数
int seq_open(struct file *file, const struct seq_operations *op)
{
 struct seq_file *p = file->private_data;

 if (!p) {
  p = kmalloc(sizeof(*p), GFP_KERNEL); 
  if (!p)
   return -ENOMEM;
  file->private_data = p;
 }
 memset(p, 0, sizeof(*p));
 mutex_init(&p->lock);
 p->op = op;

 /*
  * Wrappers around seq_open(e.g. swaps_open) need to be
  * aware of this. If they set f_version themselves, they
  * should call seq_open first and then set f_version.
  */
 file->f_version = 0;

 /* SEQ files support lseek, but not pread/pwrite */
 file->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE);
 return 0;
}
struct seq_file {
 char *buf;
 size_t size;
 size_t from;
 size_t count;
 loff_t index;
 u64 version;
 struct mutex lock;
 const struct seq_operations *op;
 void *private;
};
再来看下seq_read函数
/**
 * seq_read - ->read() method for sequential files.
 * @file: the file to read from
 * @buf: the buffer to read to
 * @size: the maximum number of bytes to read
 * @ppos: the current position in the file
 *
 * Ready-made ->f_op->read()
 */
ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)
{
 struct seq_file *m = (struct seq_file *)file->private_data;
 /* grab buffer if we didn't have one */
 if (!m->buf) {
  m->buf = kmalloc(m->size = PAGE_SIZE, GFP_KERNEL);
  if (!m->buf)
   goto Enomem;
 }
 p = m->op->start(m, &pos);
 while (1) {
  err = m->op->show(m, p);

   p = m->op->next(m, p, &pos);

  m->op->stop(m, p);
  }
} //可见seq_read函数分别调用了自定义的seq_operation结构中的回调函数start,show,next,stop等函数。
这样就将vfs层的sys_read->seq_read(调用我们自己定义的seq_operation的start,show,next,stop等函数),从而可以根据我们自己选择的方式去显示我们的数据。

 关于proc,seq_file的使用和介绍参考:

在 Linux 下用户空间与内核空间数据交换的方式,第 2 部分: procfs、seq_file、debugfs和relayfs

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
内核模块遍历进程--内核PS - ldd学习笔记 - ubuntuer zone
在 Linux 下用户空间与内核空间数据交换的方式,第 2 部分: procfs、seq_file、debugfs和relayfs
Linux RTC驱动分析(三)
Linux编程:proc_mkdir与proc_create
创建属于自己的系统信息,往proc中留下一个脚印
第44回 | 进程的阻塞与唤醒
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服