How do I use execve in C?

The execve system call is part of how new processes are created in UNIX. A call to execve replaces the current process image with a new process image. Example:

#include <stdio.h>
#include <unistd.h>
int main(void) {
  printf("Main program started\n");
  char* argv[] = { "jim", "jams", NULL };
  char* envp[] = { "some", "environment", NULL };
  execve("./sub", argv, envp) == -1);
  perror("Could not execve");
  return 1;

Running this program starts a process which prints some text, then replaces itself with a different program. In this example, the program is given by "./sub", a path to the program. After executing execve("./sub", ...), the process behaves like the program ./sub. Here’s the output, with a ./sub program which prints its arguments and environment:

% cc main.c -o main
% ./main
Main program started
Sub program started with args: jim jams
Sub program environment:

The full call is execve(path, argv, env). The second argument provides the process’s argument array (the argv seen in the second argument to main in the ./sub program). The third argument provides the process’s environment (the environ seen by the ./sub program).

The argv and envp values are deliberately strange in this example. It is idiomatic to pass the program’s name as its first argument, but, as this shows, this idiom can be broken: the program is "./sub", but we pass the first argument "jim". Thus the sub program never knows that it was executed from the program at "./sub". The envp is strange because is it idiomatic to pass key-value strings in the environment, such as "FOO=bar". Again, this is just an idiom, and it can be broken.

The execve call ordinarily never returns, since the process that called it is replaced. It only returns if it fails, in which case it returns -1.

Notice that execve does not create a new process! So, how then can we get from one process to two, and so on? The answer is fork - another system call, to be covered in a future post.