|
Computer Science 432 Operating Systems Williams College Fall 2006
|
|
Lab 5: The Cow Shell
Due: 9:55 AM, Tuesday, October 31, 2006
After a few weeks of small labs while being distracted by Reading
Period and an exam, it's back to a bigger programming task.
For this lab, you are to write a C program called the Cow Shell (cowsh), a mini command shell interpreter. cowsh is similar to
familiar Unix shells such as the Bourne shell (sh) the
Bourne-Again shell (bash), and C shell (csh, tcsh). You
will learn about process creation, pipes, input/output redirection,
background process management, signals, and interrupt handling, and
gain extensive experience with C.
The program is designated a "team program" (groups of size 2 or 3
permitted) for honor code purposes. Collaboration within a group is,
of course, unrestricted. You may discuss the program with members of
other groups, but what you turn in must be your own group's work.
Groups must be formed no later than 9:00 AM, Monday, October 23, 2006, and be confirmed by
all group members by electronic mail to terescoj@cs.williams.edu. All group members will be assigned the
same grade for the lab. There are many subtasks that can be carved
off and assigned to group members, so everyone is encouraged to join a
group.
Like the Unix shells you use every day, cowsh should issue a prompt
(perhaps "cowsh#"), at which it reads commands from the user
and executes them.
Your shell should interpret the following commands and provide the
following functionality:
- exit: exit from the shell
- help: display a message listing usage of all commands
- Execute a command (program on disk). As in the shells you use,
the command should be located according to the PATH environment
variable Appropriate choice of exec function will help here.
The arguments following the command should be passed to the command.
For example,
cowsh# cat cat.c
should execute cat with one argument, cat.c
- Input and output redirection should be implemented.
For example,
cowsh# cat < cat.c > myfile.c
should cause the cat program to read from cat.c and write
to the file myfile.c.
cowsh# ls -l >> dirlistings.txt
should cause the output of ls -l to be appended to the end of the
existing file dirlistings.txt.
An individual command may only redirect input once and output once,
but those redirections may be specified in any order.
cowsh# > alines grep -i < Makefile a
should be interpreted the same as the more usual
cowsh# grep -i a < Makefile > alines
- Pipes should be implemented.
- Typing <ctrl-c> should abort a command being run, but not
cause cowsh to terminate.
- A list of commands separated by semicolons should be executed in
sequence.
- As with the familiar Unix shells, appending an & to the
end of your command line will execute the command in the background.
- jobs: Displays all the active background programs that
have been started from this shell, along with their ids. (This
id need not be that same as the actual process id. For example, it
could be the index into your process table).
cowsh# jobs
PID Name
[0] mycat < myfile.c > newfile.c
[1] sleep 20
[4] grep cowsh < doc | wc
- kill: Without any arguments, prints a usage statement:
cowsh# kill
Usage: kill <pid> [<pid> ...]
Otherwise it kills the processes with the specified ids and displays
the processes killed.
cowsh# kill 4
[4] "grep" Killed
cowsh# kill 3 7
[3] "cat" Killed
[7] "wc" Killed
- Implement a builtin cd command.
- Errors should be reported meaningfully.
- Additional functionality of your group's choosing should also be
implemented (see also the Submission and Evaluation section below).
Ideas for extra functionality include:
- command history: history command, !command, !!,
^
modification of previous command
- control structures in the shell (for, while, if)
- aliases
- user-specified prompts (as in bash, tcsh)
- More advanced redirection and pipes:
<<
, >&
, |&
- <ctrl-z> trapping and corresponding job control (fg, bg commands)
- Parenthesis-delimited subshells
See builtin(1) for more ideas.
- A similar project is described at the end of Chapter 3 of
SG&G. You may find some useful information and examples there.
- The system(3) system call is not to be used.
- The system calls that you should use are fork(2), a variant
of exec(3), signal(3), kill(2), open(2), dup2(2), close(2), pipe(2), and chdir(2).
- You may find the readline(3) and the strsep(3)
functions to be useful. readline(3) is part of the GNU
Readline Library and strsep(3) is in the Standard C Library.
- You may assume the builtin commands (exit, help,
jobs, kill) stand alone on a command line (no pipes, I/O
redirection).
- Use cowsh scripts to test your shell.
- A shell may run for a long time. Be careful about memory management.
- gcc's -Wall flag will report additional compiler
warnings. This can help you find some of the more subtle bugs that
are so common in C code before they have a chance to cause their
subtle problems. If you aren't absolutely certain that a given
warning is harmless, fix it!
- A verbose/debugging mode is essential for, well, debugging.
- Keep your code under source code control. You may wish to use
subversion to track your changes and to allow you to go back to
previously working code. If you're working in a group, this is even
more useful, allowing easier concurrent development. Group members
should request a Unix group for safe sharing of files.
- The following might be a good order to tackle the required functionality.
- exit and help commands
- run a command (with no argument passing, no redirection, no pipes)
- run a command with argument passing
- run a command with input and output redirection
- run a command in the background
- jobs command
- kill command
- <ctrl-c> trapping
- trapping termination of background processes
- pipes
;
- or &
-separated commands
- cd command
- extra functionality
- /usr/cs-local/share/cs432/shell/cowsh
contains my version of cowsh.
All necessary files should be submitted using turnin as a
single "tar" file, lab5.tar. Include a Makefile to
allow easy compilation of the Cow Shell program.
I will compile and test your shell programs on CSLab FreeBSD systems.
Your program will be graded based on a total of 50 points.
- 6 points for documentation. Your code should
be commented appropriately throughout. Please also include a longer
comment at the top of your program describing your implementation.
This documentation should list your important design decisions, the
assumptions that you made (if any), the additional functionality
implemented, and any other relevant information.
- 1 point for a functional Makefile.
- 1 point for implementing the exit and help commands.
- 4 points for running a command with no arguments.
- 4 points for running a command with arguments.
- 4 points for running a command with input/output redirection.
- 4 points for launching a command in the background.
- 4 points for launching a sequence of jobs separated by
;
's or &
's.
- 2 points for the jobs command.
- 2 points for the kill command.
- 2 points for correctly trapping the <ctrl-c> keystroke.
- 3 points for reporting termination of backgrounded jobs.
- 4 points for a pipeline of two processes.
- 3 points for an arbitrarily long pipeline of processes.
- 1 point for a builtin cd command.
- Up to 5 points for extra functionality.
- 1-point enhancements: aliases, more
advanced redirection and pipes:
<<
, >&
, |&
,
user-specified prompts.
- 2-point enhancements: command history, control structures in
the shell (for, while, if), modification of
previous command with
^
.
- 3-point enhancements: <ctrl-z> trapping and corresponding
job control (fg, bg commands).
- Please ask about other possible enhancements. Point values
will be based on level of difficulty.
Penalties may be applied for poor design choices, poor formatting of
code, poor programming style, or if your program compiles with
warnings (when using gcc -Wall).
Have fun and good luck!