我正在尝试编写一个可以查找网址的C程序,并且可以使用它的新版本,它可以自行更新。
我尝试过的方法:
forkout一个新的进程来下载新的二进制文件说BINARY.tmp,我用来代码的代码是:
int
forkout_cmd(char *cmdstr) {
pid_t pid;
char *cmd[4];
cmd[0] = "/bin/bash";
cmd[1] = "-c";
cmd[2] = cmdstr;
cmd[3] = NULL;
pid = vfork();
if( pid == -1 ) {
logmsg("Forking for upgradation failed.");
return -1;
}else if( pid == 0 ){
/* we are in child process */
execvp(cmd[0], cmd);
logmsg("execl failed while executing upgradation job.");
}else{
/* need not to wait for the child to complete. */
wait(NULL);
}
return 0;
}
新进程尝试覆盖原始BINARY
例如,您可以考虑分叉的例程:forkout_cmd("wget -O BINARY.tmp https://someurl.com/BINARY_LATEST; /bin/mv -f BINARY.tmp BINARY");
但是,覆盖失败,因为原始二进制文件仍处于执行状态,因此在磁盘上繁忙,有人可以在此提供一些建议来解决这个问题。
提前致谢。
答案 0 :(得分:7)
将当前运行的二进制文件重命名为其他内容,编写新的二进制文件,运行它,然后再删除重命名的二进制文件。
答案 1 :(得分:5)
我会将binary.tmp
保存到与可执行文件相同的目录中,验证其校验和/签名(无论100%确定没有发生错误),然后atomically rename将其作为可执行文件的名称
在Linux下,这可以在程序运行时完成,没有任何问题(您只是更改链接,底层文件在映射到它时仍然存在,直到程序关闭或重新启动)。 / p>
在任何情况下,我都不会重命名原始文件,甚至不会覆盖它。这是不安全的,没有必要。在触摸原始文件之前,您可以执行所有可能在临时文件上失败的“不安全”操作。如果在原子重命名中出现任何问题,您仍然可以使用原始文件。
然后提示用户重新启动程序(如果是交互式的)并完成。