Execing Processes in C++
Our example demonstrates how to replace the current process with a new one using the exec
system call in C++. This is similar to the classic exec
function in Unix-like operating systems.
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <vector>
int main() {
// For our example we'll exec 'ls'. We need the full path to the binary.
const char* binary = "/bin/ls";
// exec requires arguments in a vector of C-strings.
// The first argument should be the program name.
std::vector<char*> args = {
const_cast<char*>("ls"),
const_cast<char*>("-a"),
const_cast<char*>("-l"),
const_cast<char*>("-h"),
nullptr // The last element must be nullptr
};
// exec also needs the current environment.
extern char** environ;
// Here's the actual execve call. If this call is successful,
// the execution of our process will end here and be replaced
// by the '/bin/ls -a -l -h' process. If there is an error,
// execve will return -1.
if (execve(binary, args.data(), environ) == -1) {
std::cerr << "execve failed: " << std::strerror(errno) << std::endl;
return 1;
}
// This line will only be reached if execve fails
return 0;
}
When we run our program, it is replaced by ls
:
$ g++ -o exec_example exec_example.cpp
$ ./exec_example
total 24K
drwxr-xr-x 2 user user 4.0K Jun 15 10:00 .
drwxr-xr-x 10 user user 4.0K Jun 15 09:55 ..
-rwxr-xr-x 1 user user 17K Jun 15 10:00 exec_example
-rw-r--r-- 1 user user 750 Jun 15 09:59 exec_example.cpp
Note that C++ doesn’t offer a direct equivalent to Go’s exec.LookPath
. In this example, we’ve used the full path to ls
. In a more robust implementation, you might want to search the PATH environment variable to find the executable.
Also, C++ doesn’t have built-in support for getting the current environment variables like Go’s os.Environ()
. Instead, we use the environ
external variable, which is a null-terminated array of strings representing the current environment.
Unlike Go, C++ (and C) do offer a classic Unix fork
function. However, for many use cases, creating new processes or using threads can cover similar functionality.