2014-04-13 38 views
0

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

问题是即使我打印在离开写入之前的返回值,并且在我测试的客户端程序中以-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 
+0

你用什么程序写入设备文件?当你看到上述行为时,你可以举个例子吗?另外,您可以粘贴:count的值,还是从内核日志中看到的两个retval语句? –

+0

我已添加更多详情。我测试的程序和内核日志。 – silentnights

+0

你的“客户”程序的输出是什么? –

回答

3

测试内核的东西时,尽量使用低级用户空间API。如果你使用的是write()(系统调用),一切都会好的(你会得到你的错误代码)。但是,你决定去处理更为复杂的fwrite()功能,做不同的东西(http://linux.die.net/man/3/fwrite):

成功时,FREAD()和fwrite()返回的数项读取或写入 。此数字等于仅当 大小为1时传输的字节数。如果发生错误或达到文件末尾,则返回值为短项数(或零)。 ()不区分文件结束和错误,调用者 必须使用feof(3)和ferror(3)来确定发生的事件。

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

+0

很好的解释。我猜“如果misc_write中的条件”失败并返回“-EINVAL”。如果(strncmp(MY_UNIQUE_ID,buff,count)) retval = -EINVAL; –

+0

非常感谢,现在我可以克服这一点,一直呆在那里。 对不起,我迟到的回应。 – silentnights