Datei löschen bei Programm-Abbruch
-
Moin moin!
Mein Programm erzeugt mit FILE* fpdst = fopen("data.txt", "w") eine Datei und schreibt Daten rein, das Ganze kann ein paar Minütchen dauern.
Nun möchte ich die Datei löschen, wenn der Benutzer das Programm vorzeitig schließt, wenn die Datei also nicht fertig beschrieben ist.
Dafür habe ich per atexit(exit_func) eine Funktion registriert die das erledigen soll, indem remove("data.dat") aufgerufen wird.void exit_func ( void ) { if ( file_processing ) { fclose ( fpdst ); remove ( "data.txt" ); } }
Die nicht zu Ende geschriebene Datei "data.txt" ist aber nach Abbruch des Programms trotzdem noch auf der Festplatte,
remove ( "data.txt" ) wird also nicht erfolgreich ausgeführt.
Was tun?
-
Was sagen denn der return-Wert von remove und errno?
-
atexit wird beim Aufruf von exit aufgerufen. Das was du vermutlich möchtest ist auf das Schließen des Konsolenfensters reagieren. Das ist allerdings Betriebssystemabhängig. Für Windows gibt es irgendwelche Handler, um das abzufragen.
-
Die mit atexit registrierten Funktionen werden auch ohne explizites exit aufgerufen, also auch bei return aus main.
Probiere malperror("data.txt");
nach dem remove bzw. sogar zuvor nochmal nach dem fclose.
-
dfgdfg schrieb:
atexit wird beim Aufruf von exit aufgerufen. Das was du vermutlich möchtest ist auf das Schließen des Konsolenfensters reagieren. Das ist allerdings Betriebssystemabhängig. Für Windows gibt es irgendwelche Handler, um das abzufragen.
Wutz schrieb:
Die mit atexit registrierten Funktionen werden auch ohne explizites exit aufgerufen, also auch bei return aus main.
Probiere malperror("data.txt");
nach dem remove bzw. sogar zuvor nochmal nach dem fclose.
Das Schließen des Konsolenfensters unter Windows ruft exit und damit auch meine exit_func auf.
Das passiert irgendwo mitten in einer Funktion, die gerade meine Datei beschreibt(denn sonst würde diese Funktion am Ende das globale file_processing = 0 setzen) und die auch nicht mehr nach main zurückkehrt denn sonst würde am Ende von main, vor dem return 0 die Testausgabe fputs("good bye!", fopen("bye.txt", "w")); ausgeführt werden!DirkB schrieb:
Was sagen denn der return-Wert von remove und errno?
Der Tipp errno abzufragen, hat mich weitergebracht!
Die Funktion remove hatte -1 geliefert und
ich habe in der exit_func strerror(errno) in eine Datei umgeleitet, weil
das Konsolenfenter beim Beenden ja nicht mehr sichtbar ist.
Durch das "Permission denied == strerror(errno)" hatte ich eine vergessene
Dateisperre entdeckt.Die Datei entsperre ich jetzt in der exit_func
und alles läuft wie es soll!
Nochmal danke @DirkB für den Tipp!
Und natürlich auch an Wutz, der dieses mal etwas zu spät kam :p
weil ich das Problem um 21:33:21 schon gelöst hatte, aber jetzt erst dazu komme, die Antwort zu schreiben.
-
Um auf das eigentliche Titelthema zurückzukommen:
atexit-Funktionen werden nur beim (normalen) Programmende durchlaufen, beim Programmabbruch (abort,assert) muss man einen Signalhandler für SIGABRT installieren wenn man standardkonform bleiben will und nicht irgendwelche Compilerfeatures benutzen will.
-
Unter Windows wird die von atexit registrierte Funktion aufgerufen, wenn ich per Mausklick das Konsolenfenster schließe.
Die Standard-Signale werden nicht gesendet, außer ich drücke Strg+C, dann wird SIGINT gesendet.
Irgendwann werde ich das Programm evtl. auch unter Linux lauffähig machen wollen,
dann muss ich vermutlich auf SIGTERM reagieren wenn das Konsolenfenster geschlossen wird oder so...aber bis dahin vergehen noch ein paar Tage.Für Windows bedeutet ein Schließen des Konsolenfensters per Mausklick offensichtlich ein normales Programmende,
auch wenn das Programm noch läuft und Daten schreibt.
Von der Sicht meines Programmes aus ist das ein Programmabbruch,
aber das ist Windows egal, so sind se die Nasen