CS 232 Homework04: A Command Shell


A shell is a program that repeatedly:

Your task in this 2-person group assignment is to write your own xyshell program, where x and y are the first initials of the people in your group.

(For more information about job control -- which you don't have to do except to support starting a program in the background -- watch this short 5 minute video.)


This project is to write an object-oriented C++ shell program. Each non-trivial object in the project should be written as a class. Your driver program for the project should be no more complicated than this:

   #include "XYShell.h"

   int main()
      XYShell myShell;
One possible breakdown of the functionality is as follows: You should feel free to create other classes as you need them. You may also define additional methods in each of these classes. Methods that define messages to be sent to class objects should be implemented as public methods; methods used to define class utilities or break a big method into more manageable pieces should be defined as private methods. Stylistically, no method should be more than a half-page in length (10 lines in length would be even better). Remember: Any class that allocates memory dynamically should provide a destructor to reclaim that memory, to avoid leaking memory.

To execute system programs, your shell should use the fork(), waitpid(), and execve() system calls: The fork() call clones the current process to create a child process that is a complete copy of its parent. The child process should then use execve() to execute the user's command.

If no ampersand has been given on the command-line, the parent should use waitpid() to wait until the child terminates; otherwise (an ampersand was given, indicating the command was to be run in the background), it should return to the top of its loop, prompt the user, and await their next command. You may also find the sched_yield() system call to be useful in synchronizing the parent and child processes.

You should read the UNIX manual pages (section 2) for the details of the various system calls listed above, especially what header files must be #include-d to use them. There are also may be WWW tutorials/examples available that you may find useful.

To illustrate:

   $ ./xyshell
should run your shell, which then displays its prompt and awaits a user command:
When the user types a command, the program should perform that command and then prompt for the next one:
   /home/vtn2/proj/shell$ ps
     PID TTY          TIME CMD
     2208 pts/2    00:00:00 bash
     2428 pts/2    00:00:00 xyshell
     2485 pts/2    00:00:00 ps
If the user types a command with an ampersand, the program should not wait before prompting for the next command:
   /home/vtn2/proj/shell$ ps &
     PID TTY          TIME CMD
     2208 pts/2    00:00:00 bash
     2428 pts/2    00:00:00 xyshell
     2485 pts/2    00:00:00 ps

Those doing the course for honors:.

Design and build an Environment class that captures your shell's environment, so that you can run X-Window programs. When your child process invokes execve(), send your Environment class a message that returns a char** vector containing the enviroment, and pass that vector as the third argument to execve().

Plan of Action.

0. Divide the work between you and your partner. One person should be responsible for the CommandLine class and the other should be responsible for the Path and Prompt classes. You should aim to have these classes done at the end of the first week. You should work together the second week to build your XYShell class integrating the other classes.

1. The person building CommandLine should read up on argc and argv (these are covered in C++ An Introduction to Computing most C books, and a number of on-line sites), as well as the system calls that are useful for this class. Then implement the class.

2. The person building the Path class should read up on the system calls it uses. Then implement the class. Then do the same for the Prompt class.

3. Together, read up on fork(), execve(), and waitpid(). Design the algorithm for your run() method; then build your XYShell class (replacing X andY with your initials). cd, exit, and pwd are the only built-in shell commands your shell needs to recognize.

Feel free to discuss the project, the Unix manual pages, and the system calls with myself or your classmates. You are not to look at anyone else's source code.

Your program should be reasonably efficient in terms of its use of both time and space. It should also be fully documented, with an opening (header) comment that gives all of the usual information (who, what, where, when, and why), descriptive identifiers, judicious use of white space, and in-line comments explaining any 'tricky' parts. Write hospitable code -- code that someone else is comfortable reading. Indent perfectly. Beauty counts!

Turn in:

Use the program script to create a file in which you exercise your program as necessary to show its functionality (e.g., ls, cd .., pwd, ls -a, ls -l /home/cs/, pwd, ps -ax &, ..., followed by exit). Include at least one invalid command to show that your program handles such commands gracefully.

Submit 3 things to /home/cs/232/current/<yourid>/homework04/:

Only one of the partners in the group needs to turn in their submission, but make sure your login-ids and names are in the grading.txt file and in a comment in each submitted file.

Due date: Wednesday, Mar. 7, 11:59:59.999 p.m.

This page maintained by Victor Norman.