Linux内核实践之序列文件

发表于:2012-4-01 10:45

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bullbat(CSDNblog)    来源:51Testing软件测试网采编

分享:

  我们这里调用seq_open函数建立这种关联。

int seq_open(struct file *file, const struct seq_operations *op)
{
 struct seq_file *p = file->private_data;/*p为seq_file结构实例*/

 if (!p) {
  p = kmalloc(sizeof(*p), GFP_KERNEL);
  if (!p)
   return -ENOMEM;
  file->private_data = p;/*放到file的private_data中*/
 }
 memset(p, 0, sizeof(*p));
 mutex_init(&p->lock);
 p->op = op;/*设置seq_file的operation为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() and pread().  They do not implement
  * write() at all, but we clear FMODE_PWRITE here for historical
  * reasons.
  *
  * If a client of seq_files a) implements file.write() and b) wishes to
  * support pwrite() then that client will need to implement its own
  * file.open() which calls seq_open() and then sets FMODE_PWRITE.
  */
 file->f_mode &= ~FMODE_PWRITE;
 return 0;
}

  可以看到,我们的seq_file结构以file的私有数据字段传入虚拟文件系统,同时在open函数中设置了seq_file的操作实例。

  我们看下面这个简单的例子:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>


#define MAX_SIZE 10


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mike Feng");

/*用于操作的数据*/
struct my_data
{
 int data;
};

/*全局变量*/
struct my_data *md;

/*数据的申请*/
struct my_data* my_data_init(void)
{
 int i;
 md=(struct my_data*)kmalloc(MAX_SIZE*sizeof(struct my_data),GFP_KERNEL);

 for(i=0;i<MAX_SIZE;i++)
  (md+i)->data=i;

 return md;
}

/*seq的start函数,仅仅做越界判断然后返回pos*/
void *my_seq_start(struct seq_file *file,loff_t *pos)
{
 return (*pos<MAX_SIZE)? pos :NULL;
}

/*seq的next函数,仅仅做越界判断然后pos递增*/
void *my_seq_next(struct seq_file *p,void *v,loff_t *pos)
{
 (*pos)++;
 if(*pos>=MAX_SIZE)
  return NULL;

 return pos;
}

/*seq的show函数,读数据的显示*/
int my_seq_show(struct seq_file *file,void *v)
{
 unsigned int i=*(loff_t*)v;
 seq_printf(file,"The %d data is:%d\n",i,(md+i)->data);
 
 return 0;
}

/*seq的stop函数,什么也不做*/
void my_seq_stop(struct seq_file *file,void *v)
{

}


/*operations of seq_file */
static const struct seq_operations my_seq_ops={
 .start =my_seq_start,
 .next =my_seq_next,
 .stop =my_seq_stop,
 .show =my_seq_show,
};

/*file的open函数,用于seq文件与虚拟文件联系*/
static int my_open(struct inode *inode,struct file *filp)
{
 return seq_open(filp,&my_seq_ops);
}

/*file操作*/
static const struct file_operations my_file_ops={
 .open =my_open,
 .read =seq_read,
 .llseek =seq_lseek,
 .release=seq_release,
 .owner =THIS_MODULE,
};

static __init int my_seq_init(void)
{
 struct proc_dir_entry *p;
 my_data_init();
 p=create_proc_entry("my_seq",0,NULL);
 if(p)
 {
  p->proc_fops=&my_file_ops;
 }

 return 0;
 
}

static void my_seq_exit(void)
{
 remove_proc_entry("my_seq",NULL);
}

module_init(my_seq_init);
module_exit(my_seq_exit);

42/4<1234>
精选软件测试好文,快来阅读吧~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号