2010-01-11 3 views
4

J'ai lu dans une page de manuel que lorsque exit() est appelé, tous les flux sont vidés et fermés automatiquement. Au début, j'étais sceptique quant à la façon dont cela a été fait et si c'est vraiment fiable, mais vu que je ne peux pas en savoir plus, je vais accepter que cela fonctionne - nous verrons si quelque chose explose. Quoi qu'il en soit, si ce comportement de fermeture de flux est présent dans exit(), un tel comportement est-il également présent dans le gestionnaire par défaut pour SIGINT (le signal d'interruption est généralement déclenché avec Ctrl + C)? Ou, serait-il nécessaire de faire quelque chose comme ceci:Les flux ouverts sont-ils automatiquement vidés et fermés sur SIGINT en C?

#include <signal.h> 
#include <stdlib.h> 

void onInterrupt(int dummy) { exit(0); } 

int main() { 
    signal(SIGINT, onInterrupt); 
    FILE *file = fopen("file", "a"); 
    for (;;) { fprintf(file, "bleh"); } } 

pour obtenir file à fermer correctement? Ou les lignes signal(SIG... et void onInterrupt(... peuvent-elles être omises en toute sécurité?

Veuillez limiter les réponses à C, C99 et POSIX car je n'utilise pas GNU libc. Merci.

+1

C'est définitivement fermé. Tous les descripteurs de fichiers sont libérés à la fin du processus. Je ne suis pas sûr qu'ils soient rouges. –

Répondre

7

La spécification C99 7.19.3 a une garantie plus faible:

5 Si la fonction principale retourne à l'appelant d'origine, ou si la fonction de sortie est appelée, tous les fichiers ouverts sont fermés (donc toutes les sorties les flux sont vidés) avant la fin du programme. Les autres chemins vers la fin du programme, tels que l'appel de la fonction d'abandon, ne doivent pas nécessairement fermer tous les fichiers correctement.

4 Un fichier peut être dissocié d'un flux de contrôle en fermant le fichier. Les flux de sortie sont vidés (tout contenu de tampon non écrit est transmis à l'environnement hôte) avant que le flux ne soit dissocié du fichier.

Donc en C99, s'il est fermé, il est vidé.

Le POSIX exit function a plus de détails, en particulier que si _exit ferme les flux est défini par l'implémentation.

6

Vous devrez gérer le signal si vous voulez que vos tampons soient vidés. Sinon, le processus sera terminé et les descripteurs de fichier seront fermés sans vidage des tampons stdio.

+1

Ceci est correct. Par défaut, un SIGINT met fin au processus * abnornally *. Les processus ainsi terminés n'appellent pas exit() et n'ont donc pas de tampons vidés. –

+0

Comment le savez-vous? –

+1

Les tampons de vidage provenant d'un gestionnaire de signal invoquent un comportement indéfini dans presque tous les cas. La seule façon de ne pas le faire est si vous pouvez vous assurer qu'aucune fonction async-signal-safe ne peut être exécutée au moment où le signal se produit. –

Questions connexes