Take the 2-minute tour ×

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?

share|improve this question
add comment

4 Answers

up vote 5 down vote accepted

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.

share|improve this answer
Really, you cannot do anything wrong with fork(), as it does not have any argument. Can it be any simpler? –  0x6adb015 May 29 '09 at 14:20
Umm, exec replaces the entire mm, not just the "text"... see /usr/src/linux/fs/exec.c and /usr/src/linux/fs/binfmt_elf.c –  ephemient May 29 '09 at 15:25
Typically, fork will not clone the data area, but mark it as Copy-On-Write (COW) instead. If either parent or child tried to change data, the page will then be cloned and the parent and child will end up with different pages. –  camh May 31 '09 at 1:59
add comment
  • exec: Execute new process
  • v : use array of arguments
  • e: Specify as well the environment

Other variations of exec abound:

              ..., char * const envp[]);
  • l: list arg on function
  • p: use $PATH to locate executable file
share|improve this answer
add comment

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 functionality 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.

share|improve this answer
add comment

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:

  • File descriptors
  • User/group ID
  • Process group and session IDs
  • Current directory
  • Resource limits
  • Scheduling priority and affinity
  • File creation mask (umask)

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.

share|improve this answer
+1. I was wondering what you mean by "it would need to take arguments for each of these process attributes if you wanted them set differently in a child process." –  Tim Aug 6 '11 at 22:46
Are there some example code to illustrate changing env vars w and w/o spliting up fork and exec, to show which one is more flexible? –  Tim Aug 6 '11 at 23:40
@Tim: See msdn.microsoft.com/en-us/library/ms682425(v=vs.85).aspx for one example, and see that the argument list in that function call does not cover everything listed above. –  camh Aug 6 '11 at 23:43
Is it right that the envp argument of spawn* functions (en.wikipedia.org/wiki/Spawn_%28computing%29) can accept any env vars? So are they as flexible as fork-exec, and more flexible than createprocess function? Why does the article say that "the spawn function, although it deals adequately with the most common use cases, lacks the full power of fork-exec, since after fork any process settings which will survive an exec may be changed. However, in most cases, this deficiency can be made up for by using the more low-level CreateProcess API"? –  Tim Aug 7 '11 at 0:05
@Tim: Comments here are for comments, not questions. If you have a question, post it as a question. My answer here adequately answers the original question, and I don't feel it should be expanded to talk about Windows process creation functions. –  camh Aug 7 '11 at 3:33
add comment

Your Answer


