Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编写自替换/更新二进制文件?_C++_C_Linux - Fatal编程技术网

C++ 如何编写自替换/更新二进制文件?

C++ 如何编写自替换/更新二进制文件?,c++,c,linux,C++,C,Linux,我试图写一个C程序,它可以查找一个网址,如果有新版本的网址可用,它应该能够自我更新 我尝试过的方法是: Forkout下载新二进制文件的新过程,比如binary.tmp,我用于Forkout的代码是: 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 = v

我试图写一个C程序,它可以查找一个网址,如果有新版本的网址可用,它应该能够自我更新

我尝试过的方法是:

  • Forkout下载新二进制文件的新过程,比如binary.tmp,我用于Forkout的代码是:

    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;
    }
    
  • 新进程尝试覆盖原始二进制文件

    例如,你可以考虑分叉的程序可能是:

    forkout_cmd("wget -O BINARY.tmp https://someurl.com/BINARY_LATEST; /bin/mv -f BINARY.tmp BINARY");
    
  • 但是,由于原始二进制文件仍在执行中,因此在磁盘上很忙,所以重写失败。有人能给我一些建议来克服这个问题吗


    提前感谢。

    将当前正在运行的二进制文件重命名为其他文件,编写新的二进制文件,运行它,然后稍后删除重命名的二进制文件。

    我会将
    binary.tmp
    保存到与可执行文件相同的目录中,验证其校验和/签名(无论采取何种措施,都要100%确保未发生错误),然后将其转换为可执行文件的名称

    在Linux下,这可以在程序运行时完成,没有任何问题(您只需更改链接,在打开到它的映射时,基础文件会一直存在,直到程序关闭或重新启动)

    在任何情况下,我都不会重命名原始文件,甚至覆盖它。这是不安全的,也没有必要。在接触原始文件之前,可以对临时文件执行所有可能失败的“不安全”操作。如果原子重命名中出现任何错误,您仍然可以使用原始版本


    然后提示用户重新启动程序(如果是交互式的)并完成。

    C程序可以删除自身吗?@akm:在Linux上,任何二进制文件都可以删除自身,只要它有足够的权限。@akm:在Linux下,可以(至少是某种程度的)。它不能真正删除二进制文件,但它可以替换链接并孤立实际文件(在进程退出后有效地将其删除)。我这样做的方式是用更新的二进制文件覆盖当前二进制文件,并向用户显示一条消息,如:“程序已更新,重新启动以使更改生效”。对于GUI应用程序来说很有意义。当然,对于控制台应用程序来说,情况并非如此。新应用程序可以删除旧应用程序(在Windows上,运行时不能删除旧应用程序)。我不确定这是一个好主意。将更新留给包经理负责。。。