Linux – 为什么自定义系统调用不能正确使用负数?

我写了一个自定义的系统调用来比较两个整数并返回最大的赋值。 这是我的内核代码(max.c):

#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; } 

我正在使用这个小程序来testing系统调用:

 #include <stdio.h> #include <max.h> int main() { int a, b; scanf("%d", &a); scanf("%d", &b); printf("%d", max(a, b)); return 0; } 

对于正数,或者一个是正数,另一个是负数,对于两个负值处理,max总是返回-1。 我想知道,如果这是因为int – >长转换,但我似乎无法理解是什么原因造成的问题。

如果系统调用返回一个负值,则将其视为错误,并在libc中调用特殊的错误处理代码。 也就是说,返回值被否定并移入errno全局变量,并且系统调用的返回值变为-1

其实,在阅读这篇文章的时候,我发现在Linux上, 只有从-4095到-1的值被认为是错误 ,但是这不是可移植的,如果你希望你的函数能够处理任何可能的值,那么这种方法也不会有帮助。

简而言之,您不能安全地使用系统调用的返回值来返回可能为负数的值。 通常的做法是将指针传递给目标变量来保存结果,并保留成功/失败的返回码。 请注意,使用系统调用执行此操作时,您将使用来自内核空间的用户空间指针,因此需要copy_to_user来编写结果。