我到处检查,所以我希望不会重复一个问题。
我想为我正在编写的一些 C 代码添加一个可移植的更新功能。该程序可能不在任何特定位置,我更愿意将其保留为单个二进制文件(无动态库加载)
然后更新完成后,我希望程序能够重新启动(不是循环,实际上是从硬盘重新加载)
有什么办法可以在 Linux 上的 C 中做到这一点?
如果您知道程序在磁盘上的保存位置,那么您可以exec()
程序:
char args[] = { "/opt/somewhere/bin/program", 0 };
execv(args[0], args);
fprintf(stderr, "Failed to reexecute %s\n", args[0]);
exit(1);
如果您不知道该程序在磁盘上的位置,请使用execvp()
$PATH 搜索它,或者找出。在 Linux 上,使用/proc
文件系统——/proc/self/exe
特别是;它是可执行文件的符号链接,因此您需要使用它readlink()
来获取值。注意:readlink()
不会终止它读取的字符串。
如果需要,您可以安排传递一个参数,该参数指示新进程在更新后正在重新启动;我提供的最简单的参数列表可以根据您的需要而复杂(可能是当前打开以供编辑的文件列表,或者任何其他适当的信息和选项)。
另外,不要忘记在重新执行之前进行清理——例如,干净地关闭所有打开的文件。请记住,打开的文件描述符由执行的进程继承(除非您将它们标记为exec
用FD_CLOEXEC
or关闭O_CLOEXEC
),但新进程不会知道它们的用途,除非您告诉它(在参数列表中)所以它不会无法使用它们。他们只会在没有任何帮助的情况下混乱这个过程。
是的,您需要调用正确的exec()
函数。可能会有一些复杂性,找到绝对路径名可能很麻烦。你需要:
main()
.argc
和(所有)argv[]
值main()
。由于调用exec()
会替换当前进程,因此您需要做的就是重新启动自己。您可能还需要注意关闭任何打开的文件,因为否则它们可能会“继承”回您自己,而这很少是您想要的。