如何编写自我替换/更新二进制文件
How to write a a self replacing/updating binary?
我正在尝试编写一个C程序,该程序可以查找url,并且如果新版本可用,它应该能够自行更新。
我尝试过的方法:
-
分叉一个新进程来下载新的二进制文件,比如 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; }
-
新进程尝试覆盖原始二进制
例如,您可以考虑 forks out 可能正在执行的例程:
forkout_cmd("wget -O BINARY.tmp https://someurl.com/BINARY_LATEST; /bin/mv -f BINARY.tmp BINARY");
但是,由于原始二进制文件仍在执行中,因此在磁盘上很忙,因此覆盖失败,有人可以在这里为我提供一些建议来克服这个问题。
提前谢谢。
将
当前运行的二进制重命名为其他名称,编写新的二进制文件,运行它,然后稍后删除重命名的二进制文件。
我会binary.tmp
保存到与可执行文件相同的目录中,验证其校验和/签名(无论需要什么才能 100% 确定没有发生错误),然后原子地将其重命名为可执行文件的名称。
在 Linux 下,这可以在程序运行时完成,没有任何问题(您只是更改链接,底层文件在打开映射到它的映射时仍然存在,直到程序关闭或重新启动)。
我在任何情况下都不会重命名原始文件,甚至不会覆盖它。这是不安全的,也是不必要的。您可以在接触原始文件之前对临时文件执行所有可能失败的"不安全"操作。如果在原子重命名中出现任何问题,您仍然拥有工作原件。
然后提示用户重新启动程序(如果是交互式)并完成。
相关文章:
- 正在读取二进制文件(is_open)
- 在C++中将类(带有Vector成员)保存为二进制文件
- 如何从二进制文件中读取字符串
- 保存/加载大量短数组到二进制文件
- 从二进制文件中读取整数数组
- Android 在编译二进制文件时重建静态库
- 在 C++ 中将双精度变量写入二进制文件
- clang 的 libFuzzer 可以在同一二进制文件中测试超过 1 个 API 吗?
- C++:实际上不是从二进制文件中读取
- 如何从二进制文件中的给定符号中获取调用程序图
- 无法正确编写和更新二进制文件
- 从二进制文件C++更新数据
- 如何编写自我替换/更新二进制文件
- 在运行时动态更新二进制文件(可执行文件)而不停止的任何类型的方法
- 如何在二进制文件(.net或非托管文件)中注入/更新Version和其他详细信息
- 简单的高分更新使用二进制文件
- 用c++更新二进制文件中的记录
- 更新二进制文件中的学生记录,同时删除以前的数据
- 二进制文件在C++中更新
- 需要帮助调试简单的更新二进制文件的功能