You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:39:03