CS 405  Fall 2000
Project 1
Introduction to OS and Threads

Assigned: Monday, September 11, 2000            Due: Monday, September 25, 2000

Overview

You are to implement a simple command interpreter that simulates the behavior of a Unix shell. Basically your shell will do the following until the command to exit is entered.

Command Line Input

In response to the prompt, a user may enter one or more commands on a single line (before hitting return). Multiple commands must be separated by a semi-colon.

Commands

The good news is that your shell need only handle the commands listed in this section. The bad news is that instead of calling Unix utilities to do the "work" of these commands, you will have to implement them in Java.

cat file1 file2 .... fileN           Print the contents of the named files (in order of their appearance on
                                                the command line) to Console.out.

cmp file1 file2                       Print an appropriate message to indicate whether file1 and file2 have
                                               identical contents.

sort file1                                Print the lines of the file in sorted (lexicographic) order. You may
                                               assume that the file has a maximum of 1000 lines.

exit                                        Terminate the program. If an exit command appears on the same
                                              command-line with any other commands, the program should not
                                              exit until all preceding commands on the line have finished execution.

Error Handling

You are not required to handle Unix redirects or pipes or anything fancy. You are required to recover gracefully from errors such as an unknown command, the wrong number of arguments, or a non-existent file. You are also required to handle arbitrary amounts of white space between commands, arguments, and command separators.

Threads

We will study threads and processes in detail during the next few weeks. For now, view threads as a mechanism for having several "activities" in your program simultaneously (concurrently) executing.   (See Section 5.6.1.)

There are two ways to create threads in Java. We will use the second way specified in the online documentation for the Thread class (java.lang). To create a thread, you declare a class that implements the Runnable interface as shown below in Example 1. In addition to any other methods in the class, the run method must also be defined for the class.

Example 1

public class Command implements Runnable {

   private String theCommand;

   public Command (String c) {
       theCommand = c;
   }

   public void run () {
      // code to handle what the command says to do
   }

}

An instance of the above class can then be allocated, and passed as an argument when creating the thread and starting it as shown below in Example 2.

Example 2

Thread t = new Thread(command);     //create a new thread t
t.start();  // Thread t starts to execute, while the program does other stuff

// Do other stuff which may include creating and starting other threads

// Later in the program we do the following
t.join();   // wait for thread t to finish executing

Note that in Example 2, command is assumed to be an instance of the class Command. It satisfies the requirement for threads of being an instance of a class which implements Runnable. When t.start() is called thread t "runs a command" by calling the run() method.

Main Program Loop

To get you going, I've included a rough pseudo-code draft for code in your main program loop. This should be in a class separate from Command and need not implement the Runnable interface.

   while (true) {
      output the prompt;
      read entire command line into a string;
      int numberOfCommands = ?   //How many on this line
      /* Create array to hold that many threads */
      Thread t[] = new Thread[numberOfCommands];
      for (int i=0; i<numberOfCommands; i++) {
         String c = // set this to the next command
         /* Create thread and store in array */
         t[i] = new Thread(new Command(c));
         t[i].start();   //Fire the next thread off to execute c
      }

      /* Wait for threads to finish before prompting again */
      for (int i=0; i<numberOfCommands; i++) {
         t[i].join();
      }
   }