/* * Simple demonstration of the seq_file interface. * * $Id:
seq.c,v 1.1 2003/02/10 21:02:02 corbet Exp $ */
#include #include #include
#include #include
#include
MODULE_AUTHOR("Jonathan Corbet"); MODULE_LICENSE("Dual BSD/GPL");
/*
使用seq_file接口,需要实现4个函数:start()、next()、stop()、show(),这4个函数用于对设备的输出信息的迭代访问(控制)*/ /* *
The sequence iterator functions. We simply use the count of the * next
line as our internal position. */
/*start()函数,用于设置访问设备的起始位置;本示例的设备位置的含义与proc文件的偏移量相同;返回值作为迭代子*/ static void
*ct_seq_start(struct seq_file *s, loff_t *pos) { loff_t *spos =
kmalloc(sizeof(loff_t), GFP_KERNEL); if (! spos) return NULL; *spos
= *pos; return spos; }
/*next()函数,用于实现迭代子的访问步长,本示例的步长是偏移量递加,每次加1;返回值是新的迭代子*/
static void *ct_seq_next(struct seq_file *s, void *v, loff_t
*pos) { loff_t *spos = (loff_t *) v; *pos = ++(*spos); return
spos; }
/*stop()函数,完成一些清理函数*/
static void ct_seq_stop(struct seq_file *s, void *v) { kfree
(v); }
/* * The show function. */
/*show()函数,用于向proc文件输出设备需要输出的信息;本示例中仅输出迭代子的序列号*/ static int
ct_seq_show(struct seq_file *s, void *v) { loff_t *spos = (loff_t *)
v; seq_printf(s, "%Ld\n", *spos); return 0; }
/* * Tie them all together into a set of seq_operations. */
/*seq_file接口的函数操作集*/ static struct seq_operations ct_seq_ops =
{ .start = ct_seq_start, .next = ct_seq_next, .stop =
ct_seq_stop, .show = ct_seq_show };
/* * Time to set up the file operations for our /proc file. In this
case, * all we need is an open function which sets up the sequence
ops. */
/*proc接口的open方法实现,open()函数将proc文件与seq_file接口的函数操作集关联起来*/
static int ct_open(struct inode *inode, struct file *file) { return
seq_open(file, &ct_seq_ops); };
/* * The file operations structure contains our open function along
with * set of the canned seq_ ops. */
/*proc接口的函数操作集,除open方法外,其他方法不需要实现,已经由seq_file的内部代码实现完毕*/ static struct
file_operations ct_file_ops = { .owner = THIS_MODULE, .open =
ct_open, .read = seq_read, .llseek = seq_lseek, .release =
seq_release }; /* * Module setup and teardown. */
/*模块初始化,创建proc文件*/
static int ct_init(void) { struct proc_dir_entry *entry;
entry = create_proc_entry("sequence", 0, NULL); if
(entry) entry->proc_fops = &ct_file_ops; return 0; }
/*模块注销,删除所创建的proc文件*/
static void ct_exit(void) { remove_proc_entry("sequence",
NULL); }
module_init(ct_init); module_exit(ct_exit);
|