【问题标题】:Linux - Why doesn't a custom system call work properly with negative numbers?Linux - 为什么自定义系统调用不能与负数一起正常工作?
【发布时间】:2018-07-24 17:32:09
【问题描述】:

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

ma​​x.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;
  }
}

这是我的用户空间代码:

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

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

【问题讨论】:

  • int max(int num1, int num2){} - 这是一个函数定义,而不是声明。你的意思是int max(int, int);
  • 如果您将max 函数重命名为mymax,有什么变化吗?
  • @melpomene 英语不是我的母语,所以我不确定这里的正确词是什么。但关键是函数max必须返回一个整数,并接收两个整数作为参数。
  • 不,关键是您的标题中需要;,而不是{}
  • @melpomene 更改函数名称并没有改变任何内容。

标签: c linux linux-kernel int system-calls


【解决方案1】:

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

实际上,在阅读此内容时,我发现在 Linux 上 only values from -4095 to -1 are treated as errors,但如果您希望您的函数处理任何可能的值,这既不便携,也没有帮助。

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

【讨论】:

  • 非常感谢您的努力和回答。我在实现 copy_to_user 和 copy_from_user 函数时遇到问题。关于如何做到这一点的任何提示?
  • @BernardoLopes 这是另一个问题,我不能很好地回答。搜索答案,如果您无法弄清楚,请在 SO 上提出一个新问题 :)
  • 谢谢,我会尝试使用新代码。编译完成后我会报告。
猜你喜欢
  • 2020-06-12
  • 2021-08-18
  • 1970-01-01
  • 2019-01-06
  • 2012-09-04
  • 2019-05-31
  • 2021-12-06
  • 2020-09-01
  • 1970-01-01
相关资源
最近更新 更多