/* fork.c - demo of fork and exec * * Note that exec takes 2 parameters: name of binary; argument list * * Modifications to experiment with: * 1. Change the name of the file we wish to display to a nonexistent one. * 2. Instead of running cat, run a "bad" program. */ #include #include #include #include main(int argc, char **argv) { char *newargv[3]; int i, j; /* We can change name of the file to display to a nonexistent file. */ /* newargv[0] = "cat"; newargv[1] = "f85.txt"; newargv[2] = NULL; */ newargv[0] = "./bad"; newargv[1] = NULL; for (j = 1; j <= 4; ++j) { /* Print out Process ID. Used to prove which process is talking. */ printf("I am process %d. Iteration %d\n", getpid(), j); /* Try to fork and create a new process address space, then * in the child: attempt to exec the 'cat' program/command. */ if (fork() == 0) { printf (" Child process %d has just been born\n", getpid()); i = execv("/bin/cat", newargv); printf (" (child) pid = %d: execv returned %d\n", getpid(), i); } else { /* The parent: if we successfully called cat, we are going to "wait" * until it finishes and then only move on from there. */ printf (" (parent) pid = %d: i = %d ", getpid(), i); printf ("wait returns %d ", wait(&i)); printf ("wait changed i to %d\n\n", i); /* i is the status. Documentation on the wait system call is given * in "man -s 2 wait". It says we can test the value of the status * parameter i using various macros to see what happened. */ printf(" WIFEXITED: terminated normally? %d\n", WIFEXITED(i)); printf(" WEXITSTATUS: child's exit status %d\n", WEXITSTATUS(i)); printf(" WIFSIGNALED: signal killed child? %d\n", WIFSIGNALED(i)); if (WIFSIGNALED(i)) { printf(" WTERMSIG: which signal: %d\n", WTERMSIG(i)); printf(" WCOREDUMP: core dump? %d\n", WCOREDUMP(i)); } } } }