fork/exec/process explorations

This homework concerns two C programs about how fork and exec work. They come from Understanding Unix/Linx Programming, Bruce Molay, Chapter8.

These are brain-teaser-type problems designed to call your attention to certain subtleties. They are available in source code form on the remote unix server. You can bring them to your own linux machine from the remote server (user "public" has password CS78password). Or, if you want to use them on the remote server, they are in /home/public/ from where you can copy them into your home directory.

The files that contain them are

prob8.2.c
prob8.6.c

Also available there, for you to examine or experiment, are the series of 11 programs used in my slides demonstrating the workings of fork and exec. Source code files for these programs reside on the server. Individually, they are there under the same names by which they appear in the slides shown in class: fork1.c, fork2.c,..., fork11.c. Collectively, the same files are consolidated in fork-sourcefiles-process-creation.zip. They sit in /home/public. You can use them either on the server, logging in to your account there to do so and copying them into your home directory. Alternatively, you can transfer them by scp/sftp, as user "public," to a linux computer of your choice elsewhere and work with them there instead. If you download these source files you will want to compile so you can run them. The command to compile would be, for example:

 gcc  fork2.c  -o  fork2

and then to run"

 ./fork2

The summary of the point of these programs is:

Version Purpose
fork1 shows fork, demonstrates that 2 processes result
fork2 shows PIDs (process id numbers) of these processes, and that they're distinct
fork3 shows fork's return value to the child copy (zero) and its return value to the parent copy (child's PID)
fork4 shows how to code differentiated behavior via an "if" structure conditioned on fork's return value
fork5 incorporates an exec call in the child
fork6 introduces exit call in child and wait call in parent, to give orderly discipline to their relative timing
fork7 gets the name of the program to be exec'd from the user via the command line
fork8 interactively gets the name of the program to be exec'd by prompting user
fork9 puts the activity inside a loop to extend it to second, third, fourth,... commands
fork10 shows a zombie process
fork11 shows an adopted child, init process as its step-parent after being pre-deceased by its original parent

You must understand that copying is the way fork( ) births a new process,. The resultant child process is genetically identical to the parent process, the one that issued the fork( ) call. That is, the child has the same content as the parent (data, buffers, variables, data structures expressing resource usage, even code). Review my presentations (links entitled "Processes," "Homemade shell" "Process miscellany") and Molay's chapter 8 whose source code is available from Molay's website. To figure out 8.4, see the short discussion of file pointers on pages 63-64.

 

The exercise for you to perform:

Run each of the two programs. Observe the results. Identify what is noteworthy, unexpected, or the supposed point in each of these programs (its behavior of interest). On a piece of paper, for each, write a one or two sentence explanation of what you've identified. In other words, state what the point is and explain. Hand in the paper.

For prob8.2.c what the Molay book asks of the student is, "Predict the output of this program. How would the output change if the two lines with comments were removed?"

For prob8.6.c what the book asks is, "Unix shells allow users to run programs in the background. How is this program similar to a background process?

 

Here is the source code for the two programs:

prob8.2.c

main()
{
  int n;
  for (n=0;n<10;n++)
  {
    printf("my pid = %d, my ppid = %d, n = %d\n" , getpid(), getppid(), n);
    sleep(1);
    if ( fork() != 0 )    /* what if these two */
      exit(0);               /* lines were removed? */
  }
}

prob8.6.c

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

main()
{
  int i;

  if ( fork() != 0 )
    exit(0);
  for( i=1 ; i<=10 ; i++ )
    {
    printf("still here..\n");
    sleep(i);
    }
  return 0;
}