2014-04-13 36 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