Skip to content

Functional shell in C, implementing many of the fundamental features found in shells such as Bash

Notifications You must be signed in to change notification settings

lb1224-icl/Shell-Implementation

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

S3 – Software Systems Shell

Table of Contents

  1. Repository Layout
  2. Building & Running
  3. Core Functionality
  4. Proposed Extensions (PEs)
  5. Extra Enhancements (EEs)
  6. Example Sessions

Repository Layout

Path Description
src/s3main.c Main control loop (execute_command_line), entry point, and integration of every feature.
src/s3.c Implementation of parsing helpers, process launches, redirection plumbing, and pipeline logic.
src/history.c / .h Simple persistent history database plus expansion logic (!!, !n, !prefix).
src/txt/ Sample data files (e.g., phrases.txt) for redirection / pipeline demos.
tmp/ Working folder used for testing (not part of the build).

Building & Running

# from repo root
gcc src/s3main.c src/s3.c src/history.c -o src/s3
./src/s3

The shell persists command history in .history (created automatically) and uses the current working directory in its prompt: [s3 /path/to/cwd]$.


Core Functionality

Command Execution

  • Fork / exec pathlaunch_program and child are responsible for basic commands. Each call fork/execs and returns control to the parent, while the parent synchronises via reap():

    void launch_program(char *args[], int argsc, int input_fd, int output_fd) {
        pid_t rc = fork();
        if (rc == 0) {
            child(args, argsc, input_fd, output_fd); // execvp happens here
        }
    }
  • exit built-in – handled in the parent so the shell terminates cleanly and can accept optional status codes (e.g., exit 7).

  • Whitespace-aware parsingparse_command tokenises while preserving quoted substrings and removing quote characters, enabling commands like echo "== subshell test ==".

Redirections

  • Detects <, >, >>, 2>, 2>>, 2>&1, &> using command_with_redirection plus extract_redirections. All descriptors are validated (stat + access) before launching.
  • Input/output/error/both file descriptors are opened in the parent, then duplicated in the child via dup2. Multiple redirections in a single command obey the “last one wins” rule because later operators overwrite earlier ones inside Redirections.
  • Safety checks prevent writes to directories and surface clear diagnostics (e.g., “s3: 'tmp/' is a directory”).

Semicolons (Batched Commands)

split_by_semicolon walks the line once, keeping track of parentheses and quotes via the QuoteState helper so constructs such as echo one ; (cd src; make) parse correctly. Each command in the batch executes independently, matching Bash’s cmdA ; cmdB semantics.

Shell Built-ins & Prompt

  • cd – Recognised upfront (execute_command_line calls change_directory in the parent). Supports cd ., cd .., cd - (jump back to previous directory), cd -- <path> (treats paths starting with - literally), and tilde expansion (cd ~, cd ~/path). The prompt reflects the new directory immediately because construct_shell_prompt calls getcwd on each loop iteration. A missing argument defaults to $HOME.
  • Prompt[s3 <cwd>]$ truncated safely if the current path would exceed MAX_PROMPT_LEN.
  • History CLI – Typing history prints numbered entries. The subsystem (see src/history.c) loads .history on startup and appends after every user command.

Pipelines

  • Quote-aware detection (command_with_pipe) and tokenisation (split_by_pipe) ensure that only real | separators (not those inside strings) split the pipeline.
  • run_pipeline orchestrates the chain: it creates pipes in the parent, invokes launch_pipeline_stage for each segment, closes unused FDs to avoid deadlocks, then waits for all children.
  • launch_pipeline_stage reuses the same launch_program / _with_redirection functions by passing the appropriate input_fd / output_fd. Even mid-pipeline commands can redirect to files (>), which effectively “breaks” the stream beyond that point, mirroring Bash’s behaviour.
  • Pipelines can include subshell segments. When a stage is wrapped in parentheses, we fork another copy of s3 with execlp(shell_path, shell_path, "-c", inner, NULL) so constructs like (cd src; tr ...) | grep ... work exactly as in the reference shell.

Proposed Extensions (PEs)

Extension Status Notes
PE1 – Subshells We allow arbitrary command groups inside parentheses. Each group executes in a forked child running s3 -c "<inner>", so changes (e.g., cd) do not leak back to the parent.
PE2 – Nested Subshells Parentheses depth is tracked when splitting on semicolons and pipes, so nested groups such as (echo outer ; (cd src; ls)) are parsed correctly.

Subshells can also appear inside pipelines, with the child inheriting pipe file descriptors before execvp.


Extra Enhancements (EEs)

Enhancement Status Notes
EE1 – History Expansion Interactive shells expand !!, !n, and !prefix, print the expanded line before running it, and reject unmatched requests with friendly messages (“No such history entry.”). A bare ! is ignored to avoid surprises.
EE2 – Multi-way Redirection Redirection parser accepts <, >, >>, 2>, 2>>, 2>&1, and &>. Operators can appear multiple times; the last occurrence wins per stream, matching Bash semantics.

Example Sessions

[s3 /home/lucca/Documents/Shell-Implementation]$ history
1  ls
2  cd src
3  history

[s3 /home/lucca/Documents/Shell-Implementation]$ !!   # repeats `history`
history

[s3 /home/lucca/Documents/Shell-Implementation]$ ls txt | head -n 3
calendar.txt
phrases.txt
phrases_sorted.txt

[s3 /home/lucca/Documents/Shell-Implementation]$ (cd src; tr a-z A-Z < txt/phrases.txt) | grep BURN | sort | uniq -c | head -n 5
      1 BURNING CANDLE
      1 BURNING COAL
      1 BURNING DAWN
      1 BURNING EMBER
      1 BURNING FIELD

These examples demonstrate batched commands, history, pipelines, redirections, and subshells working together – covering both the assignment’s core specs and the implemented extensions.


About

Functional shell in C, implementing many of the fundamental features found in shells such as Bash

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •  

Languages