Shell
Custom-built Shell application in C

Tech Stack
- C
- C++
- UNIX
Check It Out
About
This project is a fully functional Unix-like shell written in C. It supports process execution, signal handling, and input/output redirection — all constructed from scratch. Inspired by classic CLI environments, it replicates much of the behavior seen in shells like bash
and sh
, while adding custom features like PID expansion and foreground-only toggling.
My main goal with this project was to gain low-level experience working with the POSIX API, including process control, signals, and file descriptors. Writing everything manually — from memory management to command tokenization — helped me deeply understand how shells work under the hood.
How I Built It
- Language & Tools: C (with POSIX headers),
gcc
,valgrind
for memory safety, and a terminal for testing. - Custom Lexer & Parser: I developed a lexer and parser by hand. The lexer handles quotation marks and filters I/O redirection, pipe, and background operators. The parser processes the output from the lexer and creates an Abstract Syntax Tree (AST), allowing efficient and organized execution of the user’s command.
- Signal Handling:
- Used
sigaction()
to handleSIGTSTP
(Ctrl+Z
) for toggling foreground-only mode. - Foreground processes are interruptible via
SIGINT
(Ctrl+C
), while the shell ignores it.
- Used
- Execution Model:
- Forks child processes for external commands.
- Handles input/output redirection using
dup2()
andopen()
. - Tracks background processes in a linked list and reaps zombies with
waitpid()
usingWNOHANG
.
Features
- Built-in Commands: Supports
cd
,status
, andexit
internally. - PID Expansion: Substitutes
$$
with the current shell’s process ID. - Foreground/Background Execution: Uses
&
to send jobs to the background; toggle-safe withSIGTSTP
. - Signal-Safe Behavior: Shell and children handle
SIGINT
/SIGTSTP
differently for robust control. - Redirection Support: Clean redirection of STDIN and STDOUT with file fallback for background jobs.
- Memory Management: Manual
malloc()
andfree()
for every structure, with clean shutdown logic. - Zombie Reaping: Non-blocking cleanup of completed background jobs to avoid defunct processes.