6

我到处检查,所以我希望不会重复一个问题。

我想为我正在编写的一些 C 代码添加一个可移植的更新功能。该程序可能不在任何特定位置,我更愿意将其保留为单个二进制文件(无动态库加载)

然后更新完成后,我希望程序能够重新启动(不是循环,实际上是从硬盘重新加载)

有什么办法可以在 Linux 上的 C 中做到这一点?

4

2 回答 2

10

如果您知道程序在磁盘上的保存位置,那么您可以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()不会终止它读取的字符串。

如果需要,您可以安排传递一个参数,该参数指示新进程在更新后正在重新启动;我提供的最简单的参数列表可以根据您的需要而复杂(可能是当前打开以供编辑的文件列表,或者任何其他适当的信息和选项)。

另外,不要忘记在重新执行之前进行清理——例如,干净地关闭所有打开的文件。请记住,打开的文件描述符由执行的进程继承(除非您将它们标记为execFD_CLOEXECor关闭O_CLOEXEC),但新进程不会知道它们的用途,除非您告诉它(在参数列表中)所以它不会无法使用它们。他们只会在没有任何帮助的情况下混乱这个过程。

于 2012-12-18T16:03:30.697 回答
2

是的,您需要调用正确的exec()函数。可能会有一些复杂性,找到绝对路径名可能很麻烦。你需要:

  • 将当前目录存储在main().
  • 存储来自 的argc和(所有)argv[]main()

由于调用exec()会替换当前进程,因此您需要做的就是重新启动自己。您可能还需要注意关闭任何打开的文件,因为否则它们可能会“继承”回您自己,而这很少是您想要的。

于 2012-12-18T16:02:54.113 回答