Inspiration

We were inspired by the foundational role that shells play in every operating system. The original smallsh assignment from OS coursework demonstrates how core system utilities, process management, signals, I/O redirection, work under the hood. We wanted to take that concept further: rewrite it in Rust for memory safety and modern ergonomics, and then expand it with built-in coreutils that normally live as separate binaries. The hackathon theme of "Rebuilding the OS: Core System Utilities" was a perfect fit.

What it does

smallsh is a fully functional Unix shell written in Rust. It supports:

  • An interactive : prompt with command parsing, I/O redirection (<, >), and background process execution (&)
  • Three core shell built-ins: exit, cd, status
  • Signal handling: SIGINT (Ctrl-C) is ignored by the shell but kills foreground children; SIGTSTP (Ctrl-Z) toggles foreground-only mode
  • Six integrated coreutils that run in-process without fork/exec:
  • [echo]
  • [cat]
  • [grep]
  • [cp] diskusage, and benchmark
  • diskusage recursively walks directories and displays file sizes with a Unicode bar chart
  • benchmark measures disk write speed by streaming data from /dev/zero and /dev/urandom

How we built it

  • nix crate for POSIX syscalls (fork, execvp, waitpid, dup2, sigaction)
  • libc crate for async-signal-safe write(2) in signal handlers
  • AtomicBool for the foreground-only mode flag shared between the signal handler and the main loop
  • [ProcessTable] struct to replace C's global mutable state for background process tracking into a dedicated cmd_*.rs module, then registered in the built-in dispatch table
  • Cross-compilation checks against x86_64-unknown-linux-gnu were run throughout development on Windows to catch platform issues early
  • 19 unit tests cover parsing, grep search, and error handling for every built-in

Challenges we ran into

  • Cross-platform development: We developed on Windows but the shell requires Unix APIs (fork, signals). We solved this with #[cfg(unix)] conditional compilation and cross-compile checks against a Linux target.
  • Signal handler safety: Rust's println! (like C's printf) is not async-signal-safe. We had to use raw libc::write(2) with hardcoded file descriptor constants inside the SIGTSTP handler.
  • Type mismatches: The nix crate's API differs subtly from raw libc with RawFd imports, OFlag vs raw integers, CStr vs CString for execvp. Each module needed careful type wiring.

Accomplishments that we're proud of

  • A complete, working Unix shell in Rust with full signal handling, background process management, and I/O redirection
  • Six integrated coreutils
  • Zero unsafe outside of signal handlers, the only unsafe code is the libc::write calls and sigaction setup, which are inherently unsafe operations
  • 19 passing unit tests covering parsing, search algorithms, and error handling
  • Clean modular architecture: 12 focused Rust source files, each under 140 lines

What we learned

  • How Unix shells actually work at the syscall level with fork/exec/waitpid lifecycle, dup2 for redirection, sigaction for signal handling
  • How Rust's ownership model forces you to think carefully about shared state that C lets you scatter across globals
  • The nix crate provides safe Rust wrappers for POSIX APIs, but signal handlers still require raw unsafe code because async-signal-safety is a runtime property the type system can't enforce
  • Cross-compilation with cargo check --target is a powerful workflow for developing Unix software on non-Unix machines

What's next for Shell

  • Pipe operator (|) chain commands together (ls | grep .rs | wc -l)
  • Command history with arrow-key navigation (using the rustyline crate)
  • Tab completion for filenames and built-in commands
  • Environment variable expansion ($HOME, $PATH, $$ for PID)
  • Job control (fg, bg, jobs) for full background process management
  • More coreutils: mv, rm, mkdir, head, tail, sort, uniq
  • Packaging as a standalone Linux binary for embedded/minimal systems

Built With

Share this project:

Updates