【问题标题】:Return value from file_operations.write is not respected不遵守 file_operations.write 的返回值
【发布时间】:2014-04-15 12:50:05
【问题描述】:

我正在为 linux 内核编写一个简单的 misc 设备驱动程序。 在我的 file_operations.write 中,我很少检查并将传递的值与预定义的值进行比较,如果值相等,则返回字符串长度,否则返回 -EINVAL

问题是,即使我在离开写入之前打印了返回值,并且它在日志中打印为 -22,在我测试的客户端程序中,我一直在获取传递给写入系统的字节数称呼。 !

以下是我的 write 函数的示例:

ssize_t misc_write(struct file *filp, const char __user *buff,
            size_t count, loff_t *offp)
{
    ssize_t retval;
    pr_crit("count: %zu\n", count);
    pr_crit("strlen(MY_UNIQUE_ID) + 1: %zu\n", strlen(MY_UNIQUE_ID) + 1);
    printk(KERN_INFO "Inside write \n");
    if (count != (strlen(MY_UNIQUE_ID) + 1)) {
            retval = - EINVAL;
            pr_crit("retval: %i\n", retval);
            goto out;
    }
    if (strncmp(MY_UNIQUE_ID, buff, count))
            retval = -EINVAL;
    else   
            retval = count;
out:   
    pr_crit("retval: %i\n", retval);
    return retval;
}

下面是我的测试客户端:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
    char buffer[] = "0daf007211a9";
    char filename[] = "/dev/misctest";
    int string_size, write_size;
    FILE *handler = fopen(filename, "r+");
    if (handler == 0)
    {
            printf("error openning file\n");
            return -1;
    }       
    write_size = fwrite(&buffer, sizeof(char), 2, handler);
    if (write_size < 0)
            printf("Error");
    printf("write_size: %i\n", write_size);
    return 0;
}     

这是内核日志中打印的内容:

[793868.964583] count: 2
[793868.964593] strlen(MY_UNIQUE_ID) + 1: 13
[793868.964596] Inside write 
[793868.964600] retval: -22
[793868.964602] retval: -22

【问题讨论】:

  • 您使用什么程序写入设备文件?当你看到上述行为时,你能举个例子吗?另外,您能否粘贴以下值:count 和您从内核日志中看到的两个 retval 语句?
  • 我添加了更多细节。我测试的程序和内核日志。
  • 你的“客户端”程序的输出是什么?
  • FWIW,您可以简单地使用“sudo bash -c echo -n 'yourdata' > /dev/misctest'”或“dd”来测试您的 misc 设备驱动程序。
  • 另外,你为什么要在“r+”中打开你的文件,而你只是想写?

标签: c linux linux-kernel linux-device-driver


【解决方案1】:

在测试内核内容时,请始终使用尽可能低级的用户空间 API。如果你使用write()(系统调用)一切都会好起来的(你会得到你的错误代码)。但是你决定使用更复杂的 fwrite() 函数,它做一些不同的事情 (http://linux.die.net/man/3/fwrite):

成功时,fread() 和 fwrite() 返回读取的项目数或 书面。此数字等于仅在以下情况下传输的字节数 size 为 1。如果发生错误或到达文件末尾,则 返回值是一个简短的项目计数(或零)。

fread() 不区分文件结束和错误,以及调用者 必须使用 feof(3) 和 ferror(3) 来确定发生了什么。

事实上,fwrite() 不可能返回负值,即使它也想返回(查看它的签名)。

【讨论】:

  • 很好的解释。我猜“如果 misc_write 中的条件”失败并返回“-EINVAL”。 if (strncmp(MY_UNIQUE_ID, buff, count)) retval = -EINVAL;
  • 非常感谢,现在我可以克服这个问题了,我已经卡在那里一段时间了。很抱歉我的回复晚了。
猜你喜欢
  • 2011-04-30
  • 2016-08-29
  • 2023-03-13
  • 2019-03-09
  • 1970-01-01
  • 2011-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多