In my C++ application, my application does an execv()
in a fork()
ed child process to use the same executable to process some work in a new child process with different arguments that communicates with pipes to the parent process. To get the pathname to self, I execute the following code on the Linux port (I have different code on 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));
However, if while the executable is running, I replace the executable with an updated version of the binary on disk, the readlink()
string result is: "/usr/local/bin/myExecutable (deleted)"
I understand that my executable has been replaced by a newer updated version and the original for /proc/self/exe
is now replaced, however, when I go to execv()
it now fails with the errno
2 - No such file or directory.
due to the extra trailing " (deleted)"
in the result.
I would like the execv()
to either use the old executable for self, or the updated one. I could just detect the string ending with " (deleted)"
and modify it to omit that and resolve to the updated executable, but that seems clumsy to me.
How can I execv()
the current executable (or its replacement if that is easier) with a new set of arguments when the original executable has been replaced by an updated one during execution?
Instead of using readlink
to discover the path to your own executable, you can directly call open
on /proc/self/exe
. Since the kernel already has an open fd to processes that are currently executing, this will give you an fd regardless of whether the path has been replaced with a new executable or not.
Next, you can use fexecve
instead of execv
which accepts an fd
parameter instead of a filename
parameter for the executable.
int fd = open("/proc/self/exe", O_RDONLY);
fexecve(fd, argv, envp);
Above code omits error handling for brevity.