System call execve
Description
execve() executes the program referred to by pathname.
This causes the program that is currently being run by the calling process to
be replaced with a new program, with newly initialized stack, heap, and
(initialized and uninitialized) data segments.
One sometimes sees execve() (and the related functions described
in exec(3)) described as "executing a new process" (or similar).
This is a highly misleading description: there is no new process;
many attributes of the calling process remain unchanged (in
particular, its PID). All that execve() does is arrange for an
existing process (the calling process) to execute a new program.
exec() is standard C library (libc, -lc), execve() is systemcall.
The exec() family of functions replaces the current process image
with a new process image.
Example
The following program is designed to be execed by the second program below. It just echoes its command-line arguments, one per line.
/* myecho.c */
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
for (int j = 0; j < argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
}
This program can be used to exec the program named in its command-line argument:
/* execve.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) {
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve"); /* execve() returns only on error */
exit(EXIT_FAILURE);
}
We can use the second program to exec the first as follows:
$ cc myecho.c -o myecho
$ cc execve.c -o execve
$ ./execve ./myecho
argv[0]: ./myecho
argv[1]: hello
argv[2]: world