From 6609f522ff4555f0e9a4f7d58425f3cfd3166d36 Mon Sep 17 00:00:00 2001 From: ibrohimovmuhammad2020 Date: Fri, 17 Apr 2026 22:54:01 +0200 Subject: [PATCH 1/4] docs: rewrite README with architecture and constraints sections - Remove student-journal 'What We Learned' and 'Repo Owner' framing - Add Architecture section pointing to tokenizer/parser/executor source files - Add Constraints section listing the permitted libc calls from the 42 subject - Add 'What was technically hard' section (heredoc+expansion, quote tokenisation, signals across fork, no-leak discipline) - Keep Readline dependency and build instructions - Credit co-author Ghazaleh Ansari --- README.md | 86 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index aef5b11..da18436 100755 --- a/README.md +++ b/README.md @@ -1,58 +1,68 @@ # Minishell -Minishell is a simplified UNIX shell project developed as part of the 42 School curriculum. The goal is to understand how a shell works by creating a minimalistic version that can interpret and execute user commands. +[![build](https://github.com/MukhammadIbrokhimov/Minishell/actions/workflows/build.yml/badge.svg)](https://github.com/MukhammadIbrokhimov/Minishell/actions/workflows/build.yml) ---- +A UNIX shell reimplementation in C. Parses and executes commands with pipes, redirections, heredocs, environment-variable expansion, quote handling, signal handling, and 7 built-in commands — all within the [42 norm](https://github.com/42School/norminette) (80-char lines, 25-line functions, no globals except a signal flag). -## 🚀 Features +Built with [Ghazaleh Ansari](https://github.com/ghazalehans) as part of the 42 Berlin Common Core. -- Prompt display -- Execution of binary commands with arguments -- Built-in commands: `echo`, `cd`, `pwd`, `export`, `unset`, `env`, `exit` -- Environment variables handling -- Pipes (`|`) and redirections (`>`, `>>`, `<`, `<<`) -- Signal handling (`CTRL+C`, `CTRL+\`) -- Quote management (`'`, `"`) -- Exit status handling -- Error messages similar to bash +## Features ---- +- Interactive prompt powered by GNU Readline, with history +- Command execution via `fork` + `execve` with `PATH` resolution +- Pipes (`|`) and combinations thereof +- I/O redirections: `<`, `>`, `>>`, `<<` (heredoc) +- Environment variable expansion (`$VAR`, `$?`) inside and across quote contexts +- Single-quote and double-quote handling with correct expansion semantics +- Signal handling: `Ctrl-C` (SIGINT), `Ctrl-\` (SIGQUIT), `Ctrl-D` (EOF) +- Exit-status propagation compatible with `bash`'s behaviour +- Built-ins: `echo`, `cd`, `pwd`, `export`, `unset`, `env`, `exit` -## 🛠️ Built-ins Implemented +## Architecture -| Command | Description | -|---------|-------------| -| `echo` | Display a line of text | -| `cd` | Change the current directory | -| `pwd` | Print the current working directory | -| `export`| Set environment variables | -| `unset` | Remove environment variables | -| `env` | Show environment variables | -| `exit` | Exit the shell | +Input flows through three stages: ---- +1. **Tokenizer** (`srcs/parsing/token_utils*.c`) — splits the raw line into tokens respecting quotes and shell meta-characters (`| & ; < > ( )`). +2. **Parser** (`srcs/parsing/parse*.c`) — builds a tree of command nodes. Node kinds: `EXEC`, `REDIR`, `PIPE`, `LIST`, `BACK`, `HEREDOC`. +3. **Executor** (`srcs/execution/*.c`) — walks the tree, setting up file descriptors and forking processes as needed. Heredocs are materialised via temporary pipes before the pipeline starts. -## 📦 Compilation +Memory ownership is traced through every exit path — including signal-driven interrupts during heredoc input — which was the hardest part of the project. + +## Build and run + +Minishell depends on GNU Readline. ```bash +# Debian/Ubuntu +sudo apt-get install libreadline-dev + +# macOS (Apple Silicon Homebrew) +brew install readline +# Makefile flags may need adjustment if readline isn't at /opt/homebrew + make +./minishell ``` -## 🧠 What We Learned +The vendored `includes/libft/` provides the 42 libft (strings, memory, linked list, ft_printf) used throughout the project. + +## Constraints + +From the 42 subject: -- How shells parse and execute commands -- Managing processes with `fork()`, `execve()`, and `wait()` -- File descriptor and pipe management -- Implementing a command parser -- Handling environment and built-in commands -- Signal handling and user input +- C, compiled with `cc -Wall -Wextra -Werror` +- No leaks (verified with `valgrind --leak-check=full`) +- Limited set of permitted libc calls (`readline`, `printf`, `malloc`, `free`, `write`, `access`, `open`, `read`, `close`, `fork`, `wait`/`waitpid`/`wait3`/`wait4`, `signal`, `sigaction`, `sigemptyset`, `sigaddset`, `kill`, `exit`, `getcwd`, `chdir`, `stat`/`lstat`/`fstat`, `unlink`, `execve`, `dup`/`dup2`, `pipe`, `opendir`/`readdir`/`closedir`, `strerror`, `perror`, `isatty`, `ttyname`, `ttyslot`, `ioctl`, `getenv`, `tcsetattr`/`tcgetattr`, `tgetent`/`tgetflag`/`tgetnum`/`tgetstr`/`tgoto`/`tputs`) +- 42 norm: 80-char lines, ≤25-line functions, no globals except one `volatile sig_atomic_t` for the signal flag ---- +## What was technically hard -## 👥 Authors +- **Heredoc with expansion**: collecting the heredoc body while still respecting `$VAR` expansion (unless the delimiter was quoted) and handling `Ctrl-C` cleanly during collection. +- **Quote-aware tokenisation**: `echo "$USER's home"` must expand `$USER` but treat the embedded apostrophe as a literal. +- **Signal handling across `fork`**: the child and parent need different `SIGINT` behaviour; the executor installs/restores handlers at the right moments. +- **No-leak discipline**: every allocation traced through normal, error, and signal-interrupt paths. -- **Repo Owner** - [Mukhammad Ibrokhimov](https://github.com/mukhammadibrokhimov) +## Authors -- **Teammate Name** - [Ghazaleh Ansari](https://github.com/ghazalehans) +- [Mukhammad Ibrokhimov](https://github.com/MukhammadIbrokhimov) +- [Ghazaleh Ansari](https://github.com/ghazalehans) From dcadff6983c49c6aed7a8cd6b42c496c08146ec9 Mon Sep 17 00:00:00 2001 From: ibrohimovmuhammad2020 Date: Fri, 17 Apr 2026 22:54:01 +0200 Subject: [PATCH 2/4] chore: add MIT LICENSE Covers both authors. MIT chosen for permissiveness; it grants equal rights to all contributors listed in the copyright notice. --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..386a3cc --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Mukhammad Ibrokhimov, Ghazaleh Ansari + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 75089e75cd990454f62b6f4fe7a34fd97961c132 Mon Sep 17 00:00:00 2001 From: ibrohimovmuhammad2020 Date: Fri, 17 Apr 2026 22:54:01 +0200 Subject: [PATCH 3/4] chore: ignore macOS and editor metadata; untrack srcs/.DS_Store The existing .gitignore covered C build artefacts but missed .DS_Store and .vscode/. This adds those plus the minishell binary output. Also untracks srcs/.DS_Store which slipped back in after an earlier cleanup commit. --- .gitignore | 15 +++++++++++++++ srcs/.DS_Store | Bin 8196 -> 0 bytes 2 files changed, 15 insertions(+) delete mode 100644 srcs/.DS_Store diff --git a/.gitignore b/.gitignore index 2b441a2..6ba3e06 100755 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,18 @@ Mkfile.old dkms.conf # minishell_tester ./minishell_tester +# covers build artefacts but NOT macOS metadata or editor configs). + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Editor / IDE +.vscode/ +.idea/ +*.swp +*.swo + +# Minishell binary (project-specific) +minishell diff --git a/srcs/.DS_Store b/srcs/.DS_Store deleted file mode 100644 index 6f5d9c2824dfd05ffee6327517ef99f70d9f4531..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeI1L66cv6vy8ztdwj_IB3Gfq={Fug1F*lFBR8=S221}gDv3NSX%;RF(D*9>v!-g zc=eO`T|DXk&5YVDMzC}q9zeJaMs2iniAuA_6^&y zBbT8H`9vv&6w~}cl#Di_Wk3iB0U;m+gn$tE7YJa_W^=ae`({>JAs__)O9K3SaN(?; z)y$}VbfD2C0JMr>ZRn#8&^fME&uV5=r{XnD^`LC3vL%Kx>6mvp9O_xkjGA;(CY_Xh zXJsoCrQaQSt_~;V8I@KD2!TxkT)R6I&;pfvl&{}|C%v(*tC>+A;&HtTLuLPGAYww`0uiW~&)Ver|Ni##{|j_S@==9=5cpLBs(L&)?juX@ x>LuB{%e(Lwa5j$1jOr9LXZ{hu^^YG6(RUHbIiA(bC`Mp%5TG$gBLw~`fp1Y}BZ>e3 From 3d85c849d93319100cd126983f130395c1a4dfed Mon Sep 17 00:00:00 2001 From: ibrohimovmuhammad2020 Date: Fri, 17 Apr 2026 22:54:01 +0200 Subject: [PATCH 4/4] ci: add build workflow for readline-based build on ubuntu-latest Installs libreadline-dev and verifies that make produces a minishell binary. Runs on push to main and on PRs. Surfaces a build-passing badge in the README. --- .github/workflows/build.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..a759da8 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,29 @@ +name: build + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install readline + run: | + sudo apt-get update + sudo apt-get install -y libreadline-dev + + - name: Build + run: make + + - name: Verify binary + run: | + test -x ./minishell + file ./minishell + + - name: Clean + run: make fclean