Das unmittelbare Problem ist, dass Sie die Datei vor dem Neustart nicht synchronisieren. Das aktuelle Problem ist, dass Sie den reboot
Syscall direkt aufrufen, ohne Rücksicht darauf, was sonst noch auf dem System passiert. Was Sie tun, ist dem Drücken der HW-Reset-Taste sehr ähnlich. Sie geben dem Kernel nur die Chance, ein wenig aufzuräumen, aber dann wird alles auf die harte Tour abgetötet. Dies ist eine todsichere Möglichkeit, Dateisysteme und Dateistrukturen zu beschädigen. Tun Sie das nicht!.
Stattdessen sollten Sie das Init-System bitten, einen ordnungsgemäßen Neustart durchzuführen. Der Aufruf des Systemaufrufs reboot
erfordert einen privilegierten Zugriff. Sie können also das init-System einfach neu starten. Auf den meisten Systemen gibt es einen Symlink /sbin/reboot
, der auf das Programm verweist, das einen vernünftigen Neustart initiiert, wenn es über diesen Symlink aufgerufen wird. Daher empfehle ich Ihnen, Ihre schmutzige reboot(RB_AUTOBOOT)
durch zu ersetzen (beachten Sie die doppelte Spezifikation von "/sbin/reboot"
in execlp - das ist wichtig).
pid_t reboot_pid;
if(0 == (reboot_pid = fork())) {
execlp("/sbin/reboot", "/sbin/reboot", NULL);
exit(1); /* never reached if execlp succeeds. */
}
if(-1 == reboot_pid) {
/* fork error... deal with it somehow */
}
int reboot_status;
waitpid(reboot_pid, &reboot_status, 0);
if(!WIFEXITED(reboot_status)) {
/* reboot process did not exit sanely... deal with it somehow */
}
if(0 != WIFEXITSTATUS(reboot_status)) {
/* reboot process exited with error;
* most likely the user lacks the required privileges */
}
else {
fputs("reboot call sucessfull -- system is about to shutdown.");
/* The init system is now shutting down the system. It will signals all
* programs to terminate by sending SIGTERM, followed by SIGKILL to
* programs that didn't terminate gracefully. */
}
es auf diese Weise das System tun kann ordnungsgemäß heruntergefahren, beenden Sie alle Programme in einem sauberen Art und Weise ausgeführt wird und alle Dateisysteme aushängen, bevor der Neustart tun, damit keeing Dateisystem und Datenintegrität.
Beachten Sie, dass wenn Sie erwarten, dass Ihr Programm keinen Root-Zugriff hat, dann müssen Sie einige Reifen springen; Auf Systemen mit Systemd können Sie eine Neustartanforderung per D-Bus senden. Aber außer dass es fehlschlägt, wenn der Benutzer, der den Befehl ausführt, keine Neustart-Rechte hat.
Flush (sync) die Datei selbst: http: //linux.die.net/man/2/fsync ... – ChristopheD
Ich stimme nicht zu, aber ich bin überrascht, dass Aufruf von fclose() ist nicht ausreichend . – larsks
@larks Siehe meine Antworten. Die man-Seite gibt dies explizit an. Es ist allerdings ein bisschen komisch. – pmr