我正在研究一个linux内核,所以我尝试编写一个简单的模块。
以下代码应控制调用read()
的{{1}}次:
/proc/proc_test
我遇到的问题是,当我使用#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/kernel.h>
#include <asm/current.h>
static int __init init(void);
static void __exit stop(void);
static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data);
static int counter = 0;
static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data) {
if (size < 256) return -ENOMEM;
return sprintf(buffer, "counter = %d\n", counter++); <-- supposed to be incremented once
}
static int __init init() {
if (create_proc_read_entry("proc_test", 0, NULL, proc_read, NULL) == 0) {
printk(KERN_ERR "Can not creat entry\n");
return -ENOMEM;
}
printk("Entry created!\n");
return 0;
}
static void __exit stop() {
remove_proc_entry("proc_test", NULL);
printk("Entry removed!\n");
return;
}
module_init(init);
module_exit(stop);
MODULE_LICENSE("GPL");
或/proc/proc_test/
从cat
读取时,计数器会增加3而不是1。
输出:
tail
我做错了什么?
答案 0 :(得分:3)
试试这个:
static int proc_read(char *buffer, char **start, off_t offset, int size, int *eof, void *data) {
if (size < 256) return -ENOMEM;
int count= sprintf(buffer, "counter = %d\n", counter++);
*eof = 1;
return count;
}
设置* eof = 1,您的驱动程序通知内核(以及想要读取您的proc文件的应用程序)您的驱动程序已达到EOF。
答案 1 :(得分:3)
唯一不对的是你有一个不合理的期望。是什么让您认为cat /proc/proc_test
只会拨打read
一次?
$ strace cat /proc/self/stat | grep read
read(3, "17423 (cat) R 17420 17420 13224 "..., 32768) = 238
read(3, "", 32768) = 0
$
答案 2 :(得分:1)
即使this answer有一个很好的提示,我也遇到过这个问题。理论上设置*eof = 1
应该已经解决了问题,但不知何故它没有。
我的解决方法是还将此功能添加到功能的顶部:
if (offset > 0) // even though I set *eof = 1, the kernel is still calling me, so return 0 for it to stop
return 0;
上面的评论实际上就是我在自己的模块中所写的内容。
这样做是为了确保只对您的函数(offset
为0)的第一次调用做任何事情。