如何从C/C++应用程序进行Linux系统调用,而不使用汇编,并且以独立于CPU的方式?

joh*_*dav 0 c c++ linux assembly system-calls

我期待编写一个程序,需要对进程进行低级别的工作(即使用fork系统调用等).该程序用C++编写,只能在Linux上运行.理想情况下,这将是整个CPU架构(即86,x86_64和ARM)与只不过是重新编译更便携,但我只真正需要x86_64的支持.

由于每个Linux系统调用都需要许多参数并在cpu寄存器中返回许多参数(通常只有1个返回值),因此每个系统调用的C函数包装器很容易实现.另外,因为AFAIK,在内核中实现的系统调用具有相同的参数和返回值,如果是不同的汇编级实现,则可以公开相同的C接口.

这样的事情存在吗?如果是这样,我该如何访问它?

它的文档在哪里(可用函数列表,它们的解释参数以及函数的确切解释)?

Pet*_*des 10

libc已经包含了您正在寻找的包装函数.#include <unistd.h>正如POSIX所指出的,其中许多原型都在.

C是Unix(和Linux)上的低级系统程序的语言,所以这是因为Unix存在的事情.(在libc中提供包装函数比教学编译器更容易实现函数调用和系统调用之间的区别,并允许设置errno错误.它还允许LD_PRELOAD在用户空间中拦截系统调用等技巧.)


系统调用的手册页在第2节,而第3节则是库函数(可能会也可能不会使用系统调用作为其实现的一部分:math.h cos(3),ISO C stdio printf(3)fwrite(3)vs. POSIX write(2)).

execve(2) 是系统调用.

看到execl(3)和朋友也是libc的一部分,并最终打电话execve(2).它们是方便的包装器,用于构建argv数组,进行$PATH查找以及传递当前进程的环境.因此,它们被归类为函数,而不是系统调用.

有关syscalls(2)概述,请参阅系统Linux调用的完整列表,其中包含指向其man-page包装器的链接.(我已经链接了Linux手册页,但是所有标准系统调用都有POSIX手册页.)


在你没有连接libc中的可能性不大的情况下,你可以像使用MUSL的宏syscall2/ syscall3/等宏(数量为ARG计数)为嵌入任何平台上正确的ASM.您使用__NR_writefrom asm/unistd.h来获取系统调用号码.

但请注意,原始Linux系统调用可能与libc包装器提供的接口存在细微差别.例如,他们不会检查pthreads取消点,并且brk/ sbrk需要libc在用户空间中进行簿记.

请参阅Android中的SYSCALL_INLINE以获取sys_write()使用MUSL宏的可移植原始内联包装器.

但是,如果你正在使用的libc像正常人一样像函数mallocprintf,你应该只使用它的系统调用包装功能.