Using the fork system call

The signature of the fork is simplicity itself:

pid_t fork(void);

This looks trivial, but you know the saying the devil lies in the details! Indeed, we shall bring out several subtle, and not-so-subtle, pointers regarding the correct usage of this system call.

To begin to understand how fork works, lets write a simple C program (ch10/fork1.c):

int main(int argc, char **argv)
{
fork();
printf("Hello, fork. ");
exit (EXIT_SUCCESS);
}

Build and run it:

$ make fork1
gcc -Wall -c ../../common.c -o common.o
gcc -Wall -c -o fork1.o fork1.c
gcc -Wall -o fork1 fork1.c common.o
$ ./fork1
Hello, fork.
Hello, fork.
$

The fork will, on success, have created a new child process.

A key programming rule: never assume an API succeeds, always check for the failure case !!!

This cannot be overstressed.

OK, let's modify the code to check for the failure case; any and every system call (with perhaps just two exceptions out of around 380 syscalls) return -1 on failure. Check for it; here is the relevant code snippet (ch10/fork1.c):

    if (fork() == -1)
FATAL("fork failed! ");
printf("Hello, fork. ");
exit(EXIT_SUCCESS);

The output is identical to what we saw previously (of course, since the fork did not fail). So, the printf seems to have been executed twice. Indeed it was: once by the parent process, and once by the new child process. This immediately teaches us something about the way fork works; here, we will attempt to codify these things as the rules of fork. In this book, we shall end up codifying seven rules of fork(2).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset