Linux - 为什么自定义系统调用不能正常处理负数?
Linux - Why doesn't a custom system call work properly with negative numbers?
我写了一个自定义系统调用来比较两个整数和 returns 最大的一个。这是我的内核端代码:
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;
}
}
这是我的用户-space代码:
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;
}
它对正数非常有效,或者当一个为正而另一个为负时,但在处理两个负值时最大值总是 returns -1。我想知道这是否是因为 int->long 转换,但我似乎无法理解导致问题的原因。
如果系统调用 return 为负值,则将其视为错误,并在 libc 中调用特殊的错误处理代码。即return值取反,移入errno
全局变量,系统调用的return值变为-1
.
实际上,在阅读这篇文章时,我发现 Linux、only values from -4095 to -1 are treated as errors,但这既不可移植,如果您希望您的函数处理任何可能的值,也无济于事。
简而言之,您不能安全地将系统调用的 return 值用于 return 可能为负的值。通常的约定是传递一个指向目标变量的指针来保存结果,并为 success/failure 保留 return 代码。请注意,当使用系统调用执行此操作时,您将使用来自 kernel-space 的 user-space 指针,因此需要 copy_to_user 来写入结果。
我写了一个自定义系统调用来比较两个整数和 returns 最大的一个。这是我的内核端代码:
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;
}
}
这是我的用户-space代码:
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;
}
它对正数非常有效,或者当一个为正而另一个为负时,但在处理两个负值时最大值总是 returns -1。我想知道这是否是因为 int->long 转换,但我似乎无法理解导致问题的原因。
如果系统调用 return 为负值,则将其视为错误,并在 libc 中调用特殊的错误处理代码。即return值取反,移入errno
全局变量,系统调用的return值变为-1
.
实际上,在阅读这篇文章时,我发现 Linux、only values from -4095 to -1 are treated as errors,但这既不可移植,如果您希望您的函数处理任何可能的值,也无济于事。
简而言之,您不能安全地将系统调用的 return 值用于 return 可能为负的值。通常的约定是传递一个指向目标变量的指针来保存结果,并为 success/failure 保留 return 代码。请注意,当使用系统调用执行此操作时,您将使用来自 kernel-space 的 user-space 指针,因此需要 copy_to_user 来写入结果。