syscalls - Linux-Systemaufrufe
ÜBERSICHT
Linux-Systemaufrufe.
Der Systemaufruf ist eine fundamentale Schnittstelle zwischen
Anwendungen und dem Linux-Kernel.
Systemaufrufe werden im Allgemeinen nicht direkt aufgerufen,
sondern mittels Wrapper-Funktionen in Glibc (oder möglicherweise
einer anderen Bibliothek). Zu Details des direkten Aufrufs eines
Systemaufrufs siehe intro(2). Oft, aber nicht immer, ist der Name der
Wrapper-Funktion identisch zu dem Namen des Systemaufrufs, den sie aufruft.
Beispielsweise enthält Glibc eine Funktion chdir(), die den
zugrundeliegenden Systemaufruf »chdir« aufruft.
Oft ist die Glibc-Wrapper-Funktion recht dünn und sie macht
kaum mehr, als die Argumente in die richtigen Register zu kopieren, bevor
sie den Systemaufruf aufruft, und anschließend errno
entsprechend zu setzen, nachdem der Systemaufruf zurückkehrte. (Dies
sind die gleichen Schritte, die auch syscall(2) durchführt,
welches dazu verwandt werden kann, Systemaufrufe aufzurufen, für die
keine Wrapper-Funktion bereitgestellt wird.) Hinweis: Systemaufrufe zeigen
einen Fehlschlag an, indem sie eine negative Fehlernummer an den Aufrufenden
auf Architekturen zurückliefern, die kein getrenntes
Fehlerregister/-schalter bereitstellen. Darauf wird in syscall(2)
hingewiesen. Wenn dies passiert negiert die Wrapper-Funktion die
zurückgelieferte Fehlernummer (damit sie positiv wird), kopiert sie
nach errno und liefert -1 an den Aufrufenden des Wrappers
zurück.
Manchmal erledigt die Wrapper-Funktion vor dem Aufruf des
Systemaufrufs zusätzliche Aufgaben. Beispielsweise gibt es heutzutage
(aus weiter unten beschriebenen Gründen) zwei zusammenhängende
Systemaufrufe truncate(2) und truncate64(2) und die
Glibc-Wrapper-Funktion truncate() prüft, welche dieser
Systemaufrufe vom Kernel bereitgestellt wird und bestimmt, welcher
eingesetzt werden soll.
Nachfolgend ist eine Liste der Linux-Systemaufrufe. In der Liste
zeigt die Spalte Kernel die Kernelversion für solche
Systemaufrufe an, die in Linux 2.2 neu waren oder seitdem in dieser
Kernelversion erschienen sind. Beachten Sie die folgenden Punkte:
- •
- Wo keine Kernelversion angezeigt ist, erschien der Systemaufruf in Linux
1.0 oder früher.
- •
- Wo ein Systemaufruf mit »1.2« markiert ist, bedeutet dies,
dass der Systemaufruf wahrscheinlich in einer Linux 1.1.x-Kernelversion
und erstmalig in einem stabilen Kernel mit 1.2 erschien. (Die Entwicklung
der Linux 1.2er-Kernel erfolgte von einem Zweig von Linux 1.0.6
über die instabile Linux-1.1.x-Kernelserie.)
- •
- Wo ein Systemaufruf mit »2.0« markiert ist, bedeutet dies,
dass der Systemaufruf wahrscheinlich in einer Linux 1.3.x-Kernelversion
und erstmalig in einem stabilen Kernel mit Linux 2.0 erschien. (Die
Entwicklung der Linux 2.0er-Kernel erfolgte von einem Zweig von Linux
1.2.x, irgendwo rund um Linux 1.2.10, über die instabile
Linux-1.3.x-Kernelserie.)
- •
- Wo ein Systemaufruf mit »2.2« markiert ist, bedeutet dies,
dass der Systemaufruf wahrscheinlich in einer Linux 2.1.x-Kernelversion
und erstmalig in einem stabilen Kernel mit Linux 2.2.0 erschien. (Die
Entwicklung der Linux 2.2er-Kernel erfolgte von einem Zweig von Linux
2.0.21 über die instabile Linux-2.1.x-Kernelserie.)
- •
- Wo ein Systemaufruf mit »2.4« markiert ist, bedeutet dies,
dass der Systemaufruf wahrscheinlich in einer Linux 2.3.x-Kernelversion
und erstmalig in einem stabilen Kernel mit Linux 2.4.0 erschien. (Die
Entwicklung der Linux 2.4er-Kernel erfolgte von einem Zweig von Linux
2.2.8 über die instabile Linux-2.3.x-Kernelserie.)
- •
- Wo ein Systemaufruf mit »2.6« markiert ist, bedeutet dies,
dass der Systemaufruf wahrscheinlich in einer Linux 2.5.x-Kernelversion
und erstmalig in einem stabilen Kernel mit Linux 2.6.0 erschien. (Die
Entwicklung der Linux 2.6er-Kernel erfolgte von einem Zweig des Kernels
2.4.15 über die instabile 2.5.x-Kernelserie.)
- •
- Beginnend mit Linux 2.6.0 wurde das Entwicklungsmodell geändert und
neue Systemaufrufe können in jeder Linux-2.6.x-er
Veröffentlichung erscheinen. In diesem Fall wird die genaue
Versionsnummer, bei der der Systemaufruf erschien, angezeigt. Diese
Konvention gilt auch für die Linux 3.x-er-Kernelserie, die auf
Linux 2.6.39 folgte und die Linux 4.x-er-Kernelserie, die auf Linux 3.19
folgte und die Linux 5.x-er-Kernelserie, die auf Linux 4.20 folgte; und
die Linux 6.x-Kernelserie, die auf Linux 5.19 folgte.
- •
- In einigen Fällen wurde ein Systemaufruf zu einer stabilen
Kernelserie hinzugefügt, nachdem sie von der vorherigen stabilen
Kernelversion abgeleitet wurde, und dieser wurde dann in vorherige stabile
Kernelserie zurückportiert. Beispielsweise wurden einige
Systemaufrufe, die in Linux 2.6.x erschienen, auch in eine Linux
2.4.x-Veröffentlichung nach Linux 2.4.15 rückportiert. Wenn
dies der Fall ist, werden die Versionen, in denen der Systemaufruf in
beiden Haupt-Kernelserien erschien, aufgelistet.
Die Liste der Systemaufrufe, die in Linux 5.14 verfügbar
sind (oder in einigen wenigen Fällen nur in älteren Kerneln)
ist wie folgt:
Auf vielen Plattformen, einschließlich X86-32, werden
Socket-Aufrufe (mittels der Glibc-Wrapper-Funktionen) über
socketcall(2) im Multiplex-Verfahren behandelt und ebenso werden
System-V-IPC-Aufrufe mittels ipc(2) im Multiplex-Verfahren
behandelt.
Obwohl für sie in der Systemaufruftabelle Plätze
reserviert sind, sind die folgenden Systemaufrufe im Standard-Kernel nicht
implementiert: 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) und vserver(2) (siehe auch
unimplemented(2)). Allerdings existieren ftime(3),
profil(3) und ulimit(3) als Bibliotheksroutinen. Der Platz
für phys(2) wird seit Linux 2.1.116 für
umount(2) verwandt; phys(2) wird niemals implementiert. Die
Aufrufe getpmsg(2) und putpmsg(2) sind für Kernel, die
auf die Unterstützung von Streams angepasst wurden, reserviert und
könnten niemals im Standard-Kernel auftauchen.
Für einen kurzen Zeitraum gab es
set_zone_reclaim(2), hinzugefügt in Linux 2.6.13 und entfernt
in Linux 2.6.16. Dieser Systemaufruf stand dem Anwendungsraum niemals zur
Verfügung.
Grob gesagt kann der Code, der zu dem Systemaufruf mit der in
/usr/include/asm/unistd.h definierten Nummer __NR_xxx gehört
in den Linux-Kernelquellen in der Routine sys_xxx() gefunden werden.
Allerdings gibt es viele Ausnahmen, da hauptsächlich ältere
Systemaufrufe durch neuere ersetzt wurden und dabei nicht immer systematisch
vorgegangen wurde. Auf Plattformen mit proprietären
Betriebssystem-Emulationen, wie Sparc, Sparc64 und Alpha, gibt es viele
zusätzliche Systemaufrufe; Mips64 enthält auch einen
kompletten Satz an 32-bit-Systemaufrufen.
Im Laufe der Zeit wurden Änderungen an einigen
Schnittstellen der Systemaufrufe notwendig. Ein Grund für solche
Änderungen war die Notwendigkeit, die Größe von
Strukturen oder skalaren Werten, die an den Systemaufruf übergeben
werden, zu erhöhen. Aufgrund dieser Änderungen haben jetzt
bestimmte Architekturen (insbesondere die langexistierenden
32-bit-Architekturen wie I386) verschiedene Gruppen von
zusammengehörigen Systemaufrufen (z.B. truncate(2) und
truncate64(2)), die ähnliche Aufgaben erledigen, aber sich in
Details wie der Größe ihrer Argumente unterscheiden. (Wie
weiter oben angemerkt, bekommen das Anwendungen im Allgemeinen nicht mit:
Die Glibc-Wrapperfunktion haben Vorkehrungen um sicherzustellen, dass der
richtige Systemaufruf aufgerufen wird und dass die ABI-Kompatibilität
für ältere Programme gewährt wird). Folgende
Systemaufrufe sind Beispiele, die in verschiedenen Versionen existieren:
- •
- Es gibt jetzt drei verschiedene Versionen von stat(2):
sys_stat() (Platz __NR_oldstat), sys_newstat() (Platz
__NR_stat) und sys_stat64() (Platz __NR_stat64),
wobei letzterer der neuste ist. Eine ähnliche Geschichte existiert
für lstat(2) und fstat(2).
- •
- Ähnlich beziehen sich die Definitionen __NR_oldolduname,
__NR_olduname und __NR_uname auf die Routinen
sys_olduname(), sys_uname() und sys_newuname().
- •
- In Linux 2.0 erschien eine neue Version von vm86(2), wobei die alte
und die neue Kernelroutine als sys_vm86old() und sys_vm86()
benannt wurden.
- •
- In Linux 2.4 erschien eine neue Version von getrlimit(2) , wobei
die alte und die neue Kernelroutine als sys_old_getrlimit() (Platz
__NR_getrlimit) und sys_getrlimit() (Platz
__NR_ugetrlimit) benannt wurden.
- •
- Linux 2.4 erhöhte die Größe der Benutzer- und
Gruppenkennungen von 16 auf 32 bit. Um diese Änderung zu
unterstützen, wurden eine Reihe von Systemaufrufen
hinzugefügt (z.B. chown32(2), getuid32(2),
getgroups32(2), setresuid32(2)), die ältere Aufrufe
mit dem gleichen Namen ohne die Endung »32« ersetzen.
- •
- Linux 2.4 fügte Unterstützungen zum Zugriff auf große
Dateien (d.h. Dateien, deren Größe und Dateiversatz nicht in
32 bit dargestellt werden kann) für Anwendungen auf
32-bit-Architekturen hinzu. Um diese Änderung zu
unterstützen, wurden für Systemaufrufe, die mit
Dateiversätzen und -größen umgehen, Ersetzungen
notwendig. Daher wurden die folgenden Systemaufrufe hinzugefügt:
fcntl64(2), getdents64(2), stat64(2),
statfs64(2), truncate64(2) und ihre Entsprechungen, die mit
Dateideskriptoren und symbolischen Links arbeiten. Diese Systemaufrufe
ersetzen die älteren Systemaufrufe, die bis auf den Fall der
»stat«-Systemaufrufe die gleichen Namen ohne die Endung
»64« haben.
- Auf neueren Plattformen, die nur über 64-bit-Zugriff und 32-bit
UIDs/GIDs verfügen (z.B. Alpha, Ia64, S390x, X86-64) gibt es nur
eine einzige Version der UID/GID- und Dateizugriffs-Systemaufrufe. Auf
Plattformen (typischerweise 32-bit-Plattformen), bei denen die *64- und
*32-Aufrufe existieren, sind die anderen Versionen veraltet.
- •
- Die Aufrufe rt_sig* wurden in Linux 2.2 hinzugefügt, um die
Hinzufügung von Echtzeitsignalen (siehe signal(7)) zu
unterstützen. Diese Systemaufrufe ersetzen die älteren
Systemaufrufe mit dem gleichen Namen ohne den Präfix
»rt_«.
- •
- Die Systemaufrufe select(2) und mmap(2) verwenden
fünf oder mehr Argumente, was zu Problemen mit der Art, wie die
Argumentenübergabe auf I386 eingerichtet war, führte.
Während andere Architekturen über sys_select() und
sys_mmap() entsprechend zu __NR_select und __NR_mmap
verfügen, kann auf I386 stattdessen old_select() und
old_mmap() (Routinen, die einen Zeiger auf einen Argumentenblock
verwenden) gefunden werden. Heutzutage ist die Übergabe von
fünf oder mehr Argumenten kein Problem mehr und es gibt ein
__NR__newselect, das direkt sys_select() entspricht und
ähnlich __NR_mmap2. S390x ist die einzige
64-bit-Architektur, die über old_mmap() verfügt.
- getxgid(2)
- Liefert ein Paar an GID- und effektiver GID mittels der Register r0
und r20 zurück; er wird anstelle von getgid(2) und
getegid(2) bereitgestellt.
- getxpid(2)
- Liefert ein Paar an PID und Eltern-PID mittels der Register r0 und
r20 zurück; er wird anstelle von getpid(2) und
getppid(2) bereitgestellt.
- old_adjtimex(2)
- Ist eine Variante von adjtimex(2), die zur Kompatibilität
mit OSF/1 struct timeval32 verwendet.
- getxuid(2)
- Liefert ein Paar an GID und effektiver GID mittels der Register r0
und r20 zurück; er wird anstelle von getuid(2) und
geteuid(2) bereitgestellt.
- sethae(2)
- Wird für die Konfiguration der Rechneradressen-Erweiterungsregister
in günstigen Alphas verwandt, damit auf den Adressraum jenseits der
ersten 27 bit zugegriffen werden kann.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von
Helge Kreutzmann <debian@helgefjell.de> erstellt.
Diese Übersetzung ist Freie Dokumentation; lesen Sie die
GNU General
Public License Version 3 oder neuer bezüglich der
Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.
Wenn Sie Fehler in der Übersetzung dieser Handbuchseite
finden, schicken Sie bitte eine E-Mail an die Mailingliste der
Übersetzer:
debian-l10n-german@lists.debian.org.