SYSCALLS - Linux手册页
Linux程序员手册 第2部分
更新日期: 2020-08-13
名称
syscalls-Linux系统调用
语法
Linux系统调用。
说明
系统调用是应用程序和Linux内核之间的基本接口。
System calls and library wrapper functions
通常不直接调用系统调用,而是通过glibc(或其他库)中的包装函数来调用。有关直接调用系统调用的详细信息,请参见intro(2)。通常,但并非总是如此,包装函数的名称与其调用的系统调用的名称相同。例如,glibc包含一个函数chdir(),该函数调用基础的" chdir"系统调用。
glibc包装器函数通常很薄,除了在调用系统调用之前将参数复制到正确的寄存器,然后在系统调用返回之后适当地设置errno之外,几乎没有做其他工作。 (这些与syscall(2)执行的步骤相同,可用于调用未提供包装函数的系统调用。)注:系统调用通过将负错误号返回给体系结构上的调用方来指示失败没有单独的错误寄存器/标志,如syscall(2)所述;发生这种情况时,包装器函数将返回的错误号取反(使其为正数),将其复制到errno,然后将-1返回给包装器的调用方。
但是,有时包装函数在调用系统调用之前会做一些额外的工作。例如,当今有(出于下面描述的原因)两个相关的系统调用,truncate(2)和truncate64(2),而glibc truncate()包装函数检查内核提供了哪些系统调用,并确定了哪些系统调用应该由内核提供。被雇用。
System call list
以下是Linux系统调用的列表。在列表中,"内核"列指示Linux 2.2中新的或自该内核版本以来出现的那些系统调用的内核版本。请注意以下几点:
- *
- 如果未指示内核版本,则系统调用出现在内核1.0或更早版本中。
- *
- 如果系统调用标记为" 1.2",则意味着系统调用可能出现在1.1.x内核版本中,并且首先出现在具有1.2的稳定内核中。 (1.2内核的开发是从内核1.0.6的一个分支通过1.1.x不稳定内核系列开始的。)
- *
- 如果系统调用标记为" 2.0",则意味着系统调用可能出现在1.3.x内核版本中,并且首先出现在带有2.0的稳定内核中。 (2.0内核的开发是通过1.3.x不稳定内核系列从1.2.x内核的一个分支(大约在1.2.10左右)开始的。)
- *
- 如果系统调用标记为" 2.2",则意味着该系统调用可能出现在2.1.x内核版本中,并且首先出现在带有2.2.0的稳定内核中。 (2.2内核的开发是通过2.1.x不稳定内核系列从2.0.21内核的分支开始的。)
- *
- 如果系统调用标记为" 2.4",则意味着系统调用可能出现在2.3.x内核版本中,并且首先出现在具有2.4.0的稳定内核中。 (通过2.3.x不稳定内核系列从内核2.2.8的一个分支启动了2.4内核的开发。)
- *
- 如果系统调用标记为" 2.6",则意味着该系统调用可能出现在2.5.x内核版本中,并且首先出现在带有2.6.0的稳定内核中。 (通过2.5.x不稳定内核系列从内核2.4.15的一个分支启动了内核2.6的开发。)
- *
- 从内核2.6.0开始,开发模型发生了变化,新的系统调用可能会出现在每个2.6.x版本中。在这种情况下,将显示出现系统调用的确切版本号。此约定在3.x内核系列中继续,此系列从2.6.39内核开始;以及从内核3.19开始的4.x内核系列;以及5.x内核系列,随后是内核4.20。
- *
- 在某些情况下,系统调用是从先前的稳定内核系列分支出来的,然后再添加到稳定内核系列中,然后回移植到较早的稳定内核系列中。例如,出现在2.6.x中的某些系统调用在2.4.15之后也被反向移植到2.4.x版本中。在这种情况下,将列出两个主要内核系列中出现系统调用的版本。
从内核4.19(或在某些情况下仅在较旧的内核上)可用的系统调用列表如下:
单元格不一致
在包括x86-32在内的许多平台上,套接字调用都通过socketcall(2)多路复用(通过glibc包装器函数),类似地,系统IP IPC调用通过ipc(2)多路复用。
尽管在系统调用表中为它们保留了插槽,但是以下系统调用未在标准内核中实现:afs_syscall(2),break(2),ftime(2),getpmsg(2),gtty(2),idle (2),lock(2),madvise1(2),mpx(2),phys(2),prof(2),profil(2),putpmsg(2),security(2),stty(2),tuxcall (2),ulimit(2)和vserver(2)(另请参见unimplemented(2))。但是,ftime(3),profil(3)和ulimit(3)作为库例程存在。自从umount(2)的内核2.1.116开始使用phys(2)的插槽; phys(2)将永远不会实现。 getpmsg(2)和putpmsg(2)调用适用于已打补丁以支持STREAMS的内核,并且可能永远不在标准内核中。
在Linux 2.6.13中有一个简短的set_zone_reclaim(2),在2.6.16中已删除;用户空间永远无法使用此系统调用。
备注
粗略地说,在/usr/include/asm/unistd.h中定义的编号为__NR_xxx的系统调用的代码可以在Linux内核源代码的sys_xxx()中找到。但是,有许多例外,主要是因为较旧的系统调用已被较新的系统调用所取代,并且对此进行了一些不系统的处理。在具有专有操作系统仿真的平台上,例如sparc,sparc64和alpha,存在许多其他系统调用;例如, mips64还包含完整的32位系统调用集。
随着时间的流逝,必须更改某些系统调用的接口。进行此类更改的原因之一是需要增加传递给系统调用的结构或标量值的大小。由于这些更改,某些体系结构(尤其是长期存在的32位体系结构,例如i386)现在具有执行相关任务的各种相关系统调用组(例如truncate(2)和truncate64(2)),但是它们在细节上有所不同例如其参数的大小。 (如前所述,应用程序通常不知道这一点:glibc包装器功能做了一些工作,以确保调用正确的系统调用,并为旧的二进制文件保留ABI兼容性。)存在多个版本的系统调用示例如下:下列:
- *
- 到目前为止,有三种不同版本的stat(2):sys_stat()(插槽__NR_stat),sys_newstat()(插槽__NR_stat)和sys_stat64()(插槽__NR_stat64),最后一个是最新的。 lstat(2)和fstat(2)也有类似的情况。
- *
- 同样,定义__NR_oldolduname,__NR_olduname和__NR_uname引用例程sys_olduname(),sys_uname()和sys_newuname()。
- *
- 在Linux 2.0中,出现了新版本的vm86(2),新旧内核例程分别命名为sys_vm86old()和sys_vm86()。
- *
- 在Linux 2.4中,出现了新版本的getrlimit(2),新旧内核例程分别命名为sys_old_getrlimit()(插槽__NR_getrlimit)和sys_getrlimit()(插槽NRNR_ugetrlimit)。
- *
- Linux 2.4将用户和组ID的大小从16位增加到了32位。为了支持此更改,添加了一系列系统调用(例如chown32(2),getuid32(2),getgroups32(2),setresuid32(2)),取代了不带后缀" 32"的同名早期调用。
- *
- Linux 2.4增加了对32位体系结构上的应用程序的支持,以访问大型文件(即,其大小和文件偏移量不能以32位表示)。为了支持此更改,处理此问题的系统调用需要替换文件偏移量和大小。因此,添加了以下系统调用:fcntl64(2),getdents64(2),stat64(2),statfs64(2),truncate64(2)及其与文件描述符或符号链接一起使用的类似物。这些系统调用将取代较旧的系统调用,这些较早的系统调用(在使用" stat"调用的情况下除外)具有相同的名称,但不带有" 64"后缀。
- 在只有64位文件访问权限和32位UID / GID(例如alpha,ia64,s390x,x86-64)的较新平台上,只有一个版本的UID / GID和文件访问系统调用。在存在* 64和* 32调用的平台(通常是32位平台)上,其他版本已过时。
- *
- rt_sig *调用已添加到内核2.2中,以支持添加实时信号(请参阅signal(7))。这些系统调用将取代不带" rt_"前缀的同名旧系统调用。
- *
- select(2)和mmap(2)系统调用使用五个或更多参数,这会导致过去设置i386的参数传递方式出现问题。因此,尽管其他体系结构具有对应于__NR_select和__NR_mmap的sys_select()和sys_mmap(),但在i386上却找到了old_select()和old_mmap()(使用指向参数块的指针的例程)代替。现在,传递五个参数不再是问题,并且有一个__NR__newselect直接对应于sys_select()和类似的__NR_mmap2。 s390x是唯一具有old_mmap()的64位体系结构。
Architecture-specific details: Alpha
- *
- getxgid(2)通过寄存器r0和r20返回一对GID和有效GID;提供它而不是getgid(2)和getegid(2)。
- *
- getxpid(2)通过寄存器r0和r20返回一对PID和父PID;提供它而不是getpid(2)和getppid(2)。
- *
- old_adjtimex(2)是adjtimex(2)的变体,它使用结构timeval32,以与OSF / 1兼容。
- *
- getxuid(2)通过寄存器r0和r20返回一对GID和有效GID;提供它而不是getuid(2)和geteuid(2)。
- *
- sethae(2)用于在低成本Alpha上配置主机地址扩展寄存器,以便访问超出前27位的地址空间。
出版信息
这个页面是Linux手册页项目5.08版的一部分。有关项目的说明、有关报告错误的信息以及此页面的最新版本,请访问https://www.kernel.org/doc/man-pages/。