程序在更新时重启self

时间:2012-12-18 15:58:56

标签: c linux restart

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

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

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

有没有办法在Linux上的C中执行此操作?

2 个答案:

答案 0 :(得分: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_CLOEXEC标记它们在O_CLOEXEC上的封闭,但新进程将不知道它们是什么除非你告诉它(在参数列表中)所以它将无法使用它们。他们只会在没有帮助的情况下弄乱这个过程。

答案 1 :(得分:2)

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

  • 将当前目录存储在main()
  • 存储来自argc的{​​{1}}和(所有)argv[]值。

由于调用main()取代了当前进程,因此您需要完成所有操作才能重新启动。您可能还需要注意关闭所有打开的文件,因为它们可能会被“继承”回自己,这很少是你想要的。