2015-11-07 34 views
5

我寫了一個自定義系統調用,用於比較兩個整數並返回最大值的賦值。這裏是我的內核端代碼(max.c):Linux - 爲什麼自定義系統調用不能正確使用負數?

#include <linux/kernel.h> 
#include <linux/syscalls.h> 

asmlinkage long sys_max(int num1, int num2) 
{ 
    if (num1 > num2) 
    { 
    return num1; 
    } 

    else 
    { 
    return num2; 
    } 
} 

這是我的用戶空間代碼(max.h):

#include <unistd.h> 
#define SYS_MAX 323 

int max(int num1, int num2) 
{ 
    int maxnumber = syscall(SYS_MAX, num1, num2); 
    return maxnumber; 
} 

我用這個小程序來測試系統撥打:

#include <stdio.h> 
#include <max.h> 

int main() 
{ 
    int a, b; 
    scanf("%d", &a); 
    scanf("%d", &b); 
    printf("%d", max(a, b)); 
    return 0; 
} 

它爲正數偉大的工作,或者當一個爲正,另一個爲負,但最大總是返回-1兩個負值的時候。我想知道這是由於int-> long轉換,但我似乎無法理解是什麼導致了這個問題。

+0

int max(int num1,int num2){}' - 這是一個函數定義,而不是聲明。你是不是指'int max(int,int);'? – melpomene

+0

如果您將'max'函數重命名爲'mymax',是否會發生任何變化? – melpomene

+0

@melpomene英語不是我的母語,所以我不確定這裏有什麼合適的詞。但重點是,函數max必須返回一個整數並接收兩個整數作爲參數。 –

回答

10

如果系統調用返回負值,則將其視爲錯誤,並在libc中調用特殊的錯誤處理代碼。即,返回值被否定並移入errno全局變量,並且系統調用的返回值變爲-1

事實上,在閱讀這篇文章時,我發現在Linux上,only values from -4095 to -1 are treated as errors,但這不是可移植的,如果你想讓你的函數能夠處理任何可能的值,這也不是有幫助的。

簡而言之,您無法安全地使用系統調用的返回值來返回可能爲負數的值。通常的慣例是將指針傳遞給目標變量以保存結果,並保留成功/失敗的返回碼。請注意,使用系統調用執行此操作時,您將使用來自內核空間的用戶空間指針,因此需要copy_to_user來編寫結果。

+0

非常感謝您的努力和答案。我在實現copy_to_user和copy_from_user函數時遇到了問題。有關如何做到這一點的任何提示? –

+0

@BernardoLopes這是另一個問題,我不能很好地回答。搜索一個答案,如果你不能弄明白,就問這個新問題:) – hobbs

+0

謝謝,我會嘗試使用新的代碼。編譯完成後我會報告。 –

相關問題