如何在C/C++中获得Linux系统调用的输出

How do I get the output of a Linux System Call in C/C++?

本文关键字:Linux 系统调用 输出 C++      更新时间:2023-10-16

我在Linux内核中添加了一个简单的helloworld系统调用。

sys_helloworld

#include <linux/kernel.h>
asmlinkage long sys_helloworld(void)
{
        printk("Hello worldn");
        return 0;
}

它只是将Hello world打印到内核日志中。

我这样调用sys_helloworld系统调用:

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
   long int a = syscall(314); // 314 is the line number of sys_helloworld in syscall table
   printf("System call sys_helloworld returned %ldn", a);
   return 0;
}

上述程序成功地在内核日志中打印了Hello world

我的问题:

如何在程序中获得sys_hello(将Hello world打印到内核日志)的输出?

您应该在系统调用中添加两个参数:要写入的缓冲区及其大小。然后,您可以使用snprintf()打印您想要的任何字符串。您只需要确保使用正确的系统调用定义宏。由于您需要2个参数,因此此处需要SYSCALL_DEFINE2

#include <linux/kernel.h> /* For snprintf() */
#include <sys/syscall.h> /* For SYSCALL_DEFINE* macros */
SYSCALL_DEFINE2(sys_helloworld, char *, buff, size_t, buff_sz)
{
        snprintf(buff, buff_sz, "Hello worldn");
        return 0;
}

为了完整性,并根据上下文,您可能希望将返回值更改为允许您知道字符串是否被截断的值。

用户代码可以这样称呼它:

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main()
{
   char buf[32];
   long int a = syscall(314, buf, sizeof(buf));
   printf("System call sys_helloworld returned %ldn", a);
   printf("buf = %sn", buf);
   return 0;
}

请注意,通常使用SYSCALL_DEFINE*宏来定义系统调用,而不是手动键入asmlinkage long ....,即使对于没有参数的系统调用(也可以使用SYSCALL_DEFINE0)。这些宏是在include/sys/syscall.h中定义的,您应该使用它们。