从/ proc读取时使用seq_file实现的无限循环

时间:2015-06-08 17:09:22

标签: linux linux-kernel filesystems

我写了一个简单的代码片段来了解/proc文件系统的用法。当我完成时,一切都很好,除了从这个文件读取导致无限循环。

下面显示了一些代码:

static struct seq_operations proc_seq_ops = {
    .start = proc_seq_start,
    .next = proc_seq_next,
    .stop = proc_seq_stop,
    .show = proc_seq_show,
};


int proc_seq_open(struct inode *inode, struct file *filp)
{
    return seq_open(filp, &proc_seq_ops);
}

static void *proc_seq_start(struct seq_file *s_file, loff_t *pos)
{
    PDEBUG("seq file start\n");
    if (list_empty(&store_list_head))
        return NULL;
    return list_first_entry(&store_list_head, struct store_node,       list);
}

static void *proc_seq_next(struct seq_file *s_file, void *v, loff_t *pos)
{
    void *tmp = NULL;
    PDEBUG("seq file next\n");
    tmp = list_next_entry((struct store_node *)v, list);
    if (&((struct store_node *)tmp)->list == &store_list_head) {
        PDEBUG("seq next return NULL\n");
        return NULL;
    }

    PDEBUG("seq file now is returning %p\n", tmp);
    return tmp;
}

static void proc_seq_stop(struct seq_file *s_file, void *v)
{
    PDEBUG("seq stop\n");
}

static int proc_seq_show(struct seq_file *s_file, void *v)
{
    PDEBUG("%p -> %s\n", v, ((struct store_node *)v)->buf);
    seq_printf(s_file, "%p -> %s\n", v, ((struct store_node *)v)->buf);
    return 0;
}

将要打印的数据放在列表中。在每次调用seq_next时,我们都会前往下一个节点。

节点的结构非常简单:

struct store_node {
    list_head list;
    char *buf;
};

当我使用cat命令读取此proc文件,然后通过dmesg检查输出时,我得到了这个:

[  893.111027] proc-fs-iterator: seq file next
[  893.111028] proc-fs-iterator: seq next return NULL
[  893.111028] proc-fs-iterator: seq stop
[  893.111036] proc-fs-iterator: seq file start
[  893.111037] proc-fs-iterator: ffff88002f863dc0 -> 1234

[  893.111038] proc-fs-iterator: seq file next
[  893.111039] proc-fs-iterator: seq next return NULL
[  893.111040] proc-fs-iterator: seq stop
[  893.111062] proc-fs-iterator: seq file start
[  893.111064] proc-fs-iterator: ffff88002f863dc0 -> 1234

[  893.111065] proc-fs-iterator: seq file next
[  893.111066] proc-fs-iterator: seq next return NULL
[  893.111067] proc-fs-iterator: seq stop

为什么无限打印?实际执行了seq_stop

1 个答案:

答案 0 :(得分:1)

您忘记更新*pos处理程序中的_next参数。通常,每_next次呼叫增加1。 更新:您的_start处理程序也应该导航到给定的位置。

无限循环实际上是cat实现的结果:它调用 read(2)直到它返回0或-1。由于您的实现不更新位置,每个 read(2)调用从开头读取并返回正值(已读取非零字节)。

在内核中使用的BTW,C标准允许void*和其他指针类型之间的隐式转换。因此,您可以安全地在tmp处理程序中将_next变量声明为struct store_node *tmp;。例如,请参阅seq_list_*内核源代码中的fs/seq_file.c个处理程序。