直接的问题是,您在重新启动之前没有同步文件。实际的问题是,您reboot
直接调用系统调用,而不考虑系统上发生的其他事情。您所做的与简单地按下硬件重置按钮非常相似;你只是给内核做一点清理的机会,但随后一切都被艰难地杀死了。这是最终破坏文件系统和文件结构的绝对可靠方法。不要这样做!.
相反,您应该要求 init 系统执行正常重启。调用reboot
系统调用需要特权访问。因此,您也可以要求 init 系统重新启动。在大多数系统上,都有一个符号链接/sbin/reboot
指向程序,如果通过该符号链接调用该程序,该程序将启动正常重启。因此,我建议您将脏替换为(注意execlp 中reboot(RB_AUTOBOOT)
的双重规范——这很重要)。"/sbin/reboot"
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. */
}
这样做,系统可以正常关闭,终止以干净方式运行的所有程序并在重新启动之前卸载所有文件系统,从而保持文件系统和数据的完整性。
请注意,如果您希望您的程序没有 root 访问权限,那么您将不得不跳一些圈子;在带有 systemd 的系统上,您可以通过 D-Bus 发送重启请求。但除非它失败,如果执行该命令的用户没有重新启动权限。