/baby-shell

Baby shell implementation in C supports most OS commands with pipelining and sequencing

Primary LanguageC

👶 Baby Shell

Screen Shot 2023-03-06 at 10 03 25

Description

Reimplement the OS Shell in C using libc API. This shell covers most of the features of a shell.

How does shell works?

Shell is simply an interface layer that uses libc API to operate a specific command. Terminal and shell is a two different concepts. Terminal is an application that uses a shell as a backend for the user to communicate with the kernel.

Tokenizer

First stage of a shell is to tokenize the command into tokens that will be processed in a later stage for command execution. You can consider a tokenizer is a preprocessing stage before moving it to the main cook. There is a rule for tokenizing:

  • Special tokens: ,, ;, |
  • String: "Hello world"

Command execution

To understand how a shell executes commands, you must have a fundamental knowledge of the process in the operating system. Whenever a process uses a system call like execve or execvp to execute the binary command, the process exits with the success code exit(0) or error code exit(1). Hence, a single process shell is unable to run interactively while waiting for user input.

Forking process

The solution is simple, for every command, we will fork another process which copies the memory of that process to the another. In this way, the context of the old process is the same while the main program is no longer interrupted after the execution.

NAME
     fork -- create a new process

SYNOPSIS
     #include <unistd.h>

     pid_t
     fork(void);

DESCRIPTION
     fork() causes the creation of a new process...

Read from man fork

Pipe

The pipelining command is a special thing in every shell, it makes use of OS file descriptors to stream the output from stdout to a file descriptor or to read the input from file descriptor instead of stdin. Implementing a pipe requires an API called pipe().

NAME
       pipe - Postfix delivery to external command

SYNOPSIS
       pipe [generic Postfix daemon options] command_attributes...

DESCRIPTION
       The pipe(8) daemon processes requests from the Postfix queue ma
nager to...

Read from man pipe

Features

  • Execute single command
  • Sequencing and execute multiple commands (Token: ;)
  • Input / Output redirection (Token: >, <)
  • Pipelining command (Token: |)
  • Executing scripts (Token: source)
  • Auto code completion
  • SSH remote connection
  • Custom config file similar to .zshrc or .bashrc

Development Guideline

The Makefile contains the following targets:

  • make all - compile everything
  • make tokenize - compile the tokenizer demo
  • make tokenize-tests - compile the tokenizer demo
  • make shell - compile the shell
  • make shell-tests - run a few tests against the shell
  • make test - compile and run all the tests
  • make clean - perform a minimal clean-up of the source tree

The examples directory contains an example tokenizer. It might help.

Contributions

Created by Micheal Baraty and Tin Chung