DEV Community

Cover image for 🌳 Building `ctree`: A Lightweight Unix `tree` Clone in C
Farhad Rahimi Klie
Farhad Rahimi Klie

Posted on

🌳 Building `ctree`: A Lightweight Unix `tree` Clone in C

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() and readdir() to read directories
  • How to use stat() to detect files vs directories
  • Recursive directory traversal
  • Memory management with strdup() and free()
  • 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
Enter fullscreen mode Exit fullscreen mode

πŸ”’ Count Summary

Shows total directories and files:

3 directories, 2 files
Enter fullscreen mode Exit fullscreen mode

πŸ“ -d (Directories Only)

./ctree -d
Enter fullscreen mode Exit fullscreen mode

➑️ Shows only directories (no files)


πŸ“ -L (Depth Limit)

./ctree -L 2
Enter fullscreen mode Exit fullscreen mode

➑️ 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)
Enter fullscreen mode Exit fullscreen mode

πŸ— Project Structure

ctree/
β”œβ”€β”€ Tree.h
β”œβ”€β”€ Tree.c
└── main.c
Enter fullscreen mode Exit fullscreen mode
  • 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:

  1. Read directory entries using readdir()
  2. Store them in an array
  3. Sort them using qsort()
  4. Filter based on flags (-d)
  5. Print with proper indentation
  6. 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
Enter fullscreen mode Exit fullscreen mode

Run:

./ctree
Enter fullscreen mode Exit fullscreen mode

Examples:

./ctree -d
./ctree -L 2
./ctree -d -L 2
./ctree /some/path
Enter fullscreen mode Exit fullscreen mode

⚠️ 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)