When I started learning low-level programming, I wanted to build something practical β not just theory. So I decided to recreate a simplified version of the Unix tree command using C.
This project, called ctree, helped me deeply understand filesystem traversal, recursion, and how real CLI tools work under the hood.
π Source Code
π Check out the full project on GitHub:
π What is ctree?
ctree is a lightweight command-line tool that prints directory structures in a tree-like format β just like the Unix tree utility.
But instead of using an existing tool, I built it from scratch using pure C and POSIX APIs.
π§ What I Learned
This project was more than just printing directories. It taught me:
- How to use
opendir()andreaddir()to read directories - How to use
stat()to detect files vs directories - Recursive directory traversal
- Memory management with
strdup()andfree() - Sorting using
qsort() - Building CLI tools with argument parsing
- Designing modular C projects (header + source + main)
β¨ Features
Hereβs what ctree can do:
π Tree Structure
Prints directories and files in a clean tree format:
.
|-- main.c
|-- src
| L__ utils.c
L__ include
π’ Count Summary
Shows total directories and files:
3 directories, 2 files
π -d (Directories Only)
./ctree -d
β‘οΈ Shows only directories (no files)
π -L (Depth Limit)
./ctree -L 2
β‘οΈ Limits how deep the recursion goes
π€ Sorted Output
Entries are sorted alphabetically using qsort() for clean output.
π¦ File Sizes
Files display their size:
main.c (1200 bytes)
π Project Structure
ctree/
βββ Tree.h
βββ Tree.c
βββ main.c
- Tree.h β declarations and configuration
- Tree.c β core logic (recursion, sorting, filtering)
- main.c β CLI argument parsing
βοΈ How It Works
The core logic follows a simple but powerful pipeline:
- Read directory entries using
readdir() - Store them in an array
- Sort them using
qsort() - Filter based on flags (
-d) - Print with proper indentation
- Recursively process subdirectories
This pattern is actually similar to how real CLI tools are implemented.
π§ Compilation & Usage
Compile:
gcc Tree.c main.c -o ctree
Run:
./ctree
Examples:
./ctree -d
./ctree -L 2
./ctree -d -L 2
./ctree /some/path
β οΈ Challenges I Faced
One tricky bug I encountered was incorrect tree formatting when using the -d flag.
Because I filtered files after counting entries, the program misidentified the "last" element in a directory.
β Solution:
I fixed it by:
- First collecting entries
- Then filtering them
- Then printing with correct indexing
This small change made the output accurate and robust.
π Whatβs Next?
Iβm planning to improve ctree with:
- π¨ Colored output (like real
tree) - π Support for hidden files (
-a) - π Human-readable file sizes (KB, MB)
- β‘ Performance optimizations
π¬ Final Thoughts
Building ctree was a huge step for me in understanding how system-level tools work.
Itβs easy to use commands like tree every day β but building one yourself changes how you see the system.
If youβre learning C, I highly recommend building small CLI tools like this. Youβll learn way more than from tutorials alone.
Top comments (0)