System Interface Guide

Spawning New Processes

fork(2)

fork(2) creates a new process that is an exact copy of the calling process. The new process is the child process; the old process is the parent process. The child gets a new, unique process ID. fork(2) returns a 0 to the child process and the child's process ID to the parent. The returned value is how a forked program determines whether it is the parent process or the child process.

The new process created by fork(2) or exec(2) function inherits all open file descriptors from the parent including the three standard files: stdin, stdout, and stderr. When the parent has buffered output that should appear before output from the child, the buffers must be flushed before the fork(2).

The following code is an example of a call to fork(2) and the subsequent actions:


	pid_t		pid;

 	pid = fork();
 	switch (pid) {
 		case -1:			/* fork failed */
 			perror ("fork");
 			exit (1);
 		case 0:			/* in new child process */
 			printf ("In child, my pid is: %d\n", getpid(); );
 			do_child_stuff();
 			exit (0);
 		default:			/* in parent, pid contains PID of child */
 			printf ("In parent, my pid is %d, my child is %d\n", getpid(), pid);
 			break;
 	}

 	/* Parent process code */
 	...

If the parent and the child process both read input from a stream, whatever is read by one process is lost to the other. So, once something has been delivered from the input buffer to a process, the buffer pointer has moved on.


Note -

An obsolete practice is to use fork(2)and exec(2) to start another executable, then wait for the new process to die. In effect, a second process is created to perform a subroutine call. It is much more efficient to use dlopen(3X), dlsym(3X), and dlclose(3X) as described in "Runtime Linking " to make a subroutine temporarily resident in memory.


exec(2)

exec(2) is the name of a family of functions that includes execl(2), execv(2), execle(2), execve(2), execlp(2), and execvp(2). All load a new process over the calling process, but with different ways of pulling together and presenting the arguments of the function. For example, execl(2) could be used like this


	execl("/usr/bin/prog2", "prog2", progarg1, progarg2, (char (*)0));

The execl argument list is:

/usr/bin/prog2

The path name of the new program file. 

prog2

The name the new process gets in its argv[0].

progarg1, progarg2

The arguments to prog2 as char (*)s.

(char (*)0)

A null char pointer to mark the end of the arguments. 

There is no return from a successful execution of any variation of exec(2); the new process overlays the process that calls exec(2). The new process also takes over the process ID and other attributes of the old process. If a call to exec(2) fails, control is returned to the calling program with a return value of -1. You can check errno to learn why it failed.