- Preet Harquissandas (CID: 02589338)
- Mikhail Agakov (CID: 02560202)
s3 is a custom Unix-like shell implemented in C. It supports execution of external programs, built-in commands, redirection, pipelines, batched commands, and optional extensions such as subshells.
This README document describes the features implemented, the architectural decisions made, and any additional enhancements beyond the base requirements.
| Feature | Status | Description |
|---|---|---|
| Basic Execution | Fully Implemented | Fork/Exec/Wait pattern, argument parsing. |
| Redirection | Fully Implemented | Support for >, >>, and <. |
Built-in cd |
Fully Implemented | Supports cd, cd <dir>, cd -, cd ~ (home). |
| Prompt | Fully Implemented | dynamic prompt showing current working directory. |
| Pipelines | Fully Implemented | Arbitrary length pipelines (cmd1 | cmd2 | cmd3). |
| Batched Commands | Fully Implemented | Sequential execution using ;. |
| Extension | Status | Description |
|---|---|---|
| PE1: Subshells | Fully Implemented | (cmd) executes in a child shell process. |
| PE2: Nested Subshells | Fully Implemented | Supports deep nesting like ((cmd)). |
| Extension | Status | Description |
|---|---|---|
| Combined Input + Output Redirection | Fully Implemented | Supports instructions like sort < input.txt > output.txt |
| Complex Recursive Redirection | Fully Implemented | Supports instructions like (ls -l | grep .c) > source_files.txt |
✔ Parsing of command input using strtok
✔ Execution of external programs using fork() + execvp()
✔ Parent waits using wait() / custom reap()
✔ Support for multiple arguments
✔ Implemented using open() + dup2()
✔ > overwrites file
✔ >> appends to file
✔ Implemented using open(O_RDONLY) + dup2()
- Detection of redirection operator using a custom parser that respects parenthesis nesting
- Launch handled through launch_program_with_redirection()
- While the specification only required handling a single redirection operator, we extended this to support multiple operators (see Section 8).
✔ Implemented directly in parent process via chdir()
✔ Prompt displays current working directory
✔ Uses getcwd() inside construct_shell_prompt()
Example prompt:
[/home/user/projects/s3 s3]$
✔ Full support for pipelines of arbitrary length
✔ Implemented using:
- pipe()
- dup2() in each child
- Multiple fork() calls in a loop
✔ Redirection allowed on pipeline endpoints
✔ Splits the command line into batch units
✔ Each batch unit is processed independently
✔ Supports pipelines or plain commands inside batch elements
✔ Support for grouped commands in parentheses
✔ Each subshell executes in its own process environment
✔ Allows redirection & pipelines involving subshells
✔ Recursive parsing of nested parentheses
✔ Stack-based matching for ( and )
✔ Support for redirecting both standard input and standard output in a single command
✔ Shell parses and records all redirection operators before executing the command
✔ Input and output redirections are applied by configuring the appropriate file descriptors
✔ Support for applying redirection to entire logical blocks (like subshells) rather than just simple binaries.
✔ Achieved a recursive architecture: the shell detects redirection at the top level, sets up the file descriptors, and then recursively calls the executor for the command string inside.
✔ Compatible with other features such as pipelines and subshell execution
We used a set of commands covering all features:
lswc txt/phrases.txtman catgrep burn txt/phrases.txt
grep June < calendar.txttr a-z A-Z < phrases.txt
cat txt/phrases.txt | sort | wc -lps aux | grep python | sort -k 3 -nr | headtr a-z A-Z < txt/phrases.txt | grep BURN
echo A ; echo B ; ls -lmkdir results ; cat txt/phrases.txt | sort > results/sorted_phrases.txt ; echo "Done"
(cd txt ; ls)(cat txt/phrases.txt | sort) | head- Nested:
((echo A)) (echo a ; (echo b ; (echo c)))
(tr a-z A-Z < txt/phrases.txt) > txt/phrases_upper.txtsort < unsorted.txt > sorted.txt((tr a-z A-Z < txt/phrases.txt) | head) > txt/new_file.txt
gcc *.c -o s3
./s3