Linux - 为什么自定义系统调用不能正确处理负数? [英] Linux - Why doesn't a custom system call work properly with negative numbers?

查看:229
本文介绍了Linux - 为什么自定义系统调用不能正确处理负数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I wrote a custom system call that compares two integers and returns the biggest one. Here's my kernel-side code:

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

这是我的用户空间代码:

And here's my user-space code:

max.h

#include <unistd.h>
#define SYS_MAX 323

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

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

I'm using this little program to test the system call:

#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转换,但我似乎无法理解导致问题的原因。

It's working great for positive numbers, or when one is positive and the other negative, but max always returns -1 when dealing with two negative values. I've wondered if this is because of the int->long conversion, but I can't seem to understand what's causing the problem.

推荐答案

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

If a system call returns a negative value it's treated as an error, and special error handling code is invoked in libc. Namely, the return value is negated and moved into the errno global variable, and the return value of the system call becomes -1.

实际上,在阅读本文时我发现在Linux上,仅将-4095到-1的值视为错误,但这既不便于携带,也不是有用的您的函数可以处理任何可能的值。

Actually, while reading about this I discovered that on Linux, only values from -4095 to -1 are treated as errors, but this is neither portable, nor helpful if you want your function to work on any possible values.

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

In short, you can't safely use the return value of a syscall to return a value that might be negative. The usual convention would be to pass a pointer to a destination variable to hold the result, and reserve the return code for success/failure. Note that when doing this with a syscall you will be working with a user-space pointer from kernel-space, so copy_to_user will be necessary to write the result.

这篇关于Linux - 为什么自定义系统调用不能正确处理负数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆