Cmput 379 Lab Exercise #3

For the period 26 January - 1 February, 2001

Objective

Write a C-program to explore the use of:

Filenames

Hold the source code of the driver program in ParentChild.c and place the source of your "to be executed" child in Exec.c
 

Program Review (previous week's work)

During the second week you should have written a small program along the following lines:

The parent is in an infinite loop reading lines of data until an EOF occurs.  When data arrives at stdin a child process is spawned and the data passed to it via a pipe,  perhaps using the "write" system call to send N bytes  The child reads the line of data from the pipe, but since it does not know how many bytes have been put there some care is needed.  The following approaches are possible:

The child also closes its stdout descriptor and uses dup2 to attach stdout to a second pipe.  Now the child can use all the output functions that are normally associated with stdout to send the converted data back to the parent.

Issues that could arise:
When executed as a command line of the form ParentChild there is no problem.  When executed as:

ParentChild <infile >outfile
there may be a problem if infile is large (has very long or varied-length lines).  Children will be created in rapid succession and, depending on how the i/o is done and when the context switches occur, a later initiated child process may output  some of its characters before  an earlier process. There should not be any lost data.

In every lab, students should demonstrate any program with anomalous i/o behaviour to their TA, and should propose explanations for the anomaly.
 

Program Guidelines (this week's work)

Re-implement last week's model program so that the Child Process now invokes the executable that is compiled from the source Exec.c  This is done using one of the exec() system functions.  The replacement process will have the same process ID as the Child.  The replacement must receive from the original child all the file descriptors it needs. The new Child must read from the Parent's outlet pipe via stdin, and must attach its stdout to the inlet pipe back to the parent (thus replicating the communication path of the week #2 exercise).

Program Execution

It should be possible to invoke your program in the following ways:
ParentChild
ParentChild <infile >outfile
ParentChild <infile 2>&outfile

The last example is for C-shell users and combines stdout and stderr output into a single file.  An equivalent demonstration by sh, bash and tsh users is expected.
While executing ParentChild <infile >outfile students should type Ctrl-Z and 
then issue a 'ps' command to see what processes exist. Comment on what you see.  
Restart with the fg (foreground) command.

Requirements

  1. Exec.c receives from the original child the "descriptions" of the inlet and outlet pipes that the parent is using [Stevens, on p.210, says that by default open file descriptors are preserved across an exec call, but you can also transfer these descriptors explicitly in the exec() parameter list]. The Exec.c child attaches the parent's outlet pipe to its own stdin, and its own stdout to the parent's inlet pipe, by using dup2() twice.  As in Lab #2, Exec.c converts the input data to upper case but now returns to the parent several lines of output.  Each line represents a single word of text from the input line.  White space is the word separator. In other words, the child code from Exercise #2 should be transferred into Exec.c (and enhanced by having each word delimited by '\n').  The fork child code only has to setup the file descriptors correctly [using dup2()], and then 'exec' the Exec.c executable.

  2.  
  3. It is necessary for students to demonstrate that their program terminates naturally and without loss of data when an EOF is read by the parent.  At the end of every line sent by the Parent to the Child the outlet pipe should be closed, even though this may not be strictly necessary.  This allows the Child to see the resultant EOF on the pipe (not actually important here, since the Child is only reading a single line).  However, because the Child is now responding to the Parent with multiple lines of output, the Child must close its outlet pipe to the Parent, so that the Parent in turn can see the EOF there and know that communication from the Child is complete.

  4.  
  5. One fundamental problem that is being addressed is for the Parent to know that it has sent an EOF to the Child, and thus that when the last Child terminates (e.g., the inlet pipe from the Child also shows EOF, or the wait()/waitpid() function completes), the Parent itself exits instead looping back to read more data.

Marking Guide

20 marks for completion of Lab Exercise #1 and #2 by 25 January (that is at the end of the lab period, or as the TA designates).

10 marks for week three, use of exec() to launch a program that returns each word on a separate line.
10 marks for week three, having the parent use wait() / waitpid() to clean-up zombies before exiting.

In the case of exercise #3, a portion of the marks will be for active participation in lab. sessions and "quality" of work done:  clean structure of programs, appropriate (but not excessive) comments, good programming style.
 


Copyright © Department of Computing Science.
All rights reserved.
Last update: