fork
and exec
System CallsThe left arrow above will return you to
the Home page
The left arrows below will return you to the Previous
page
Process creation in UNIX is achieved by means of the kernel system call, fork(). When a process issues a fork request, the operating system performs the following functions (in kernel mode):
- It allocates a slot in the process table for the new process
- It assigns a unique process ID to the child process
- It makes a copy of the parent's process control block
- It makes a copy of the process image of the parent (with the exception of any shared memory)
- It increments counters for any files owned by the parent to reflect that an additional process now also owns those files
- It assigns the child process to a Ready to Run state
- It returns the ID number of the child to the parent process and a 0 value to the child process - this function is called once and returns twice!
#include <sys/types.h> pid_t fork(void); Returns: 0 in child, process ID of child in parent, -1 on error |
The fork system call creates a new process that is essentially a clone of the existing one. The child is a complete copy of the parent. For example, the child gets a copy of the parent's data space, heap and stack. Note that this is a copy. The parent and child do not share these portions of memory. The child also inherits all the open file handles (and streams) of the parent with the same current file offsets.
The parent and child processes are essentially identical except that the new process has a new process ID and the return value from the fork call is different in the two processes:
- The "parent" process gets the new process ID of the "child" returned from the fork call. If, for some reason the process can not be cloned, then -1 is returned
- The "child" process is returned 0 (zero) from the fork call.
To actually load and execute a different process, the fork request is used first to generate the new process. The kernel system call: exec(char* programfilename) is then used to load the new program image over the forked process:
- exec identifies the required memory allocation for the new program and alters the memory allocation of the process to accommodate it
- The program is loaded into memory and execution is commenced at the start of the main() routine.
The exec system call reinitializes a process from a designated program; the program changes while the process remains! The exec call does not change the process ID and process control block (apart from memory allocation and current execution point); the process inherits all the file handles etc. that were currently open before the call.
Without fork, exec is of limited use; without exec, fork is of limited use (A favourite exam questions is to ask in what circumstances you would/could use these functions on their own. Think about it and be prepared to discuss these scenarios).
exec variants:
System |
Argument |
Environment |
PATH |
---|---|---|---|
execl |
list |
auto |
no |
execv |
array |
auto |
no |
execle |
list |
manual |
no |
execve |
array |
manual |
no |
execlp |
list |
auto |
yes |
execvp |
array |
auto |
yes |
#include <unistd.h> int execl(path,arg0,arg1,...,argn,null) char *path; // path of program file char *arg0; // first arg (file name) char *arg1; // second arg (1st command line parameter) ... char *argn; // last arg char *null; // NULL delimiter int execv(path,argv) char *path; char *argv[]; // array of ptrs to args,last ptr = NULL int execle(path,arg0,arg1,.,argn,null,envp) char *path; // path of program file char *arg0; // first arg (file name) char *arg1; // second arg (1st command line parameter) ... char *argn; // last arg char *null; // NULL delimiter char *envp[]; // array of ptrs to environment strings // last ptr = NULL int execve(path,argv,envp) char *path; char *argv[]; // array of ptrs to args,last ptr = NULL char *envp[]; // array of ptrs to environment strings // last ptr = NULL int execlp(file,arg0,arg1,...,argn,null) int execvp(file,argv) All six return -1 on error, no return on success |
In the first four exec functions, the executable file has to be referenced either relatively or absolutely by the pathname. The last two search the directories in the PATH environment variable to search for the filename specified.
Example of use of fork and exec
switch (fork()){ case -1: // fork error syserr("fork"); case 0: // continue execution in child process execlp("pgm","pgm",NULL); syserr("execl"); // will only return on exec error } // continue execution in parent processFor a full example of the use of fork and exec see the forkexec.c example.
The descriptions of the system functions above are drawn from sources that include
man
uals on the Sun Solaris system and the MAC OS X Darwin/BDS system, and also from 'Advanced Programming in the UNIX Environment', W. Richard Stevens, Addison-Wesley, 1993.
For use only by students and instructors using the supplementary material available with the text book: "Operating Systems - Internals and Design Principles", William Stallings, Prentice Hall, 5th Edition, 2004. Not to be printed out or copied by any other persons or used for any other purpose without written permission of the author(s).
©