PoSH was implemented with modularity in mind. Each file handles a responsibility:
posh.cinitializes the shell, parses input, and coordinates execution.exec.cmanages external command execution and pipelines.posh_cmds.cimplements built-in commands (cd,exit,jobs,fg,bg).jobs.cprovides job tracking, background/foreground handling, and status updates.posh_signals.csets custom signal handlers forSIGCHLD,SIGINT, andSIGTSTPto support job control.
For job control, a linked list of jobs was chosen to easily add, remove, and update processes. Built-ins were implemented separately from external execution to simplify parsing. Signal handling was designed to avoid race conditions by blocking signals during critical job table updates. Pipes and redirection were integrated into exec.c using fork(), dup2(), and pipe() for straightforward chaining.
fork(): Create child processes for external commandsexecve(): Execute external programswaitpid(): Wait for foreground processes and reap background processeschdir(): Change directory (cd command)getcwd(): Get current directory (pwd command)getline(): Read user input line
open(): Open files for redirectiondup2(): Duplicate file descriptors for stdin/stdout redirectionclose(): Close file descriptors
pipe(): Create pipe file descriptorsdup2(): Redirect stdin/stdout to pipe ends
sigaction(): Set up handlers for SIGINT, SIGTSTP, SIGCHLDsignal(): Ignore SIGQUITkill(): Forward signals to foreground processes and terminate children
waitpid()withWNOHANG: Non-blocking reaping of terminated background processeswaitpid()withWUNTRACED: Detect stopped processes for job control
- Tested builtin commands:
cd,pwd,jobs,exit - Verified error handling for invalid paths and missing arguments
- Tested external commands with relative paths (e.g.,
./program)
- Input redirection:
./cat < input.txt - Output redirection:
./echo hello > output.txt - Combined:
./cat < input.txt > output.txt - Tested syntax error detection (missing filenames)
- Simple pipes:
/bin/sleep 6 | /bin/sleep 7 - Verified both processes execute correctly
- Tested Ctrl+Z on piped commands
- Ran commands with
&:/bin/sleep 10 & - Verified PID output and job list tracking
- Tested multiple background jobs simultaneously
- Confirmed
jobscommand shows correct state
- Ctrl+C: Tested with foreground processes (terminates child, not shell) and without (no action)
- Ctrl+Z: Suspended foreground processes, verified they appear in
jobslist as 'T' (stopped) - SIGCHLD: Confirmed automatic cleanup of terminated background jobs
- Verified proper cleanup on shell exit using
cleanup_children()andjob_free_all() - Tested for memory leaks with background jobs and pipes
- Ensured dynamically allocated pipe argv arrays are freed
- Linux man pages: Reference for system call specifications
- CMPUT 379 Course materials (Textbook + Lecture notes)