linux内核seq操作

头文件linux/seq_file.h
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来读取文件


参考文章

  1. 读取proc文件之seq_file

参考资源

  1. 实现内核seq操作的例子
    其他可以参考的文章
    http://blog.chinaunix.net/uid-28253945-id-3382865.html
    http://blog.chinaunix.net/uid-28253945-id-3382866.html
    http://blog.csdn.net/itsenlin/article/details/43376991
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luckywang1103

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值