【发布时间】:2020-01-01 16:58:48
【问题描述】:
我正在对seq_files 进行一些实验,但对此有些困惑。
我从seq_file.c分析了常用函数的实现,通过seq_printf实现判断struct seq_file的内部char *buf完全用于存储格式化字符串以复制到seq_read中的用户。但是seq_file.c中定义了seq_write函数,可以写入缓冲区。
问题: 是否可以重用struct seq_file 的内部缓冲区并将其用于写入来自用户的数据或仅用于数据格式化?
我目前使用另一个缓冲区来写入数据,struct seq_file 仅用于数据格式化:
static char buf[4096];
static char *limit = buf;
void *pfsw_seq_start(struct seq_file *m, loff_t *pos){
if(*pos >= limit - buf) {
return NULL;
}
char *data = buf + *pos;
*pos = limit - buf;
return data;
}
void pfsw_seq_stop(struct seq_file *m, void *v){ }
void *pfsw_seq_next(struct seq_file *m, void *v, loff_t *pos){ return NULL; }
int pfsw_seq_show(struct seq_file *m, void *v){
seq_printf(m, "Data: %s\n", (char *) v);
return 0;
}
ssize_t pfsw_seq_write(struct file *filp, const char __user * user_data, size_t sz, loff_t *off){
if(*off < 0 || *off > sizeof buf){
return -EINVAL;
}
size_t space_left_from_off = sizeof buf - (size_t) *off;
size_t bytes_to_write = space_left_from_off <= sz ? space_left_from_off : sz;
if(copy_from_user(buf + *off, user_data, bytes_to_write)){
return -EAGAIN;
}
*off += bytes_to_write;
if(*off > limit - buf){
limit = buf + *off;
}
return bytes_to_write;
}
所以我将struct file_operations定义为
static const struct seq_operations seq_ops = {
.start = pfsw_seq_start,
.stop = pfsw_seq_stop,
.next = pfsw_seq_next,
.show = pfsw_seq_show
};
int pfsw_seq_open(struct inode *ino, struct file *filp){
return seq_open(filp, &seq_ops);
}
static const struct file_operations fops = {
.open = pfsw_seq_open,
.read = seq_read,
.write = pfsw_seq_write,
.release = seq_release,
};
【问题讨论】:
-
如果你需要一个临时缓冲区,我想你可以,但你为什么不能直接复制到数据需要去的地方?
-
@stark 例如,如果某个大对象是由用单独的
writes 编写的小块组装而成的。然后它会去其他地方。 -
@0andriy 我真正感到困惑的是,使用
procfs进行这样的写作是否很常见。为较新内核开发的模块是否应该切换到sysfs? -
对不起,我没有很好地阅读这个问题。为什么首先需要使用 seq_file?
-
@0andriy 嗯...那么有什么替代方案?
标签: c linux linux-kernel linux-device-driver