CSc 422 Assignment 2
Inmates Running the Asylum
This program involves using the Unix process management primitives.
You are given a dangerous program loony.cpp. The loony program is
rather unstable. Mostly it sleeps, but when it does wake up, it tries
to throw something at one
of it's siblings (with a Unix signal), after which
it may do something else deadly stupid (division by zero or
illegal memory reference). The assignment is to create a program
which manages a set of five loonies. Your program must create five
loony processes, each with its own name (pick any five names you like).
It then maintains a collection of five by replacing ones that die.
Your program reports each demise and its cause.
Your program should take a single number
on the command line and runs until it has started
that number of loonies.
It then waits for the existing five loonies to die and exits.
It then reports the number of creations and terminations, which should
be the same.
If the command-line parameter is omitted, create fifty loonies;
if the command line specifies less than 5, create five.
Here's what mine looks like:
[bennet@bennet whamo]$ loonybin 25
In the above, the lines starting with === are generated by
my solution (loonybin), and the other lines are generated by the
Sally throwing Interrupt at 25425
=== George (pid 25425): Signaled: Interrupt ===
Alice throwing Terminated at 25427
=== George (pid 25427): Signaled: Terminated ===
Frank throwing Quit at 25428
Frank exiting code 6.
=== Frank (pid 25422): Error exit code 6 ===
=== George (pid 25428): Signaled: Quit ===
Sally throwing Interrupt at 25423
=== Fred (pid 25423): Signaled: Interrupt ===
Frank throwing Quit at 25430
=== George (pid 25430): Signaled: Quit ===
=== Frank (pid 25429): Signaled: Floating point exception ===
Alice throwing Terminated at 25432
=== George (pid 25432): Signaled: Terminated ===
Frank throwing Terminated at 25431
=== Fred (pid 25431): Signaled: Terminated ===
Alice throwing Interrupt at 25433
Alice exiting code 0.
=== Alice (pid 25424): Normal exit ===
=== Frank (pid 25433): Signaled: Interrupt ===
George throwing Terminated at 25426
=== Sally (pid 25426): Signaled: Terminated ===
Fred throwing Terminated at 25437
=== Frank (pid 25437): Signaled: Terminated ===
=== Fred (pid 25435): Signaled: Segmentation fault ===
George throwing Quit at 25436
=== Alice (pid 25436): Signaled: Quit ===
Alice throwing Interrupt at 25441
=== Fred (pid 25441): Signaled: Interrupt ===
George throwing Quit at 25442
=== George (pid 25434): Signaled: Floating point exception ===
=== Alice (pid 25442): Signaled: Quit ===
Sally throwing Interrupt at 25444
=== George (pid 25444): Signaled: Interrupt ===
Sally exiting code 5.
=== Sally (pid 25438): Error exit code 5 ===
Frank throwing Quit at 25445
=== Alice (pid 25445): Signaled: Quit ===
Fred throwing Interrupt at 25440
=== Frank (pid 25440): Signaled: Interrupt ===
George throwing Interrupt at 25447
George exiting code 0.
=== Sally (pid 25447): Signaled: Interrupt ===
=== George (pid 25446): Normal exit ===
Fred exiting code 0.
=== Fred (pid 25443): Normal exit ===
=== 25 processes started. ===
=== 25 processes ended. ===
The loony.cpp program is given for download;
your assignment is to write the loonybin program.
You may solve the problem in plain C or C++. I used the later, but
the advantages over C for this program are minimal.
program shown in lecture provides an
example of using the Unix process creation calls, fork,
exec and wait.
You may find more information on them
using the Unix man command.
For instance, say man fork to learn about the fork call.
For many of these, you will need to give the section in the manual,
which is usually 2. For instance, man 2 wait. If it's not in 2,
try 3. Section two contains actual system calls, and three describes
library calls. Google can also find you copies of these pages online without
You may also find relevant information in books or online.
This is allowed, but if you use any external source you must
document it in a comment in your code. For books, give the author,
title, publisher and page number(s). For web pages, the URL.
Your program must do the following:
- Create five processes running the given loony program. Start each of
them with a different string name as a command-line argument. When you write
your program, you may choose any set of five different names you like.
For each process, you must execute a Unix fork followed by some
form of exec (probably execl) in the child process.
- Enter a loop which contains a wait call, probably
near the top of the body. This this will suspend
the caller until some child process terminates. When it returns, it reports
which process died, and what caused termination. You should
collect and print this information. The process can exit normally (code
zero), exit abnormally (non-zero code), or be killed (signaled) by any
of several signals.
Say which happened, and print the exit code number or the name of
the terminating signal.
See the wait man page for about recovering the status information, and
strsignal to print signal name.
- Figure out the name of the process which exited, and start a new one
with the same name. To do this, you will have to keep some sort of list
which remembers the name of each child process based on its process id.
Fork tells you the number of processes when they are created, so you
can enter the name into your table initially. The wait call tells
you the identifier of the process which ended, so you can look up its name.
- The wait call may return an error (-1 return code). The most
common reason for wait to return -1 is being called when
there are no child processes. Since you are to maintain a pool of
five processes and stop when they are done,
this will usually indicate that your program has a bug.
- Otherwise, any of the various process management calls may fail,
in which case you should print an error message an exit. The die
function in loony.cpp prints such a message. (You can't call it since you're
running a different process, but your welcome to swipe code.)
You should check each return value for failure,
usually indicated by a negative number.
- As noted above, you must extract a create count from the command line,
default 50, minimum 5. Your main loop must run until it has created that
specified number of loonies. Since you maintain a pool of five, you
will have five running at that time. Your program must continue to run
util these five have completed, and exit. Make sure you don't
accidentally start more loonies while you are waiting for the last
five to finish.
You will probably want to write this program incrementally, as
series of partial versions. You might start by writing a program
to create one
loony and simply wait for its demise. Then, modify this program to
correctly report the status of the loony's demise.
A third version might just start the five loonies and report each
demise. A fourth version might try to replace the processes
when they end.
Unfortunately, you probably won't be able to work directly
on a Mac, because it lacks the /proc file system that loony.cpp uses to
find its siblings. If anyone would can write a Mac version of
loony, that would be fine. Otherwise, you'll have to use Linux.
When your program works, and is properly commented and indented,
submit it over the web using