Provided by: manpages-de-dev_2.5-1_all 

BEZEICHNUNG
setjmp, sigsetjmp, longjmp, siglongjmp - Nichtlokalen Sprungbefehl durchführen
ÜBERSICHT
#include <setjmp.h>
int setjmp(jmp_buf env);
int sigsetjmp(sigjmp_buf env, int savesigs);
void longjmp(jmp_buf env, int val);
void siglongjmp(sigjmp_buf env, int val);
Mit Glibc erforderliche Makros (siehe feature_test_macros(7)):
setjmp(): siehe ANMERKUNGEN.
sigsetjmp(): _POSIX_C_SOURCE
BESCHREIBUNG
Die auf dieser Seite beschriebenen Funktionen werden für »nichtlokale Gotos« verwandt: Übergabe der
Ausführung von einer Funktion zu einer vorbestimmten Stelle in einer anderen Funktion. Die Funktion
setjmp() etabliert dynamisch das Ziel, zu dem die Steuerung später übergeben wird und longjmp() führt den
Ausführungstransfer aus.
Die Funktion setjmp() speichert verschiedene Informationen über die aufrufende Umgebung (typischerweise
den Stack-Zeiger, den Anweisungszeiger, möglicherweise die Werte von anderen Registern und die
Signalmaske) im Puffer env für die spätere Verwendung durch longjmp(). In diesem Fall liefert setjmp() 0
zurück.
Die Funktion longjmp() verwendet die in env gespeicherten Informationen, um die Steuerung zu dem Punkt
zurückzuübergeben, an dem setjmp() aufgerufen worden war und den Stack auf seinem Zustand zum Zeitpunkt
des Aufrufs von setjmp() wiederherzustellen (»zurückzuspulen«). Zusätzlich und abhängig von der
Implementierung (siehe ANMERKUNGEN) können die Werte einiger anderer Register und der Prozesssignalmaske
auf den Wert zum Zeitpunkt des Aufrufs von setjmp() wiederhergestellt werden.
Nach einem erfolgreichen longjmp() fährt die Ausführung so fort, als ob setjmp() ein zweites Mal
zurückgekehrt wäre. Diese »Schummel«-Rückkehr kann von einem echten Aufruf von setjmp() unterschieden
werden, da die »Schummel«-Rückkehr den in val bereitgestellten Wert zurückliefert. Falls der
Programmierer fehlerhafterweise den Wert 0 in val weitergibt, wird die »Schummel«-Rückkehr stattdessen 1
zurückliefern.
sigsetjmp() und siglongjmp()
sigsetjmp() und siglongjmp() führen auch nichtlokale Gotos durch, stellen aber eine vorhersehbare
Behandlung der Prozesssignalmaske bereit.
Nur wenn das an sigsetjmp() übergebene Argument savesigs nicht Null ist, wird die aktuelle Signalmaske
des Prozesses in env gespeichert und wiederhergestellt, wenn später mit diesem env ein siglongjmp
durchgeführt wird.
RÜCKGABEWERT
setjmp() und sigsetjmp() geben 0 zurück, wenn sie direkt aufgerufen wurden; bei dem »nachgeahmten«
Zurückkehren, das nach longjmp() und siglongjmp() auftritt, wird der in val angegebene Nichtnull-Wert
zurückgegeben.
Die Funktionen longjmp() oder siglongjmp() kehren nicht zurück.
ATTRIBUTE
Siehe attributes(7) für eine Erläuterung der in diesem Abschnitt verwandten Ausdrücke.
┌─────────────────────────┬───────────────────────┬─────────┐
│ Schnittstelle │ Attribut │ Wert │
├─────────────────────────┼───────────────────────┼─────────┤
│ setjmp(), sigsetjmp() │ Multithread-Fähigkeit │ MT-Safe │
├─────────────────────────┼───────────────────────┼─────────┤
│ longjmp(), siglongjmp() │ Multithread-Fähigkeit │ MT-Safe │
└─────────────────────────┴───────────────────────┴─────────┘
KONFORM ZU
setjmp(), longjmp(): POSIX.1-2001, POSIX.1-2008, C89, C99.
sigsetjmp(), siglongjmp(): POSIX.1-2001, POSIX.1-2008.
ANMERKUNGEN
POSIX spezifiziert nicht, ob setjmp() die Signalmaske sichern wird (um sie später während longjmp()
wieder herzustellen). In System-V wird es dies nicht tun. In 4.3BSD wird es dies tun und dort gibt es
eine Funktion _setjmp(), die es nicht tut. Das Verhalten unter Linux hängt von der Glibc-Version und den
Einstellungen der Feature-Test-Makros ab. Unter Linux mit Glibc-Versionen vor 2.19 folgte setjmp()
standardmäßig dem Verhalten von System V, aber das BSD-Verhalten wird bereitgestellt, wenn das
_BSD_SOURCE-Feature-Test-Macro explizit definiert ist und weder _POSIX_SOURCE, _POSIX_C_SOURCE,
_XOPEN_SOURCE, _GNU_SOURCE noch _SVID_SOURCE definiert ist. Seit Glibc 2.19 stellt <setjmp.h> nur die
System-V-Version von setjmp() bereit. Programme, die die BSD-Semantik benötigen, sollten Aufrufe von
setjmp() durch Aufrufe von sigsetjmp(), bei denen das Argument savesigs ungleich numerisch Null ist,
ersetzen.
setjmp() und longjmp() können zum Umgang mit Fehlern innerhalb tiefverschachtelter Funktionsaufrufe
nützlich sein oder um einem Signal-Handler zu ermöglichen, die Steuerung an einen bestimmten Punkt in dem
Programm zu übergeben, statt zu dem Punkt zurückzukehren, in dem der Handler das Hauptprogramm
unterbrochen hat. In letzterem Falle verwenden Sie sigsetjmp() und siglongjmp(), falls Sie die
Signalmaske portabel speichern und wiederherstellen möchten. Lesen Sie auch die Diskussion zur
Programmlesbarkeit weiter unten.
Der Compiler kann Variablen in Register optimieren und longjmp() kann die Werte anderer Register
zusätzlich zum Stack- und Programmzeiger wiederherstellen. Daher ist der Wert von automatischen Variablen
nach einem Aufruf von longjmp() undefiniert, falls alle folgenden Kriterien zutreffen:
• sie sind für die Funktion, die den entsprechenden Aufruf setjmp() durchführte, lokal,
• ihre Werte sind zwischen Aufrufen von setjmp() und longjmp() geändert, und
• sie sind nicht als volatile deklariert.
Entsprechende Anmerkungen gelten für siglongjmp().
Nicht lokale GOTOs und Programmlesbarkeit
Auch wenn er missbraucht werden kann, hat der traditionelle »goto«-Ausdruck von C zumindest den Vorteil,
dass lexikalische Hinweise (der Goto-Ausdruck und die Zielmarkierung) dem Programmierer erlauben, leicht
den Ablauf zu verstehen. Nichtlokale Gotos stellen keine solchen Hinweise bereit: Mehrere Aufrufe von
setjmp() können die gleiche Variable jmp_buf einsetzen, so dass der Inhalt der Variablen sich über die
Lebensdauer des Programmes verändern kann. Konsequenterweise kann der Programmierer dazu gezwungen sein,
den Code detailliert zu lesen, um das dynamische Ziel eines bestimmten Aufrufs von longjmp() zu
ermitteln. (Um das Leben der Programmierer zu erleichtern, sollte jeder Aufruf von setjmp() eine
eineindeutige Variable jmp_buf einsetzen.)
Weitere Schwierigkeiten kommen hinzu, da die Aufrufe von setjmp() und longjmp() nicht zwingend im
gleichen Quellcodemodul sein müssen.
Zusammenfassend erschweren nicht lokale GOTOs das Verständnis und die Verwaltung von Programmen. Falls
möglich, sollte eine Alternative benutzt werden.
Warnungen
Falls die Funktion, die setjmp() aufruft, zurückkehrt, bevor longjmp() aufgerufen wird, ist das Verhalten
undefiniert. Irgendwelches subtiles oder nicht so subtiles Chaos entsteht bestimmt dadurch.
Falls ein longjmp()-Aufruf in einem Programm mit mehreren Threads einen env-Puffer einsetzt, der durch
einen Aufruf von setjmp() in einem anderen Thread initialisiert wurde, ist sein Verhalten nicht
definiert.
POSIX.1-2008 Technische Berichtigung 2 fügt longjmp() und siglongjmp() zur Liste der
asynchronsignalsicheren Funktionen hinzu. Der Standard empfiehlt jedoch den Gebrauch dieser Funktionen
aus Signal-Handlern zu vermeiden. Sie fährt damit fort, zu betonen, dass, falls diese Funktionen von
einem Signal-Handler aufgerufen werden, der einen Aufruf einer nicht asynchronsignalsicheren Funktion
unterbrochen hatte (oder etwas gleichbedeutendem, wie den Schritten, die exit(3) entsprechen, die über
eine Rückkehr vom initialen Aufruf zu main() auftreten), das Verhalten nicht definiert ist, falls das
Programm nachfolgend einen Aufruf einer nicht asynchronsignalsicheren Funktion durchführt. Der einzige
Weg, nicht definiertes Verhalten zu vermeiden, ist, eines des Nachfolgenden sicherzustellen:
* Nach langen Sprüngen vom Signal-Handler ruft das Programm keine asynchronsignalsicheren Funktionen auf
und kehrt nicht vom initialen Aufruf von main() zurück.
* Jedes Signal, dessen Handler einen langen Sprung durchführt, muss während jedes Aufrufs einer nicht
asynchronsignalsicheren Funktion blockiert werden und keine nicht asynchronsignalsicheren Funktionen
werden nach der Rückkehr vom initialen Aufruf von main() aufgerufen.
SIEHE AUCH
signal(7), signal-safety(7)
KOLOPHON
Diese Seite ist Teil der Veröffentlichung 4.15 des Projekts Linux-man-pages. Eine Beschreibung des
Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden
sich unter https://www.kernel.org/doc/man-pages/.
ÜBERSETZUNG
Die deutsche Übersetzung dieser Handbuchseite wurde von Patrick Rother <krd@gulu.net>, Chris Leick
<c.leick@vollbio.de>, Helge Kreutzmann <debian@helgefjell.de> und Dr. Tobias Quathamer <toddy@debian.org>
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
<debian-l10n-german@lists.debian.org>.
13. März 2017 SETJMP(3)