c++ - 在执行过程中替换可执行文件时如何处理 "/proc/self/exe"的 readlink()?

标签 c++ linux exec fork self-reference

在我的 C++ 应用程序中,我的应用程序在 fork()ed 子进程中执行 execv() 以使用相同的可执行文件来处理新子进程中的某些工作具有不同参数的进程,这些参数通过管道与父进程通信。为了获得自己的路径名,我在 Linux 端口上执行以下代码(我在 Macintosh 上有不同的代码):

  const size_t bufSize = PATH_MAX + 1;
  char dirNameBuffer[bufSize];
  // Read the symbolic link '/proc/self/exe'.
  const char *linkName = "/proc/self/exe";
  const int ret = int(readlink(linkName, dirNameBuffer, bufSize - 1));

但是,如果在可执行文件运行时,我将可执行文件替换为磁盘上二进制文件的更新版本,则 readlink() 字符串结果为:"/usr/local/bin/myExecutable(已删除)”

我知道我的可执行文件已被较新的更新版本替换,并且 /proc/self/exe 的原始版本现在已被替换,但是,当我转到 execv() 它现在失败并显示 errno 2 - No such file or directory. 由于额外的尾随 "(deleted)"结果。

我希望 execv() 自己使用旧的可执行文件,或者更新后的可执行文件。我可以只检测以 "(deleted)" 结尾的字符串并修改它以忽略它并解析为更新的可执行文件,但这对我来说似乎很笨拙。

当原始可执行文件在执行期间被更新的可执行文件替换时,我如何使用一组新的参数execv() 当前可执行文件(或者它的替换,如果更容易的话)?

最佳答案

您可以直接在 /proc/self/exe 上调用 open,而不是使用 readlink 来发现您自己的可执行文件的路径。由于内核已经为当前正在执行的进程打开了一个 fd,因此无论该路径是否已被新的可执行文件替换,这都会为您提供一个 fd。

接下来,您可以使用 fexecve 而不是 execv,后者接受 fd 参数而不是 filename 参数对于可执行文件。

int fd = open("/proc/self/exe", O_RDONLY);
fexecve(fd, argv, envp);

为简洁起见,以上代码省略了错误处理。

关于c++ - 在执行过程中替换可执行文件时如何处理 "/proc/self/exe"的 readlink()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28953307/

相关文章:

linux - centos7上的xrdp无法连接

c - 将 execl 与多个子进程一起使用

c - 等待子执行

c++ - 直接用rapidjson保存json到文件

c++ - 我是否负责在 QImage::bits() 函数提供的指针上调用 delete?

c++ - 使用 CPP 读取 CSV 文件,使用 CMake 文件编译代码

python - 从 Cython 模块导出包装的 C++ 类

linux - Bash 脚本每行输入 2 个具有不同输出元素的文件

linux - Kmemcheck 输出位置

java - 存储可通过 php 调用的 java 可执行文件