Skip to content

ViserionBuild/posix_shell

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 

Repository files navigation

POSIX Shell Implementation

A custom interactive shell written in C++ that replicates core POSIX shell features. This project demonstrates fundamental concepts of operating systems including process management, inter-process communication, and system calls.

Features

Core Functionality

  • Command Parsing: Reads and parses user input with support for:

    • Multiple commands separated by semicolons (;)
    • Command pipelining with pipes (|)
    • Complex command chaining
  • Process Management:

    • Creates and manages child processes using fork() and execvp()
    • Supports foreground and background process execution (with &)
    • Handles process groups with setpgid()
    • Signal handling for SIGINT (Ctrl+C) and SIGTSTP (Ctrl+Z)
  • Input/Output Redirection:

    • Output redirection: > (overwrite) and >> (append)
    • Input redirection: <
    • Piping between commands: |
  • Built-in Commands:

    • cd - Change directory (with support for ~ and ..)
    • ls - List directory contents (with -a and -l flags)
    • echo - Display text
    • pwd - Print working directory
    • history - View and recall previous commands
    • pinfo - Display process information
    • search - Recursively search for files
  • Command History:

    • Maintains a persistent command history (stored in history.txt)
    • Uses GNU Readline library for command-line editing
    • Supports history navigation and recall
  • Custom Prompt:

    • Dynamic prompt showing username@hostname:path>
    • Displays current working directory relative to home
  • Error Handling:

    • Graceful handling of invalid commands
    • Proper error messages for missing arguments
    • System error reporting

Project Structure

posix_shell/
├── problem/
│   └── AOS_Assignment_2_M25_V1.pdf    # Assignment problem statement
├── solution/
│   ├── README.md                       # Documentation
│   ├── Makefile                        # Build configuration
│   ├── all_header.h                    # Common header includes
│   ├── utility.h                       # Function declarations
│   ├── utility.cpp                     # Utility functions
│   ├── home.cpp                        # Main entry point and shell loop
│   ├── base_cmd_file.cpp               # Core command execution and piping
│   ├── io_file.cpp                     # I/O redirection handling
│   ├── ls_file.cpp                     # ls command implementation
│   ├── next_cmd_file.cpp               # Additional commands (history, pinfo, search)
│   └── history.txt                     # Command history storage
├── .gitignore
└── README.md

File Descriptions

File Purpose
all_header.h Common header file including all necessary system libraries (iostream, unistd.h, readline, etc.)
utility.h / utility.cpp Utility functions used throughout the shell (clearScreen, print, string formatting, etc.)
home.cpp Main entry point containing the shell loop, command parsing, and signal handlers
base_cmd_file.cpp Core command execution logic including process management, piping, and forking
io_file.cpp Handles input/output redirection for <, >, and >> operators
ls_file.cpp Implements the ls command with support for -a and -l flags
next_cmd_file.cpp Implements additional commands: search, history, and pinfo

Prerequisites

  • C++ Compiler: g++ (with C++11 support or higher)
  • GNU Readline Library: Required for command-line editing and history

Installing Dependencies

Ubuntu/Debian:

sudo apt-get update
sudo apt-get install g++ libreadline-dev

macOS:

brew install readline

Building the Project

  1. Clone the repository:
git clone https://github.com/viserion999/posix_shell.git
cd posix_shell/solution
  1. Compile the shell:
make

This will compile all source files and link them with the readline library to produce the home executable.

  1. (Optional) Rebuild from scratch:
make rebuild
  1. Clean build artifacts:
make clean

Running the Shell

After building, run the shell with:

./home

You should see a welcome message and a custom prompt like:

----------------------------
WELCOME
----------------------------
username@hostname:~>

Usage Examples

Basic Commands

# Print working directory
username@hostname:~> pwd

# List files
username@hostname:~> ls
username@hostname:~> ls -a        # Show hidden files
username@hostname:~> ls -l        # Long listing format
username@hostname:~> ls -la       # Combined flags

# Change directory
username@hostname:~> cd /usr/local
username@hostname:/usr/local> cd ..
username@hostname:/usr> cd ~      # Return to home

Command Chaining

# Multiple commands with semicolon
username@hostname:~> ls ; pwd ; echo "Done"

# Piping
username@hostname:~> ls -l | grep ".cpp"
username@hostname:~> cat file.txt | wc -l

I/O Redirection

# Output redirection
username@hostname:~> ls > output.txt          # Overwrite
username@hostname:~> ls >> output.txt         # Append

# Input redirection
username@hostname:~> cat < input.txt

# Combined
username@hostname:~> cat < input.txt > output.txt

Background Processes

# Run in background
username@hostname:~> gedit &
[PID displayed]

History Management

# Show last 10 commands
username@hostname:~> history

# Show last N commands
username@hostname:~> history 5

Process Information

# Show current shell process info
username@hostname:~> pinfo

# Show specific process info
username@hostname:~> pinfo 12345

File Search

# Search for file recursively
username@hostname:~> search filename

Implementation Highlights

Command Parsing

The shell tokenizes input in three levels:

  1. Split by semicolon (;) for multiple commands
  2. Split by pipe (|) for piped commands
  3. Split by whitespace for individual arguments

Process Management

  • Fork-Exec Model: Each command creates a new child process using fork(), then replaces it with the target program using execvp()
  • Process Groups: Each command runs in its own process group for proper job control
  • Background Execution: Commands ending with & run asynchronously

Piping

  • Multi-command pipelines are supported by creating a chain of pipes
  • File descriptors are properly redirected using dup2()
  • Parent closes all pipe ends and waits for all children

Signal Handling

  • SIGINT (Ctrl+C): Terminates foreground processes only
  • SIGTSTP (Ctrl+Z): Suspends foreground processes

Educational Purpose

This shell is designed for educational purposes to demonstrate:

  • How UNIX shells work internally
  • Process creation and management
  • Inter-process communication via pipes
  • File descriptor manipulation
  • System call usage
  • Signal handling in multi-process applications

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published