Lab 10 Preparation

To prepare for Lab Exercise 10 on the fork() and wait() function calls and the corresponding O/S services, first review the lecture notes about fork(2) and wait(2). Copy the source files for the sample programs fork1 to fork5 (found in the directory ~allisor/Student/cst8204/fork in the lab) and compile them, then run each of them.

Read over the source code carefully and check the output from your test runs until you understand why each one behaves as it does. Use gdb if necessary to follow the execution and confirm the value of variables. Modify some or all of the samples to see how the behaviour changes as you re-compile and re-run each.

In Stevens/Rago you should read sections 8.1 to 8.3, 8.5 and 8.6, and 8.9. Note that the system() function in section 8.13 is only to be used in this course for clearing the screen if necessary: system("clear"); although you can easily duplicate this by using fork(), wait(), and execlp() (section 8.10) yourself. Read these sections over carefully and fit the knowledge there into your understanding of the sample programs.

fork(2) [derived from man 2 fork]

#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);

fork() creates a child process that differs from the parent process only in its PID (process ID) and PPID (parent process ID). On success, the PID of the child process is returned in the parent's thread of execution, and a 0 is returned in the child's thread. On failure, a -1 will be returned in the parent's context, no child process will be created, and errno will be set appropriately.

wait(2) [derived from man 2 wait]

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status)

The wait() function suspends the current process until a child has exited, or until a signal is delivered whose action is to terminate the current process or to call a signal handling function. If a child has already exited by the time of the call, the function returns immediately. Any system resources used by the child are freed.

Note that wait() is passed the address of an int, a pointer to a place to put the child's exit status: wait(&some_int). wait() returns the PID of the exiting child or -1 on error, setting errno as appropriate.

If the pointer is not NULL, wait() stores status information in the location pointed to by the pointer. This status can be evaluated with the following macros (these macros take the status variable itself (an int) as an argument -- not a pointer to the variable!) [only 2 macros are shown here -- see the man page or Stevens/Rago for others]:

WIFEXITED(status)
is non-zero (true) if the child exited normally.
WEXITSTATUS(status)
evaluates to the least significant eight bits of the return code of the child which terminated, which may have been set as the argument to a call to exit() or as the argument for a return statement in the child's main program. This macro is only valid if WIFEXITED is true.

K&R also has a brief description of exit() and system() on pages 252 and 253, and of argc/argv in section 5.10 beginning on page 114.

Finally, update your input.c and output.c programs from your previous lab as necessary (base them on the sample files from the copy subdirectory for the lecture on Standard I/O), since you will use them as the basis for this lab. Copy the completed source files and your Makefile into a new directory for Lab 10.