Due Monday, September 30th at 10:00 P.M.
Please submit your code by the deadline on royal
/Shared/cs322/submit/proj1
Include your *.c files in a directory named with your two first names and
include a readme with
- your names at the top,
- the command to run your code, and
- known issues.
Context
On Linux systems the command pstree displays running processes
as a tree. An example is below
ecdfourq@bivector:~$ pstree -aG
init
+-NetworkManager
+-acpid -c /etc/acpi/events -s /var/run/acpid.socket
+-apache2 -k start
| +-apache2 -k start
| +-apache2 -k start
| +-apache2 -k start
| +-apache2 -k start
| +-apache2 -k start
+-atd
+-automount
| +-2*[{automount}]
+-avahi-daemon
| +-avahi-daemon
+-console-kit-dae --no-daemon
| +-63*[{console-kit-da}]
+-cron
+-cupsd -C /etc/cups/cupsd.conf
+-dbus-daemon --system --fork
+-exim4 -bd -q30m
+-getty -8 38400 tty4
+-getty -8 38400 tty5
+-getty -8 38400 tty2
+-getty -8 38400 tty3
+-getty -8 38400 tty6
+-getty -8 38400 tty1
+-modem-manager
+-mysqld
| +-13*[{mysqld}]
+-portmap
+-rpc.statd -L
+-rsyslogd -c4
| +-2*[{rsyslogd}]
+-sshd -D
| +-sshd
| | +-sshd
| | +-ksh
| +-sshd
| +-sshd
| +-ksh
| +-pstree -aG
+-udevd --daemon
| +-udevd --daemon
| +-udevd --daemon
+-upstart-udev-br --daemon
+-winbindd
| +-winbindd
+-wpa_supplicant -u -s
+-ypbind -no-dbus
| +-2*[{ypbind}]
+-zmdc.pl -wT /usr/bin/zmdc.pl startup
+-zmaudit.pl -wT /usr/bin/zmaudit.pl -c
+-zmfilter.pl -wT /usr/bin/zmfilter.pl
+-zmwatch.pl -wT /usr/bin/zmwatch.pl
In this project you will write a C program that creates a
binary tree of Unix processes and prints the binary tree as it is
created.
The processes are only fork() calls,
not followed by a call to functions of the exce() family.
Description
Write a program processtree.c that takes a single command-line
parameter specifiying the height of the binary process tree. Each
process should be assigned a traversal number, which corresponds to
its position in a level-order traversal of the tree.
Given a height of 3, the tree can be thought of as this binary tree, where
the parent-child links are not explicitly stored by your program but are
part of the Unix process hierarchy.
While the graphical representation would look like this:
your program's processes should print out the information about the tree, as follows:
> ./processtree 3
[1] pid 81142, ppid 48569
[1] pid 81142 created left child with pid 81143
[1] pid 81142 created right child with pid 81144
[2] pid 81143, ppid 81142
[3] pid 81144, ppid 81142
[2] pid 81143 created left child with pid 81145
[3] pid 81144 created left child with pid 81146
[3] pid 81144 created right child with pid 81147
[4] pid 81145, ppid 81143
[2] pid 81143 created right child with pid 81148
[6] pid 81146, ppid 81144
[7] pid 81147, ppid 81144
[5] pid 81148, ppid 81143
[3] right child 81147 of 81144 exited with status 7
[3] left child 81146 of 81144 exited with status 6
[2] right child 81148 of 81143 exited with status 5
[2] left child 81145 of 81143 exited with status 4
[1] right child 81144 of 81142 exited with status 3
[1] left child 81143 of 81142 exited with status 2
To obtain this result, your program's processes should produce output in the following
format.
- When a process is created, it should print
- its traversal position,
- its pid (process ID) obtained using getpid(2) and
- its ppid (parent process ID) obtained using getppid(2).
- After a process spawns a child process, it prints its own (not the new child's)
traversal number, its own pid, and the pid of the newly-spawned child along with an
indication of whether this child forms its "left" or "right" subtree.
- When a child exits (using exit(3)), it prints its traversal number as its exit
status. This value is obtained by the parent when it calls waitpid(2) and printed
along with the parent's traversal number, whether the terminated child is a left or right subtree,
the parent's pid, the terminated child's pid and the exit status, which should be the child's
traversal number.
Two additional requirements are that each line of output
- is indented according to the depth of the node in the process tree and
- begins by printing the traversal number of the process that prints it.
Important Notes
- To create easy to understand output you need some
constraints on the order of process execution. This is most easily provided
using calls to sleep(3).
- Do NOT use shared memory. Getting a correct program while doing
so is hard.
- Develop and test this program step-by-step. The executing program has a good chance of becoming a "fork bomb".
To reduce the chance/probabiltiy of this happening, you should check the return value of your fork()
calls and stop if it returns -1, which indicates that you were unable to spawn a process.
- Use small trees when debugging. Try larger tree sizes later,
once you're confident that your program is working. Find out how large a tree you need to
exhaust the available processes. Experimenting in a way that may exhaust the number of processes
can be dangereous. Check your system or ask the system admin to know whether accounts
have restricted numbers of preocesses, and that the limit is much smaller
than the process table. If you dare to do it on your system report your finding
in your readme file for some bonus points.
Grading
This project is graded out of 20 points.
Correct number of levels created
4
Correct total number of processes created
2
Correct usage of fork system call including error checks
4
Correct usage of waitpid system call
2
Correct printing of child exit status in parent
1
Sleep between successive levels
1
Traversal order labels
3
Indentation based on tree level
3