It is said that fork
system call creates a clone of the calling process, and then (usually) the child process issues execve
system call to change its image and running a new process. Why this two-step?
BTW, what does execve
stand for?
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.
Fork system call is used for creating a new process, which is called child process, which runs concurrently with the process that makes the fork() call (parent process). After a new child process is created, both processes will execute the next instruction following the fork() system call.
So the main difference between fork() and exec() is that fork starts new process which is a copy of the main process. the exec() replaces the current process image with new one, Both parent and child processes are executed simultaneously.
exec() replaces the current process with a new one. It has nothing to do with fork(), except that an exec() often follows fork() when what's wanted is to launch a different child process, rather than replace the current one.
The reason for the two-step is flexibility. Between the two steps you can modify the context of the child process that the newly exec'ed program will inherit.
Some things you may want to change are:
If you did not split up fork and exec and instead had a single spawn-like system call, it would need to take arguments for each of these process attributes if you wanted them set differently in a child process. For example, see the argument list to CreateProcess in the Windows API.
With fork/exec, you change whatever inheritable process attributes you want to in the child before you exec the new program.
Setting up file descriptors is one of the more common things to change in a child's process context. If you want to capture the output of a program, you will typically create a pipe in the parent with the pipe(2) system call, and after fork(2)ing, you will close the write end in the parent process and close the read end in the child process before calling execve(2). (You'll also use dup(2) to set the child end of the pipe to be file descriptor 1 (stdout)). This would either be impossible or restrictive in a single system call.
Other variations of exec abound:
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With