不遵守file_operations.write的返回值

时间:2014-04-13 19:00:32

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

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

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

以下是我写函数的示例:

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

1 个答案:

答案 0 :(得分:3)

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

  

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

     

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

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