Operating Systems--Spring 2011

    Home | | Schedule | | Assignments | | Notes

    Project 2: Processes

    Part B: Writing a Shell Program

    Part B checkpoint due: Monday, Feb 28 (see below)
    Full Project Due date: Thursday, Mar 3

    Suppose you work for a company that is in the process of creating the ULTIMATE Operating System (UOS). One goal of this OS is to provide different shells for the users, some of which will offer numerous functionality and others that will not. You are in charge of developing the tiny shell (tsh). In order to complete your task, you'll need to become familiar with input/output redirection, fork, exec, pipes, and environment variables. Your tsh needs to be written in C++, and the source code should be placed in a file named tshell.cc.

    The basic ground rules for the development of your tsh is that your program cannot exec (any variant) the sh program. In other words, your tsh must be stand alone; it can not rely upon another shell to function, Thus, YOUR program (and not some other program) must manipulate the file descriptors, set up and break down the pipes, etc. Your boss for UOS wants to ensure your code can handle the following capabilities:

    1. Redirecting input: myprog < myinput
    2. Redirecting output: myprog > myoutput
    3. Appending redirected output: myprog >> myoutput
    4. A pipe between two commands: ls -l | grep root

    In addition, your boss for UOS wants your tsh to be implemented in the following manner:

    1. Use the execvp variant of exec.
    2. The prompt of tsh should be set to ''tsh.'' concatenated with the current working directory. For example:

        tsh./home/fac/lking>

      The current value of the working directoryis obtained through getenv. For example:

        getenv("PWD")

      will return a pointer to a string containing the current working directory.

    As in most shells, the valid input to tsh will consist of, from left to right, the commands to be executed along with their parameters connected by pipe symbols, with any I/O redirection occurring on the far right of the line. I/O redirection can occur in either order. For example, either

    grep fork | wc -l < infile >> report
    or
    grep fork | wc -l >> report < infile

    should produce the same result. You should assume that any input file redirection is for the first command and any output file redirection is for the last command.

    You don't have to do any error checking. Error handling is an important part of any program that will be widely used; however, it adds substantially to the complexity of the program. Thus, your boss wants the first draft (i.e., what is submitted) of your tsh without any error handling. In other words, your tiny shell will only be tested with valid input.

    The commands listed above are only to illustrate how your tsh should function. While not needed to develop your tiny shell, you are welcome to read the manual pages on any of the above commands that are unfamiliar. You should, however, check out the manual pages for the following commands: waitpid, dup, open, and close.

    The parser
    To help you with your program, you are provided with a Parser class, written by Nick Bauer at the Colorado School of Mines, that will take a command line and divide it up into its relevant components. The Parser class is contained in the files:

      parser.h
      parser.cc

    You may copy these files from the directory ~csci346/projects/project2. You should study the description of the Parser class in parser.h and examine the data available to you in this class. Briefly, the Parser class provides a method,

      ParseLine(char *commandLine)

    that takes a command line string and parses it into its component commands (up to 10, but you will only need 2) and any input or output redirection (including a boolean to indicate if the output should be appended or not to the output file), and the input and output file names (if any). It also has a flag to indicate whether the command line should be run in the background. Commands are stored in an array of structs (type: CommandLine). Each struct has the name of the command, a list of arguments for that command (args), and the number of arguments. Note that the command name is the first argument in the list, so args can be used like argv (very useful when using execvp). Finally, numCommands gives the total number of commands minus 1 (i.e. if there is 1 command in the line, numCommands is 0).

    Miscellaneous Notes

    • To receive a high grade on this programming assignment, you must submit a program that is correct and has good design and style.
    • In the notes for lecture 6, there is pseudocode on how a shell functions.
    • Redirection of file I/O and LINUX pipes were covered in lecture 7. Use your notes from lecture 7 and read the handout (up through example six), "An Introduction to Concurrency in Unix-based C Through Annotated Examples", by Henry M. Walker. Lastly, please note that multiple program statements are need to do the task of redirect I/O and to establish pipes.

    Turning in your project:

    Checkpoint:
    • You are required to submit a version of tshell.cc that executes single commands with arguments (but does not necessarily redirect input or output or deal with pipes) on Monday, February 28.
      • Submit the soft copy of your tshell.cc files by typing:
        ~csci346/bin/submit csci346 project2Bcheck
      • Turn in a printout of tshell.cc.
    • The simple version of tshell.cc (without I/O redirection or pipes) will be checked but not officially graded. There will be a deduction on your overall grade if you do not turn in the checkpoint file.

    Completed project:

    • Turn in your completed project, tshell.cc by typing:
      ~csci346/bin/submit csci346 project2B
    • Turn in a printout of tshell.cc on the project due date.


    Home | | Schedule | | Assignments | | Notes



    Computer Science 346--Operating Systems
    Last Modified: February 18, 2011
    Page Expires: January 22, 2012