mkdir in Zig
const std = @import("std");
pub fn doesItExist(path: []const u8) bool {
var found: bool = true;
std.fs.cwd().access(path, .{}) catch |e| switch (e) {
error.FileNotFound => found = false,
else => found = false,
};
return found;
}
pub fn main() !void {
const allocator = std.heap.page_allocator;
const args = try std.process.argsAlloc(allocator);
if (args.len < 2) {
std.debug.print("Usage: {s} <directory>\n", .{args[0]});
return;
}
const directory = args[1];
if (doesItExist(directory)) {
std.debug.print("Path {s} already exists!\n", .{directory});
return error.PathExists;
}
const cwd = std.fs.cwd();
try cwd.makeDir(directory);
}
This Zig program implements a simple command-line utility that takes a single directory name as an argument, checks whether a directory (or file) with that name already exists in the current working directory, prints an error message and exits with an error if it does exist, and otherwise creates the new directory — effectively ensuring the target directory is created only if it is missing.
The helper function doesItExist() accepts a path slice and returns a boolean indicating presence. It initializes a found variable to true, then calls std.fs.cwd().access(path, .{}) — a method that tests accessibility without opening the item. The empty options {} mean default behavior: it checks for existence and basic read permissions but does not follow symlinks or require special modes. If access succeeds, the path exists (and is accessible), so found remains true. If it fails, the catch block inspects the error: it explicitly handles error.FileNotFound by setting found = false, but crucially also catches all other errors (via the else branch) and likewise sets found = false. This design treats any failure — permission denied, I/O error, invalid path, etc. — as “does not exist” for the purposes of this tool, which may be intentional for a simple “create if missing” script but could mask real issues in more robust applications.
In main(), the program uses the page allocator to fetch command-line arguments safely with argsAlloc(). It enforces exactly one argument (the directory name) by checking args.len < 2 and printing usage if missing. It then calls doesItExist() on the provided name. If the path already exists, it prints a message and returns error.PathExists to signal failure. If the path does not exist, it gets the current working directory handle via std.fs.cwd() and calls makeDir() to create the new directory; this call is wrapped in try, so any creation failure propagates as an error and crashes the program with a helpful message.
Save the Zig program as mkdir.zig and use it:
$ zig version
0.15.2
$ zig run mkdir.zig -- /tmp/test
$ ls -ld /tmp/test
drwxr-xr-x 2 mtsouk wheel 64 Jan 18 11:55 /tmp/test
$ zig run mkdir.zig -- /tmp/test
Path /tmp/test already exists!
error: PathExists
Happy coding in Zig!