Linux字符设备问题:用户空间cat命令持续读取无法停止
回答
嘿,这个问题其实是字符设备驱动里很常见的小疏漏——你没处理文件偏移量offp,导致cat以为永远有数据可读,一直在发起读取请求~
具体原因:
Linux字符设备的read函数里,loff_t *offp这个参数是用来记录当前文件的读取位置的。每次完成读取后,你得更新这个偏移量,告诉内核“下次从这里接着读”。但你现在的代码完全没碰它,所以每次调用read时,偏移量始终停在初始值(比如0),你的代码每次都会重新生成那行Major number: 242的内容并返回有效字节数。用户空间的cat程序逻辑是:只要read返回大于0的字节数,就认为还有数据没读完,会立刻发起下一次read调用,循环往复停不下来。
修复方案:
你需要在read函数里更新offp,并且当所有内容都读完时返回0(这是Linux里表示“文件结束(EOF)”的标准方式)。给你改个示例代码:
static ssize_t useless_read(struct file *filp, char __user *buff, size_t count, loff_t *offp) { int ret, read_count; // 先判断:如果已经读过一次,偏移量不为0,直接返回0表示EOF if (*offp != 0) { return 0; } read_count = sprintf(message, "Major number: %d\n", MAJOR(useless_chr_dev->cdev_num)); ret = copy_to_user(buff, message, read_count); if (ret == 0) { printk(KERN_INFO "userspace read success"); // 更新偏移量,把本次读取的字节数加上去 *offp += read_count; return read_count; } else return -EFAULT; }
这样改完后,第一次read会正常返回内容并更新偏移量,第二次调用read时,因为偏移量已经不是0了,直接返回0,cat收到EOF信号就会停止读取,不会再循环打印那行内容啦。
如果以后你的驱动要支持更长的内容或者随机读取,还可以更灵活地处理:比如先计算当前偏移量到内容末尾的剩余字节数,只返回用户请求的字节数和剩余字节数中较小的那个,同时更新偏移量,直到偏移量等于内容总长度时返回0,这样兼容性更好。
内容的提问来源于stack exchange,提问作者Jay Aurabind
相关产品推荐
相关产品推荐

