CAS CS 552
Programming Assignment 1
Due: September 21, 1999
The purpose of this assignment is to introduce you to Java programming.
You are to implement a simple shell (command interpreter) that behaves
similarly (but not identically) to the UNIX shell. When you type in a command
(in response to its prompt), it will create a thread that will execute
the command you entered. Multiple commands can be entered on a single line,
separated by `&' (ampersand) characters. Your shell will create a thread
for each individual command and prompt for more user input when they have
Unlike the real shell, your program doesn't have to know how to run
arbitrary programs, only the following ``built-in'' commands. On the other
hand, you will have to implement these commands in Java rather than using
standard Unix utilities.
You do not need to implement pipes or re-direction of standard input and
standard output, but you must be able to handle an arbitrary number of
commands per line -- each with an arbitrary number of arguments separated
by arbitrary amounts of white space (blanks or tabs). Only cat may
take more than two arguments, but your program must gracefully recover
from such errors as unknown commands, wrong number of arguments, or non-existent
files by printing an error message and continuing.
|cat file ...
||Print the contents of the named files to System.out one after
|cmp file1 file2
||Check whether the two files have identical contents and print an appropriate
message to System.out.
||Print the lines of file in sorted (lexicographic) order.
||Terminate the program. You should also terminate on reaching end-of-file
This project is not as hard as it may seem at first reading, because most
of the hard parts have already been done for you by the standard Java library.
It involves finding the relevant library routines and calling them properly.
Your finished program will probably be under 200 lines, including comments.
Your public static void main() procedure in your primary class
will be quite simple. It will be an infinite loop that prints a prompt,
reads a line (in other courses, a program with an infinite loop is considered
a bad thing, but in Operating systems, it's the norm!), parses it (breaks
it up into its constituent commands), starts a new thread to handle each
of the different commands, and then waits for all the threads to finish
before printing the next prompt.
You should find Marvin Solomon's note on Java
for C++ Programmers useful.
For parsing, you may find it easier to read the entire line into a String
object. The stream
object, which gets the keyboard input, is of type
so it can read either single bytes or arrays of bytes. You could represent
an input line as an array of bytes, but you will find it much easier to
instead. You may want to look into the class
to figure out how to read a line into a String. Tokenizing a String is
made almost trivial using the
class found in
For the cat command, you should look at the class FileInputStream
to see how to read data from a file. The cmp command will be similar
to cat, but this time the contents of the two files will be compared, line
by line. You probably want to wrap the FileInputStream
for this. For sort, an efficient sorting algorithm is not required;
anything that works is ok. You might want to adapt the insertion sort
used in the
Java for C++ Programmers
note. Some of the classes that might help you here are BufferedReader
Your primary class will read a command line from a user and then will create
threads to carry out the commands on the line. It will then wait until
the threads have finished before continuing its own execution. There are
two ways to start threads in Java. The first is to derive your class from
class and then override its run() function (see pp. 181-182 in
Java book). The second is to use the
interface (pp. 201-202). With this approach, you create a class that
Runnable and pass an instance of this class into the constructor
of a new thread object. Using the second approach is recommended.
Java requires you to place within a try
block any methods that might cause an exception. Following the try block
is a catch clause (or catch clauses)
that will be used to catch any exceptions that have been thrown. See Java
for C++ Programmers and Chapter 7 of the Java book for more information
about exceptions. Your code should deal with exceptions in an appropriate
manner. For example, exceptions such as attempting to open a file that
does not exist should result in a message to the user and the continuation
of the program. More serious exceptions may require an error message followed
by program termination (using
Note: This project must be done individually. The
remaining Java projects will be done in teams of two.
Hand in your source program and a transcript of a terminal session which
demonstrates your shell's ability to perform as specified; see the UNIX
command script(1): Simply type the command "script". You will
see the message
Script started, file is typescript
After that, everything you type in and everything sent to the screen
will be saved in the file "typescript". When you are done with your demo,
type "exit" (to the UNIX shell, not to your program!), and you should get
Script done, file is typescript
Submit all your .java source files, the typescript file and
any other required files. Do not submit any .class files. Be sure
that you use test data adequate to exercise your program's capabilities.
You should follow all the principles of software engineering you learned
in CS 112 and CS 113, including top-down design, good indentation, meaningful
variable names, modularity, and helpful comments. You will be graded not
only on the basis of correctness, but also programming style and completeness
of test data.
for electronic submissions of programming assignments.
CAS CS 552 home page