The new process will be created within the fork()
call, and will start by returning from it just like the parent. The return value (which you stored in retval
) from fork()
will be:
- 0 in the child process
- The PID of the child in the parent process
- -1 in the parent if there was a failure (there is no child, naturally)
Your testing code works correctly; it stores the return value from fork()
in child_pid
and uses if
to check if it's 0 or not (although it doesn't check for an error)
It's to simplify the interface. The alternative to fork
and exec
would be something like Windows' CreateProcess function. Notice how many parameters CreateProcess
has, and many of them are structs with even more parameters. This is because everything you might want to control about the new process has to be passed to CreateProcess
. In fact, CreateProcess
doesn't have enough parameters, so Microsoft had to add CreateProcessAsUser and CreateProcessWithLogonW.
With the fork/exec
model, you don't need all those parameters. Instead, certain attributes of the process are preserved across exec
. This allows you to fork
, then change whatever process attributes you want (using the same functions you'd use normally), and then exec
. In Linux, fork
has no parameters, and execve
has only 3: the program to run, the command line to give it, and its environment. (There are other exec
functions, but they're just wrappers around execve
provided by the C library to simplify common use cases.)
If you want to start a process with a different current directory: fork
, chdir
, exec
.
If you want to redirect stdin/stdout: fork
, close/open files, exec
.
If you want to switch users: fork
, setuid
, exec
.
All these things can be combined as needed. If somebody comes up with a new kind of process attribute, you don't have to change fork
and exec
.
As larsks mentioned, most modern Unixes use copy-on-write, so fork
doesn't involve significant overhead.
Best Answer
The short answer is,
fork
is in Unix because it was easy to fit into the existing system at the time, and because a predecessor system at Berkeley had used the concept of forks.From The Evolution of the Unix Time-sharing System (relevant text has been highlighted):
Since that paper, Unix has evolved.
fork
followed byexec
is no longer the only way to run a program.vfork was created to be a more efficient fork for the case where the new process intends to do an exec right after the fork. After doing a vfork, the parent and child processes share the same data space, and the parent process is suspended until the child process either execs a program or exits.
posix_spawn creates a new process and executes a file in a single system call. It takes a bunch of parameters that let you selectively share the caller's open files and copy its signal disposition and other attributes to the new process.