系统调用通常是向操作系统(内核)发出的请求,以执行硬件/系统特定的或特权操作。 在 Linux-1.2 中,已经定义了 140 个系统调用。 像 close() 这样的系统调用在 Linux libc 中实现。 此实现通常涉及调用一个宏,该宏最终会调用 syscall()。 传递给 syscall() 的参数是系统调用的编号,后跟所需的参数。 实际的系统调用编号可以在 <linux/unistd.h> 中找到,而 <sys/syscall.h> 会随着新的 libc 更新。 如果出现新的调用,但 libc 中还没有相应的存根,你可以使用 syscall()。 例如,你可以像这样使用 syscall() 关闭文件(不建议这样做)
#include <syscall.h> extern int syscall(int, ...); int my_close(int filedescriptor) { return syscall(SYS_close, filedescriptor); }
在 i386 架构上,由于硬件寄存器的数量,系统调用除了系统调用号之外,最多只能有 5 个参数。 如果你在其他架构上使用 Linux,你可以检查 <asm/unistd.h> 中的 _syscall 宏,以查看你的硬件支持多少个参数,或者开发人员选择支持多少个参数。 可以使用这些 _syscall 宏代替 syscall(),但不建议这样做,因为这样的宏会扩展为一个完整的函数,该函数可能已经存在于库中。 因此,只有内核黑客才应该使用 _syscall 宏。 为了演示,这里是使用 _syscall 宏的 close() 示例。
#include <linux/unistd.h> _syscall1(int, close, int, filedescriptor);
_syscall1 宏会展开以显示 close() 函数。 因此我们有两次 close()——一次在 libc 中,一次在我们的程序中。 如果系统调用失败,syscall() 或 _syscall 宏的返回值是 -1,如果成功,则返回 0 或更大。 查看全局变量 errno 以了解系统调用失败的原因。
以下 BSD 和 SYS V 上可用的系统调用在 Linux 上不可用
audit(), auditon(), auditsvc(), fchroot(), getauid(), getdents(), getmsg(), mincore(), poll(), putmsg(), setaudit(), setauid().