Skip to content

sarthak-panda/codecrafters-shell-cpp

Repository files navigation

Custom C++ Shell Implementation

This project is a custom shell implementation written in C++. It was developed as part of the CodeCrafters "Build Your Own Shell" challenge. The shell mimics POSIX-compliant behavior, supporting built-in commands, external program execution, input/output redirection, and command pipelining.

Features

  • Built-in Commands: Support for cd, pwd, echo, type, exit, and history.
  • External Program Execution: Executes programs found in the system PATH using execvp.
  • Input Parsing: Handles single quotes ('), double quotes ("), and backslash escapes (\) using a custom tokenizer.
  • Redirection: Supports standard output redirection (>), append mode (>>), and standard error redirection (2>).
  • Pipelining: Supports chaining multiple commands using the pipe operator (|).
  • Autocompletion: Tab completion for executables in the system PATH utilizing GNU Readline.
  • History Management: Persists command history across sessions via a file specified by HISTFILE.

Key Design Aspects & Implementation Details

1. Finite State Machine (FSM) Tokenizer

Instead of using simple string splitting or regex, the input parsing logic (tokenize_single_quote) implements a Finite State Machine. This ensures robust handling of quoted strings and escape sequences.

  • States: The parser transitions between states such as STATE_Q0 (unquoted), STATE_Q1 (single-quoted), and STATE_Q3 (double-quoted).
  • Behavior:
    • Spaces inside quotes are preserved as part of a single argument.
    • Escape characters (\) are processed only within double quotes or unquoted text, but treated literally inside single quotes.
    • Redirection operators (>, 2>) are detected during this tokenization phase to separate filenames from command arguments.

2. Process Execution Model

The shell utilizes the standard UNIX fork-exec pattern:

  • Forking: The fork() system call creates a child process.
  • Execution: The child process replaces its memory image with the target program using execvp().
  • Waiting: The parent process uses waitpid() to pause execution until the child process terminates, ensuring the shell does not return to the prompt prematurely.

3. Pipeline Implementation

The execute_pipeline function manages inter-process communication for chained commands (e.g., ls | grep .cpp).

  • Pipe Creation: It initializes N-1 pipes for N commands.
  • File Descriptor Duplication:
    • dup2 is used to map the write end of a pipe to STDOUT_FILENO of the current process.
    • dup2 maps the read end of the previous pipe to STDIN_FILENO of the next process.
  • Resource Management: Strict care is taken to close unused pipe ends in both parent and child processes to prevent deadlocks and file descriptor leaks.

4. I/O Redirection

Redirection is handled immediately after forking but before executing the command.

  • The code parses tokens to identify file descriptors (defaulting to 1 for > and 2 for 2>).
  • It opens the target file with appropriate flags (O_TRUNC for overwrite, O_APPEND for append).
  • dup2 replaces the target file descriptor (stdout or stderr) with the file descriptor of the opened file.

5. GNU Readline Integration

The project integrates libreadline to provide a polished user experience.

  • Input Handling: Replaces std::cin with readline() to support line editing and history navigation (Up/Down arrows).
  • Custom Completion: A custom callback my_completion hooks into readline to scan the system PATH. It calculates the Longest Common Prefix (LCP) to suggest autocompletions when the user presses Tab.

Prerequisites

  • C++ Compiler: GCC or Clang with C++17 support (required for std::filesystem).
  • Libraries: libreadline-dev (or equivalent for your distribution).
  • OS: Linux or macOS (POSIX environment).

Build Instructions

To compile the shell, use the following command:

g++ -std=c++17 -o shell main.cpp -lreadline

Thanks for Visting the Repo

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors