------------------------------------------------------------------------------
MC logo
CSc 422 Assignment 2
[^] CSc 422 Home
------------------------------------------------------------------------------
[CSc 422 Assignment 1] [CSc 422 Assignment 2] [CSc 422 Assignment 3] [CSc 422 Assignment 4]
[The Loony Program]

Inmates Running the Asylum

Assigned
Due
Sept 21
Oct 13
90 pts

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
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. ===
[bennet@bennet whamo]$
In the above, the lines starting with === are generated by my solution (loonybin), and the other lines are generated by the loonies themselves.

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.

The runner.cpp 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 much trouble.

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.

Specific Requirements

Your program must do the following:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.

Submission

When your program works, and is properly commented and indented, submit it over the web using this form.