The purpose of this assignment is to help you learn about UNIX processes and inter-process communication. It will also give you ample opportunity to define software modules; in that sense the assignment is a capstone for the course.
A UNIX shell is a program that makes the facilities of the operating system available to interactive users. There are several popular UNIX shells: sh (the Bourne shell), csh (the C shell), and bash (the Bourne Again shell) are a few.
Your task in this assignment is to create a program named ish. ish should be a minimal but realistic interactive UNIX shell.
To facilitate your debugging and our testing, ish should print each line that it reads from .ishrc immediately after reading it. ish should print a percent sign and a space (% ) before each such line.
ish should terminate when the user types Control-D or exit.
The '<' token should indicate that the subsequent token is the name of a file. ish should redirect the command's standard input from that file. It should be an error to redirect a command's standard input more than once.
The '>' token should indicate that the subsequent token is the name of a file. ish should redirect the command's standard output to that file. If the file does not already exist, then ish should create it; if the file does already exist, then ish should destroy its contents and rewrite the file from scratch. ish should set the permissions of the new file to 0600. It should be an error to redirect a command's standard output more than once.
A pipeline should be a sequence of one or more commands separated by '|' tokens. ish should redirect the standard output of the command that precedes the '|' token to the standard input of the command that follows. It should acceptable to redirect the standard input of the first command of a pipeline via the '<' token; it should be erroneous to redirect the standard input of any other command of a pipeline via the '<' token. Similarly it should be acceptable to redirect the standard output of the last command of a pipeline via the '>' token; it should be erroneous to redirect the standard output of any other command of a pipeline via the '>' token.
If the command is an ish built-in, then ish should execute it directly (i.e. without forking a child process). ish should interpret four shell built-in commands:
setenv var [value] | If environment variable var does not exist, then ish should create it. ish should set the value of var to value, or to the empty string if value is omitted. Note: Initially, ish inherits environment variables from its parent. ish should be able to modify the value of an existing environment variable or create a new environment variable via the setenv command. ish should be able to set the value of any environment variable; but the only environment variable that it explicitly uses is HOME. |
unsetenv var | ish should destroy the environment variable var. |
cd [dir] | ish should change ish's working directory to dir, or to the HOME directory if dir is omitted. |
exit | ish should exit. |
Note that those built-in commands should neither read from standard input nor write to standard output. Thus ish need not support file redirection with its built-in commands. Nor does ish need to support built-in commands within pipelines.
If the command is not an ish built-in, then ish should consider the command-name to be the name of a file that contains executable binary code. ish should fork a child process and pass the filename, along with its arguments, to the execvp system call. If the attempt to execute the file fails, then ish should print an error message indicating the reason for the failure.
ish should print its prompt for the next standard input line only when all commands in the current pipeline have finished executing. If any command of a pipeline fails to execute, ish should simply let all of the other commands execute to completion.
ish should handle an erroneous line gracefully by rejecting the line and writing a descriptive error message to standard error. ish should handle all user errors; it should be impossible for the user's input to cause ish to crash.
ish should contain no memory leaks. For every call to malloc or calloc, eventually there should be a call to free.
ish need not support editing of the previously issued command.
Test ish by creating multiple files containing lines which ish should interpret, repeatedly copying each to the .ishrc file in your HOME directory, and restarting ish. The file /u/cos217/Assignment6/.ishrc contains a sequence of commands that can serve as a minimal test case.
Of course you also should test ish extensively by manually typing commands at its prompt.
A Supplementary Information page is available that lists detailed implementation requirements and recommendations.
Develop on hats. Use Emacs to create source code. Use the "make" tool to automate the build process. Use gdb to debug.
An executable version of the assignment solution is available in /u/cos217/Assignment6/sampleish. You should use it to resolve any issues concerning the desired functionality of ish.
You should submit:
Your readme file should contain:
/u/cos217/bin/i686/submit 6 makefile readme sourcecodefiles ishrcfiles
Note that we are not permitted to accept any work that is submitted after the Dean's Date.
Your work will be graded on correctness, understandability, design, and testing. An important aspect of design is proper modularity through the definition and use of interfaces and implementations. To encourage good coding practices, we will take off points based on warning messages during compilation.