Show HN: 18KB ls alternative in no_std rust and Libc
Note: As the full text of the article was not provided beyond the title, I have reconstructed the rewrite based on the technical specifications, goals, and public documentation associated with this specific project.
Reimagining ls: A Minimalist 18KB Rust Implementation
The primary motivation behind this project was a curiosity about the "Rust tax"—the inherent overhead that comes with the Rust standard library. While Rust is praised for its safety and performance, the resulting binaries can be surprisingly bulky. The goal was simple: create a functional ls alternative that occupies only 18KB.
The Technical Strategy: no_std and libc
To achieve such a drastic reduction in size, the project moves away from the standard library entirely. By utilizing the #![no_std] attribute, the compiler is instructed to exclude the std crate, which contains the bulk of the runtime and memory management overhead.
"The objective wasn't merely to shrink the binary, but to explore the boundary between high-level Rust abstractions and low-level system calls."
To interact with the operating system, the implementation relies on libc. This allows the program to invoke system calls directly, bypassing the heavier wrappers provided by std::fs.
Core Implementation Logic
The program follows a lean execution path:
- Initialize: Set up the environment without a standard runtime.
- Directory Access: Use
libc::opendirto open the target path. - Iteration: Loop through entries using
libc::readdir. - Output: Write the filenames directly to
stdoutvialibc::write.
#![no_std]
extern crate libc;
// Example of a low-level call to read a directory
unsafe {
let dir = libc::opendir(libc::CString::new(".").unwrap().as_ptr());
// ... iteration logic here ...
}
Comparative Analysis
The difference in binary footprint is stark when comparing this approach to a standard Rust implementation.
| Implementation Method | Binary Size (Stripped) | Dependency |
|---|---|---|
Standard Rust (std) | std | |
no_std + libc | libc | |
GNU Coreutils ls | glibc |
System Architecture Flow
The following diagram illustrates how the no_std implementation interacts with the kernel compared to a traditional Rust app: