Processes (proc) Project
COP-3402
Table of Contents
1. Overview
In this project, you will develop a simple version of a command-line shell that can invoke programs and perform redirection and piping.
2. Input
USAGE: ./mysh
The program should be called mysh
. It takes no arguments. When running it prompts the user with "$ " (a single dollar-sign followed by a space with no newline character) and waits for input from stdin. If the command is successful, it prompts the user again for a command. The shell terminates when it has no more input or there is an error.
The prompt takes a list of space-delimited tokens, where the first is the program name and the rest are either arguments to the program or a redirection specification.
Use printf("$ ")
to prompt the user.
See the class notes for an example of reading in input for the shell.
You can use execvp
instead of execve
, so that you don't have to do path lookups for the program binaries.
You can use the following to wait until there are no more child processes:
do { while (wait(NULL) > 0); } while (errno != ECHILD);
2.1. Redirection
Redirection works by prefixing (with no additional space!) the name of a file with <
to redirect standard input and/or >
to redirect standard output. (There is no need to support stderr.) There should only be one redirection of each kind at most. The redirection will be after arguments.
2.2. Piping
Piping works by putting a pipe symbol between two commands. Only a single pipe is required to be supported. It is an error if redirection of standard out is used with piping of the left command or in redirection of standard in is used with piping of the left command.
2.3. Example
Redirection
$ ls >out.txt
Notice the lack of a space betwen >
and out.txt
. This lack of space is required.
Piping
ls / | wc
Notice that the programs can still take arguments
Piping and redirection
3. Input validation
Report errors via exit codes passed to the exit
library call, e.g., exit(EXIT_FAILURE)
terminates the program with exit code 5
.
Error messages are optional, but should only be written to stderr, not to stdout, which will be used for program output, i.e., use fprintf(stderr, ...)
instead of printf
.
All syscall should have error checking. If one fails, you can ignore the entire command given and continue to the next prompt or just exit th program.
No erroneous commands will be used as tested.
Error |
---|
Multiple input redirects |
Input redirect is empty |
Multiple output redirects |
Output redirect is empty |
Input redirect file cannot be opened |
Output redirect file cannot be opened |
Redirected standard out of left pipe program |
Redirected standard in of right pipe program |
Standard input cannot be redirected |
Standard output cannot be redirected |
Program cannot be executed |
4. System call and library references
Do not use helper libraries or other simplified calls to achieve similar results as functions below. Just use the syscalls below for these aspects of the project.
Symbol | Reference | Reading |
---|---|---|
fork() | man 3 fork |
LPI 24 |
wait() | man 2 wait |
LPI 24 |
execvp() | man 3 execvp |
LPI 27 |
pipe() | man 2 pipe |
LPI 44.2 |
dup2() | man 2 close |
LPI 44.4 |
open() | man 2 open |
LPI 4.1 |
close() | man 2 close |
LPI 4.1 |
perror() | man 3 perror |
LPI 3.4 |
exit() | man 3 exit |
LPI 25 |
_exit() | man 2 exit |
LPI 25 |
man
is the command-line manual.- LPS is The Linux Program Interface book.
- Knowledge of memory management and string processing is assumed.
4.1. Headers to include
#include <stdio.h> #include <unistd.h> // fork() #include <stdlib.h> // exit() #include <inttypes.h> // intmax_t #include <sys/wait.h> // wait() #include <string.h> // strcspn(), strtok #include <errno.h> // ECHILD #include <fcntl.h> // O_RDONLY, open
5. Building and running the tool
Create a Makefile that will build your project and give the resulting program the name mysh
. See the hello project for an example Makefile.
Your project must be buildable with make
and runnable with ./mysh
, both from the root of your repo, i.e.,
make ./mysh
Automated grading will build and run your tool this way and only this way.
6. Submitting your project
6.1. git
setup
Be sure to complete the git exercise before attempting this project.
Create a new local repository, following the directions in the git exercise (including the git --set-upstream
last step) and set the local and remote repository URLs to be the following locations:
Local repository | ~/cop3402spring25/proc |
Remote repository | gitolite3@eustis3.eecs.ucf.edu:cop3402/$USER/proc |
Commands to setup your repo
These steps only setup the repo, do not submit your code, and assume you have already completed the git exercise. Consult that exercise for specifics on validating each step and submitting your code.
mkdir -p ~/cop3402spring25/proc cd ~/cop3402spring25/proc git init echo "proc project" > README.md git add README.md git commit README.md # Enter a commit message in the editor that pops up git remote add submission gitolite3@eustis3.eecs.ucf.edu:cop3402/$USER/proc git push --set-upstream submission master
6.2. Self-check
See the hello project for instructions on cloning a project from the grading server.
7. Grading
The test cases used to grade the project are listed below. Scripts to run the the odd-numbered test cases are provided publicly, while the even-numbered test cases are private.
To use the automated tests, first download them, e.g.,
cd ~/cop3402spring25/proc wget https://www.cs.ucf.edu/~gazzillo/teaching/cop3402spring25/files/proc_public_tests.tar tar -xvf proc_public_tests.tar
To run a test case, e.g., tests/03-threeargs.sh
, use the following bash command from the root of your local repository directory:
bash proc-tests/03-onearg.sh $(realpath mysh) echo $?
This runs the bash script, passing in the absolute path to your program, which is what $(realpath mysh)
finds for you. The result of echo $?
should be 0
which indicates the test was succesful.
To see what commands the test case is running exactly, use bash -x
instead of just bash
:
bash -x proc-tests/03-onearg.sh $(realpath mysh) echo $?
To avoid having to type the whole name, you can use a star:
bash proc-tests/03*.sh $(realpath mysh) echo $?
7.1. Test cases
# | Short Name | Description | Expected Output |
---|---|---|---|
1 | noargs-fullpath | Run a program with no args. | It should print to stdout. |
2 | noargs | Run a program by name without giving the full path and with no args. | It should print to stdout. |
3 | onearg | Run a program that takes an argument. | It should print to stdout |
4 | in-from-file | Run a program, reading its input from stdin. | It should print to stdout. |
5 | out-to-null | Run a program, redirecting its output to /dev/null | It should print nothing to stdout. |
6 | echo-hello | Run echo. | It should print to stdout. |
7 | echo-hello-to-file | Run echo, redirecting to a file. | It should print to the file. |
8 | cat-in-and-out | Run cat, redirecting both stdin and stdout from and to files. | It should copy the contents of the input file to the output file. |
9 | pipe-noargs-cat | Pipe the output of ls to cat. | It should print the output of ls to stdout. |
10 | pipe-noargs-wc | Pipe a program to word count. | It should print to stdout the word count of the first program's output. |
11 | pipe-wc-arg | Pipe ls to wc -l | It should print only the number of lines from ls. |
12 | pipe-bothargs | Pipe a program with arguments to another program with arguments. | It should correctly run both programs, piping between them, printing to stdout. |
13 | pipe-find-grep | Pipe find to grep. | It should correctly filter the results of find to stdout. |
14 | pipe-find-grep-redout | Pipe find to grep, but redirect the output. | It should correctly filter the results of find to the given file. |
15 | pipe-redin-arg | Pipe cat to grep, redirecting cat's stdin from a file. | It should correctly filter the contents of the input file to stdout. |
16 | pipe-redinout-arg | Redirecting input to program A from a file, its output to program B, and the output of program B to a file. | The file should contain the correct output. |
8. Bonus project ideas
- Support several more shell features, like repeatedly prompting for commands, performing pipes, having more bash-like built in commands, quoted strings and other string processing, etc.
- Come up with your own extension or change and propose it.
9. Grading schema
Criterion | Points |
---|---|
The git repo exists | 1 |
The program is written, builds, and runs as described here | 1 |
Tests pass, prorated by the number of test cases passing | 6 |
TOTAL | 8 |