如何在执行期间替换可执行文件时处理"/ proc/self/exe"的readlink()?

Wil*_*mKF 9 c++ linux fork exec self-reference

在我的C++应用程序中,我的应用程序execv()fork()ed子进程中执行以使用相同的可执行文件来处理新子进程中的一些工作,这些进程具有与管道与父进程通信的不同参数.要获取自己的路径名,我在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));
Run Code Online (Sandbox Code Playgroud)

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

据我所知,我的可执行文件已被替换为新的更新版本和原来的/proc/self/exe是现在换成,但是,当我去execv(),现在失败了errno2 - No such file or directory.由于额外的尾随" (deleted)"的结果.

我想要execv()使用旧的可执行文件为自己,或更新的可执行文件.我可以检测到以字符串结尾的字符串" (deleted)"并修改它以省略它并解析为更新的可执行文件,但这对我来说似乎很笨拙.

我怎样才能execv()在当前的可执行文件(或它的替代,如果这是更容易)一组新的参数,当原始的可执行已取代执行期间更新的一个?

and*_*wrk 6

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

接下来,您可以使用fexecve代替参数execv接受可执行文件fdfilename参数。

int fd = open("/proc/self/exe", O_RDONLY);
fexecve(fd, argv, envp);
Run Code Online (Sandbox Code Playgroud)

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

  • 还没有机会确认,但读完后听起来很棒! (2认同)