Linux 系统调用
介绍
系统调用是程序向内核发出的服务请求,通常是只有内核才有权限执行的操作,例如进行 I/O。程序员通常不需要关心系统调用,因为 GNU C 库中有函数可以完成几乎所有系统调用的功能。这些函数通过自身调用系统调用来工作。例如,有一个系统调用可以改变文件的权限,但您不需要了解它,因为您可以直接使用 GNU C 库的 chmod 函数。
系统调用有时也被称为内核调用。
然而,有时您可能想要显式地调用一个系统调用,为此,GNU C 库提供了 syscall 函数。syscall 比像 chmod 这样的函数更难使用,也不太可移植,但比用汇编指令编写系统调用更容易,也更可移植。
syscall 最有用的时候是当您在使用一个特定于您的系统或者比您使用的 GNU C 库更新的系统调用时。syscall 是以一种完全通用的方式实现的;该函数不知道任何一个特定的系统调用做了什么,甚至不知道它是否有效。
这一节中对 syscall 的描述假设了 GNU C 库在各个平台上运行的系统调用的某种协议。这种协议没有被任何强有力的权威所定义,但我们也不会在这里描述它,因为任何编写 syscall 的人可能不会接受任何低于内核和 C 库源代码的东西作为它们之间的接口的规范。
函数定义
sycall 函数定义在 unistd.h
Function: long int syscall (long int sysno, …)
syscall 函数可以执行一个通用的系统调用。sysno 是系统调用的编号。每种系统调用都有一个对应的编号。所有可能的系统调用编号都定义在 sys/syscall.h 中。
剩余的参数是系统调用的参数,按顺序排列,它们的含义取决于系统调用的种类。每种系统调用有一个确定的参数个数,从零到五。如果您编写的参数多于系统调用需要的,那么右边多余的参数会被忽略。
返回值是系统调用的返回值,除非系统调用失败。在那种情况下,syscall 返回 -1 并设置 errno 为系统调用返回的错误码。注意,系统调用在成功时不会返回 -1。
如果您指定了一个无效的 sysno,syscall 返回 -1 并设置 errno 为 ENOSYS。
示例:
1 | #include <unistd.h> |
这段代码,等价于下面的代码:
1 | #include <sys/types.h> |