c - Linux - 为什么自定义系统调用不能正常使用负数?

标签 c linux linux-kernel int system-calls

我编写了一个自定义系统调用来比较两个整数并返回最大的一个。这是我的内核端代码:

最大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;
  }
}

这是我的用户空间代码:

最大高度

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

对于正数,或者当一个为正而另一个为负时,它非常有用,但在处理两个负值时,max 总是返回 -1。我想知道这是否是因为 int->long 转换,但我似乎无法理解导致问题的原因。

最佳答案

如果系统调用返回负值,则将其视为错误,并在 libc 中调用特殊的错误处理代码。即,将返回值取反,移入errno全局变量,系统调用的返回值变为-1

实际上,在阅读这篇文章时我发现在 Linux 上,only values from -4095 to -1 are treated as errors ,但如果您希望您的函数处理任何可能的值,这既不可移植,也无济于事。

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

关于c - Linux - 为什么自定义系统调用不能正常使用负数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33588033/

相关文章:

c - C 中的 abs 函数

linux - 比较两个目录中的文件和版本,其中一个目录有符号链接(symbolic link)?

c - 将附加信息附加到 Linux 内核中的 SKB 缓冲区

我可以使用一个进程中的 PTE 来指示物理内存片段以在其他进程中创建适当的 PTE 吗?

c++ - 函数参数太少 ‘memcpy’

c - 如何查看输入的值是数字而不是字符?

c++ - sizeof(size_t) 可以小于 sizeof(int) 吗?

linux - 检查屏幕 session 是否正在运行并通过 cron 自动执行

c - 重定向到 execlp()

linux - 完成压缩 IP 报头的 Xmit