Flash 51 lines
// ls — list directory entries for /bin/ls.
//
// With no arguments it lists the current directory; with arguments it lists each
// path in turn. Each entry's basename is written to fd 1, a trailing '/'
// appended for a directory, then a newline. No flags, no recursion.
//
// Exercises `if`/`else`, nested `while` loops, a `.{}` struct literal for the
// stack-allocated directory entry, a `&d.name` address-of on a member, and a
// `&&` condition (which lowers to Zig's `and`). flibc_mem is imported because
// the basename-length scan can lower to a libcall.
use flibc
link "flibc_start"
link "flibc_mem"
fn emit(s []u8) {
_ = flibc.sys.write_fd(1, s.ptr, s.len)
}
fn listDir(path cstr) {
var d flibc.Dirent = .{}
var i u64 = 0
while flibc.sys.readdir(path, i, &d) == 0 {
var n usize = 0
while n < d.name.len && d.name[n] != 0 {
n += 1
}
_ = flibc.sys.write_fd(1, &d.name, n)
if d.d_type == flibc.DT_DIR {
emit("/")
}
emit("\n")
i += 1
}
}
export fn main(argc usize, argv argv) noreturn {
if argc <= 1 {
listDir(".")
} else {
var a usize = 1
while a < argc {
path := argv[a] orelse break
listDir(path)
a += 1
}
}
flibc.exit()
}