EECS 678 - Quash Shell

Introduction

In this project, you will complete the Quite a Shell (quash) program from scratch using techniques you have learned so far. You may work in groups of 2 or individually. The learning goals of this project are as follows:

Quash should behave similar to csh, bash or other popular shell programs.

You must use C, C++, Rust, or Go to implement this project.

Features

The following features should be implemented in Quash:

[QUASH]$ program1 &
Background job started: [1] 2342 program1 &
[QUASH]$ ls
Documents Downloads
Completed: [1] 2342 program1 &
[QUASH]$ echo Hello Quash! > a.txt # Write "Hello Quash!\n" to a file
[QUASH]$ cat a.txt
Hello Quash!
[QUASH]$ echo Hey Quash! > a.txt # Trucates/overwrites a.txt contents
[QUASH]$ cat a.txt # Print file contents
Hey Quash!
[QUASH]$ cat < a.txt # Make cat read from a.txt via standard in
Hey Quash!
[QUASH]$ cat < a.txt > b.txt # Multiple redirect. Read from a.txt and write to b.txt.
[QUASH]$ cat b.txt
Hey Quash!
[QUASH]$ cat a.txt >> b.txt # Append output of a.txt to b.txt
[QUASH]$ cat b.txt
Hey Quash!
Hey Quash!
[QUASH]$
[QUASH]$ cat src/quash.c | grep running
// Check if loop is running
bool is_running() {
return state.running;
state.running = false;
while (is_running()) {
[QUASH]$ cat src/quash.c | grep running | grep return
return state.running;
[QUASH]$ echo "hello world" # this is a comment
hello world
[QUASH]$ # this is another comment -> Quash does nothing
[QUASH]$

Built-in Functions

All built-in commands should be implemented in quash itself. They cannot be external programs of any kind. Quash should support the following built-in functions:

[QUASH]$ echo Hello world! 'How are you today?'
Hello world! How are you today?
[QUASH]$ echo $HOME/Development
/home/jrobinson/Development
[QUASH]$ echo "Double quoted string" 12345
Double quoted string 12345
[QUASH]$
[QUASH]$ export PATH=/usr/bin:/bin # Set the PATH environment variable
[QUASH]$ echo $PATH # Print the current value of PATH
/usr/bin:/bin
[QUASH]$ echo $HOME
/home/jrobinson
[QUASH]$ export PATH=$HOME # Set the PATH environment variable to the value of HOME
[QUASH]$ echo $PATH # Print the current value of PATH
/home/jrobinson
[QUASH]$
[QUASH]$ echo $PWD
/home/jrobinson
[QUASH]$ cd .. # Go up one directory
[QUASH]$ echo $PWD
/home
[QUASH]$ cd $HOME # Go to path in the HOME environment variable
/home/jrobinson
[QUASH]$
[QUASH]$ pwd # Print the working directory
/home/jrobinson
[QUASH]$ echo $PWD # Print the PWD environment variable
/home/jrobinson
[QUASH]$ export PWD=/usr # Change the PWD environment variable
[QUASH]$ pwd
/home/jrobinson
[QUASH]$ echo $PWD
/usr
[QUASH]$
[BASH]$ ./quash
Welcome...
[QUASH]$ exit
[BASH]$ ./quash
Welcome...
[QUASH]$ quit
[BASH]$
[QUASH]$ find -type f | grep '*.c' > out.txt &
Background job started: [1] 2342 find / -type f | grep '*.c' > out.txt &
[QUASH]$ sleep 15 &
Background job started: [2] 2343 sleep 15 &
[QUASH]$ jobs # List currently running background jobs
[1] 2342 find / -type f | grep '*.c' > out.txt &
[2] 2343 sleep 15 &
[QUASH]$
[QUASH]$ sleep 100 &
Background job started: [1] 4071 sleep 100 &
[QUASH]$ kill 2 4071 # send SIGINT signal to PID 4071
[QUASH]$ jobs # the process was terminated => no output
[QUASH]$

Useful System Calls and Library Functions

The following is a list and brief description of some system calls and library functions you may want to use and their respective man page entries. Note that this list may not be exhaustive, but be sure what ever library functions you use will run on the lab machines:

You may NOT use the system(3) function anywhere in your project.

Project Hints and Comments

In Quash, a job is defined as a single command or a list of commands separated by pipes. For example the following are each one job:

cat file.txt # A job with a single process running under it
find | grep *.qsh # A job with two processes running under it

A job may contain more than one process and should have a unique id for the current list of jobs in Quash, a knowledge of all of the pids for processes that run under it, and an expanded string depicting what was typed in on the command line to create that job. When passing the pid to the various print job functions you just need to give one pid associated with the job. The job id should also be assigned in a similar manner as bash assigns them. That is the job id of a new background job is one greater than the maximum job id in the background job list. Experiment with background jobs in Bash for more details on the id assignment.

Grading Policy

Partial credit will be given for incomplete programs. However, a program that cannot compile will get 0 points. The feature tests are placed into multiple tiers of completeness. The output to standard out from your code must match our output exactly, except for whitespace, for the next tier of grading to be accessible. This is due to reliance of previous tiers in subsequent tier tests. If we cannot run your code in one tier then it becomes far more difficult test later tiers. The point breakdown for features is below:

Description Score
  • Tier 0
    • Quash compiles
10%
  • Tier 1
    • Single commands without arguments (ls)
    • Simple built-in commands
      • pwd
      • echo with a single argument
30%
  • Tier 2
    • Single commands with arguments (ls -a /)
    • Built-in commands
      • echo with multiple arguments
      • cd
      • export
    • Environment Variables
      • echo with environment variables (echo $HOME)
      • Execution with environment variables (du -H $PWD/..)
30%
  • Tier 3
    • Built-in commands
      • jobs
      • kill
    • Piping output between one command and another (find -type f | grep '*.c')
    • Redirect standard input to any command from file (cat < a.txt)
    • Redirect standard output from a command to a file (cat b.txt > a.txt)
    • Background processes
      • Job completion notification
30%
  • Tier 4 (extra credit)
    • Pipes and redirects can be mixed (cat < a.txt | grep -o World | cat > b.txt)
    • Pipes and redirects work with built-in commands
    • Append redirection (cat a.txt | grep -o World >> b.txt)
10%
  • Valgrind Memory Errors
    • While not ideal, you will not lose any points for "still reachable" blocks
    • Unacceptable Memory Leaks
      • Definately lost
      • Indirectly lost
      • Possibly lost
    • Unacceptable Access Violations
      • Invalid Read
      • Invalid Write
      • Invalid free
      • Use of uninitialized values
-5% from tier grade down to 0% for each tier with violations

Submission

The project is due October 24th, 11:59 PM.

Each group (or individual) should submit the project via Canvas. The following will be expected in your deliverables:

Create a tar.gz archive of your deliverables. The TA should be able to run make quash to build your quash executable and then run ./quash to execute your program. Ensure your code compiles and executes on the EECS cycle servers (if C/C++).

Good Luck!