This question was migrated from Unix & Linux Stack Exchange because it can be answered on Stack Overflow. Migrated两年前。Learn more。
我在/proc
中实现了一个文件,我希望它比平常多一点。特别是,我想检测到有人在文件中添加了内容并正确地处理它——也就是说,我想区分
echo value > /proc/my_proc_file
和
echo value >> /proc/my_proc_file
与所有写函数一样,mine的第四个参数是offset:
ssize_t my_proc_write(struct file *file, const char __user *buf,
size_t count, loff_t *offs)
但是
*offs
总是0。当我设置proc文件时,我将
seq_lseek
指定为lseek函数:struct file_operations my_proc_fops = {
.open = my_proc_open,
.read = seq_read,
.write = my_proc_write,
.llseek = seq_lseek,
};
检查源代码(在
fs/seq_file.c
中),看起来seq_lseek
适当地维护了file->f_pos
,但是当我在write函数中查看file->f_pos
时,它也总是0。(这可能并不奇怪,因为追加通常意味着使用O_APPEND
打开,这不会导致对lseek的任何显式调用。)不管怎样,有办法吗?如果这些写函数不时不时地传递有用的非零值,它们可能就不会设置偏移指针参数…
最佳答案
首先,从用户的角度来看,使用o_append打开的文件在调用write()时总是会附加数据,不管f_pos是由llseek()设置的。但是f_pos对于read()仍然有效。
其次,kernel framework不知道文件长度,除非它调用llseek来查找,但这不会发生,因为它会弄乱f_pos,所以kernel希望您的驱动程序(这是唯一知道真正的“文件结尾”在哪里的驱动程序)在(file->f_flags&o_append)为true时执行相应的操作。基本上,您的驱动程序需要在调用write()时检查该标志,忽略off参数并执行追加。