diff options
-rw-r--r-- | build.zig | 6 | ||||
-rw-r--r-- | src/cmd/dir.zig | 25 | ||||
-rw-r--r-- | src/statvfs_helper.c | 19 |
3 files changed, 42 insertions, 8 deletions
@@ -14,6 +14,12 @@ pub fn build(b: *std.Build) void { // Add cross-platform terminal support exe.linkLibC(); + // Add C source file for statvfs helper + exe.addCSourceFile(.{ + .file = b.path("src/statvfs_helper.c"), + .flags = &.{}, + }); + b.installArtifact(exe); const run_cmd = b.addRunArtifact(exe); diff --git a/src/cmd/dir.zig b/src/cmd/dir.zig index 94ca29b..774bd8c 100644 --- a/src/cmd/dir.zig +++ b/src/cmd/dir.zig @@ -5,9 +5,6 @@ const ArrayList = std.ArrayList; const c = @cImport({ @cInclude("errno.h"); @cInclude("stdio.h"); - if (@import("builtin").os.tag != .windows) { - @cInclude("sys/statvfs.h"); - } }); const paths = @import("../paths.zig"); @@ -93,20 +90,31 @@ fn isLeapYear(year: u32) bool { return (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0); } -const GetFreeDiskSpaceError = error{ NotImplemented, AccessDenied }; +const GetFreeDiskSpaceError = error{ NotImplemented, AccessDenied, OutOfMemory }; fn getFreeDiskSpace(path: []const u8) GetFreeDiskSpaceError!u64 { if (@import("builtin").os.tag == .windows) { return error.NotImplemented; } - var stat: c.struct_statvfs = undefined; - if (c.statvfs(path.ptr, &stat) != 0) { - _ = c.perror("statvfs"); + // Create null-terminated path for C function + const allocator = std.heap.page_allocator; + const null_terminated_path = try allocator.dupeZ(u8, path); + defer allocator.free(null_terminated_path); + + const free_space = get_statvfs_free_space(null_terminated_path.ptr); + if (free_space == 0) { return error.AccessDenied; } - return stat.f_frsize * stat.f_bavail; + return free_space; +} + +extern fn statvfs_get_free_space_impl(path: [*:0]const u8) u64; + +fn get_statvfs_free_space(path: [*:0]const u8) u64 { + // Call the C function that uses statvfs internally to avoid struct issues + return statvfs_get_free_space_impl(path); } pub const Dir = struct { @@ -206,6 +214,7 @@ pub const Dir = struct { const bytes_free = getFreeDiskSpace(path) catch |err| switch (err) { error.AccessDenied => 0, error.NotImplemented => 0, + error.OutOfMemory => 0, }; const formatted_total_bytes = try formatWithCommas(ctx.allocator, total_file_bytes); diff --git a/src/statvfs_helper.c b/src/statvfs_helper.c new file mode 100644 index 0000000..8f6a4fe --- /dev/null +++ b/src/statvfs_helper.c @@ -0,0 +1,19 @@ +#include <stdint.h> + +#ifdef _WIN32 +uint64_t statvfs_get_free_space_impl(const char* path) { + // Windows not implemented + (void)path; + return 0; +} +#else +#include <sys/statvfs.h> + +uint64_t statvfs_get_free_space_impl(const char* path) { + struct statvfs stat; + if (statvfs(path, &stat) != 0) { + return 0; + } + return (uint64_t)stat.f_frsize * (uint64_t)stat.f_bavail; +} +#endif
\ No newline at end of file |