The Linux Shell is a custom Unix-like shell written in C as part of a university project for COMP 3659 – Operating Systems. It supports essential shell features such as command execution, I/O redirection, pipelines, signal handling, and a custom memory allocator. This project explores key operating system concepts including process management, inter-process communication, and signal control.
- Command Execution: Launch any executable with arguments
- I/O Redirection: Support for input (
<) and output (>) redirection - Pipelines: Execute chained commands using pipes (
|) - Background Execution: Run processes in the background using
& - Built-in Commands: Includes
cdfor directory navigation andexitto quit - Signal Handling: Gracefully handles
SIGINT(Ctrl+C) without killing the shell - Custom Memory Management: Lightweight heap allocator for internal operations
shell.c: Main shell loop and command parsingjob.c/job.h: Job and pipeline managementstr_lib.c/str_lib.h: Utility functions for string operationsmylib.c/mylib.h: Custom heap allocator implementationsignal_handle.c/signal_handle.h: Custom signal handling logicstruct.h: Data structure definitionsconstants.h: Configuration values and limits
Use the provided Makefile to build the project.
make # Build the shell
make clean # Remove compiled filesThis will generate an executable named shell.
Run the shell:
./shellBasic Command
mysh$ /bin/lsI/O Redirection
mysh$ /bin/ls > output.txt
mysh$ /bin/cat < input.txtPipelines
mysh$ /bin/ls -l | /usr/bin/grep .cBackground Processes
mysh$ /bin/sleep 10 &Built-in Commands
mysh$ cd /tmp
mysh$ exitA test script test_cases.txt is included with sample inputs to validate core functionality.
To test the memory management module:
make test_mylib
./test_mylib- No support for environment variables or wildcard expansion
- Argument count and pipeline depth are limited by
MAX_ARGSandMAX_PIPELINE_LEN - No support for freeing individual allocations (entire heap reset only)
MyShell uses a fixed-size heap with custom functions:
my_alloc(size_t size): Allocates memorymy_free_all(): Resets the heap
This approach reduces fragmentation and simplifies cleanup, but lacks granularity.
- Parse input into a
job_tstructure - Set up pipes (if pipeline is present)
- Fork processes for each stage
- Redirect input/output as required
- Execute using
execve - Wait for child processes unless running in background
Custom SIGINT handler allows Ctrl+C to interrupt foreground jobs without killing the shell process itself.
- Abiola Raji
- Jacky On
- Cameron Goit
Class: COMP 3659 – Operating Systems