This project was done for CS 3013: Operating Systems. The goal of this project is to introduce students to the process manipulation facilities in GNU/Linux operating systems.

For the project I wrote a C program called doit, which takes another command as an argument and executes that command. For example, executing:

./doit wc foo.txt

would invoke the wc ("word count") command with an argument of foo.txt, which will output the number of lines, words, and bytes in the file foo.txt. After execution of the specified command has completed, doit displays statistics that show some of the system resources the command used. In particular it shows:

  1. the amount of CPU time used (both user and system time) in milliseconds,
  2. the elapsed "wall-clock" time for the command to execute in milliseconds,
  3. the number of times the process was preempted involuntarily (e.g. the time slice expired, preemption by higher priority process),
  4. the number of times the process gave up the CPU voluntarily (e.g. waiting for a resource),
  5. the number of major page faults, which require disk I/O,
  6. the number of minor page faults, which could be satisfied by reclaiming memory,
  7. the maximum resident set size used, in kilobytes.

Every time doit is called, it forks off a child process to run the input command, with the parent process collecting statistics while it waits for the child to finish execution. When the child exits the parent prints out the above statistics to the command line.

Shell Mode

doit also has the ability to act as a shell. Calling doit with no command line arguments will engage shell mode, and prompt the user with the default prompt string of ==>. You can enter commands into this shell just as you would with a regular GNU/Linux shell, with the exception that the doit shell will also print the same usage statistics for every command executed on it.

Shell mode has four built-in commands. These are:

Each line of input may not contain more than 128 characters or more than 32 distinct arguments.

Shell mode also supports background tasks, indicated by putting an ampersand ('&') character at the end of an input line. When a task runs in the background the shell does not wait for the task to complete, but instead immediately prompts the user for a new command. Note that any output from the background command will intermingle with output from the shell and other commands.

When the shell receives an exit command, it waits for each running background process to complete, then exits gracefully.