Cmput 379 Lab Exercise #1
For the period 12-18 January, 2001
Objective (Your TA will review this
exercise at the start of the lab period)
Write a C-program to explore the Unix client/server use of:
-
fork() -- for creating a child process
-
pipe() -- for communicating between two processes that have a
"parent-child" relationship
-
Some i/o functions like putc, getc, read, write.
This is also an opportunity to gain a working familiarity with Stevens'
book, which will be a mainstay reference for the later programming assignments.
Filenames
Hold your source code in a single file called ParentChild.c and
your compiled executable code in ParentChild. The stderr output
is to appear in a file called ParentChild.err
Program Specifications
Write a program that consists of a simple infinite
loop: it reads a line of input from stdin, and writes the line
to stdout. This snippet of a program must terminate
properly when a Ctrl-D (end-of-file) is entered.
Next add a call to fork() before the
loop, so that a parent process creates a child (a clone) that executes
its own section of code with its own i/o requests, while the
parent continues into the infinite loop as before.
Since both the parent and the child are initially attached to the
user's keyboard and monitor, it may not be clear who is
reading/writing what. Check it out.
Revise your program so that the parent side is used for
reading from the keyboard (stdin) and sending
the information entered to the child via a data-pipe.
Similarly the child
takes the information from the parent through a data-pipe
and writes it to stdout (the monitor).
This is done by detaching the parent from the monitor
(close stdout) and the child from the keyboard (close stdin)
in the appropriate places.
Note the pipe() must be set up before the fork(),
see Stevens for details.
If stderr is attached to an output file before fork()
is called, then both parent and child write to the same error file. Thus
stderr
may be used to check the sequencing of events.
Do this, and have the parent write to
stderr a copy of whatever is sends over the pipe. Similarly, have
the child write to stderr whatever it receives over the pipe.
Check it out. Does it work OK?
Finally the parent cannot know how long the input line is going to be.
There are a couple of ways of addressing this issue. Implement one of
them. Equally, the size of the internal buffer allocated to the pipe
is fixed (what is it?), and so this too may pose problems for the
child process if the data line is longer.
Discuss briefly how you address these issues.
Diagrammatically we have:
parent child
------------- ------------
Keyboard ---->|stdin p[0]|----\ |p[0] stdin|
|stdout p[1]| \---->|p[1] stdout|---> Monitor
------------- pipe ------------
Demonstrate that the program works by invoking the program with
ParentChild
and typing miscellaneous text at the keyboard.
Program Execution
It should be possible to invoke your program in the following four ways:
ParentChild
ParentChild <infile >outfile
<infile ParentChild >outfile
cat infile | ParentChild >outfile
Where, for demonstration purposes, infile can be ParentChild.c
Do all these cases work equally well?
In what way are some of them fundamentally different?
Does the following command also work?
ParentChild 0<infile 1>outfile 2>ParentChild.err
Comment on these points and summarize what you have learnt in a
single email to your TA at the end of the laboratory period.
A Requirement (must work for all four invocations above)
-
Set up your program so that a Ctrl-D typed at the keyboard is enough to
terminate both parent and child properly.
Hints
-
Remember CMPUT 201 basics, your PATH variable must
be set correctly to execute programs in the current directory.
A More Interesting Variation
-
Move the fork() function inside the
parent's infinite loop. As each line is read by the parent a new child
process is spawned
to "process" (display) the input line. The parent and child processes
can be said to be in a client/server relationship.
These processes should all disappear after a Ctrl-D or Ctrl-C is
entered. You can check by using the "ps" command.
However, if you enter a Crtl-Z and then use "ps" you should see your
parent and child processes "waiting". Restart your application using
"fg" and terminate normally. Again use "ps" to check that all processes
have disappeared.
Copyright ©
Department of Computing Science.
All rights reserved.
Last update:
|