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 stands for?
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 stands for?
Each step is relatively simple.
In Unix, your process has two parts -- a read-only memory area with the application code ("text") and the read-write memory area ("data").
A fork clones the read-write area, leaving the text page alone. You now have two processes running the same code. They differ by a register value -- the return value from fork -- which separates parent from child.
An exec replaces the text page, leaving the data page alone. There are many forms of exec, depending on how much environment information you're passing to it. See http://linux.die.net/man/3/exec for an additional list of variants.
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[]);
The "exec" family of functions replace the current process image(from where it is called) with a new process image, so the calling image is replaced by the new process image. For eg. if you were to run the 'ls' command from a shell(/bin/sh or /bin/csh) then the shell would fork to a new process which would then execute ls. Once the ls command exits it returns control to the parent process, which in this example is the shell.
If there were no fork funtionality then the shell would be replaced by the 'ls' process which upon exit would leave you with an inaccessible terminal since the shell's image in memory was replaced upon the exec call to ls.
For variations in the 'exec' family look at 0x6adb015's answer.
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 beofore 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.