读取/proc下文件数据方法有两种:
1.使用read_proc,此方法一次最多只能返回1 PAGE(页)内页大小的数据,不适合大数据量交换
创建:使用 create_proc_read_entry(NAEM, MASK, MODE, read_proc, void *for_read_proc_data);
前面3个参数用于创建 /proc/xxxx 文件 ,第3个参数为 read_proc 函数名, 最后参数为传递给 read_proc 函数使用的参数
如:
/*在 /proc 下创建my_proc_dir 目录,如 /proc/my_proc_dir */
struct proc_dir_entry *proc_entry = proc_mkdir("my_proc_dir", NULL);
/*在/proc下创建/proc/my_proc_dir/name 文件, 并关联读取name文件数据时(cat /proc/my_proc_dir/name), 使用my_read_proc函数*/
create_proc_read_entry("name", 0744, proc_entry, my_read_proc, NULL);
2.使用seq_file 对/proc文件进行大数据量获取
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_open函数调用中分配, 然后作为参数传递给每个seq_file的操作函数。private变量可以用来在各个操作函数之间传递参数。
seq_file要实现4个操作函数:
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);
};
使用如下:
static void *my_seq_start(struct seq_file *s, loff_t *pos)
{
static unsigned long counter = 0;
/* beginning a new sequence ? */
if ( *pos == 0 )
{
/* yes => return a non null value to begin the sequence */
return &counter;
}
else
{
/* no => it's the end of the sequence, return end to stop reading */
*pos = 0;
return NULL;
}
}
static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
unsigned long *tmp_v = (unsigned long *)v;
(*tmp_v)++;
(*pos)++;
return NULL;
}
static void my_seq_stop(struct seq_file *s, void *v)
{
}
static int my_seq_show(struct seq_file *s, void *v)
{
loff_t *spos = (loff_t *) v;
seq_printf(s, "%Ld\n", *spos);
return 0;
}
static struct seq_operations my_seq_ops = {
.start = my_seq_start,
.next = my_seq_next,
.stop = my_seq_stop,
.show = my_seq_show
};
static int my_open(struct inode *inode, struct file *file)
{
return seq_open(file, &my_seq_ops);
};
static struct file_operations my_file_ops = {
.owner = THIS_MODULE,
.open = my_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
};
int init_module(void)
{
struct proc_dir_entry *entry;
entry = create_proc_entry(PROC_NAME, 0, init_net.proc_net);
if (entry) {
entry->proc_fops = &my_file_ops;
}
return 0;
}
void cleanup_module(void)
{
remove_proc_entry(PROC_NAME, init_net.proc_net);
}