2013-07-18 17 views
5

Die Manpage atexit(3) sagt der folgende:Kann der Exit-Code in einer mit atexit() registrierten Funktion geändert werden?

POSIX.1-2001 sagt, dass das Ergebnis von exit(3) mehr als einmal aufrufen (das heißt, ruft exit(3) innerhalb einer Funktion mit atexit() registriert) ist nicht definiert. Auf einigen Systemen (aber nicht unter Linux) kann dies zu einer unendlichen Rekursion führen. portable Programme sollten exit(3) nicht in einer Funktion aufrufen, die unter atexit() registriert ist.

Ich bin jedoch daran interessiert, den Exit-Code in einem Finalizer für mein Programm zu ändern. Die einzige Möglichkeit, dies zu erreichen, besteht darin, innerhalb meiner Finalisierungsfunktion exit() aufzurufen, aber die man-Seite warnt ausdrücklich davor.

Gibt es eine praktische Gefahr, dies zu vermeiden? Gibt es Implementierungen, bei denen dieser Ansatz Probleme verursachen könnte? Noch besser, gibt es eine andere Möglichkeit, dies zu tun?

Antwort

3

Sie können stattdessen _exit() anrufen.

Im Notes-Abschnitt der Manpage:

Die Funktion _exit() ist wie exit(), aber ruft keine Funktionen registriert mit atexit() oder on_exit().

Dies sollte das "rekursive" Problem vermeiden, über das in der POSIX-Spezifikation gewarnt wird. Wenn Sie irgendwie in der Lage zu garantieren, dass Ihr „Exit-Code zu ändern“ exit-Handler zuletzt ausgeführt, sollten diese perfekt funktionieren, Modulo die Einsprüche auch im Anhang aufgeführt:

Ob Standard-I/O-Puffer spült und vorübergehend entfernt Dateien, die mit tmpfile(3) erstellt wurden, sind implementierungsabhängig. Auf der anderen Seite schließt _exit() offene Dateideskriptoren, und dies kann zu einer unbekannten Verzögerung führen, die darauf wartet, dass die ausstehende Ausgabe beendet wird. Wenn die Verzögerung unerwünscht ist, kann es nützlich sein, Funktionen wie tcflush(3) vor dem Aufruf von _exit() aufzurufen. Ob eine ausstehende E/A abgebrochen wird und welche ausstehende E/A nach _exit() abgebrochen werden kann, hängt von der Implementierung ab.