authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-30 01:48:41 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-30 01:48:41 -07:00
logff118ab7234a8881b4c03a47e27ac9b204309ce1
tree531f99578e6f57326b3b7b8fe78848191466e34b
parent18b00c5c5d25e230ff4f3ea07fadb2a1d54a773d
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

more macos support and things for zigmod


3 files changed, 97 insertions(+), 0 deletions(-)

Dir.zig+67
......@@ -146,6 +146,7 @@ pub fn iterate(self: Dir) Iterator {
146146 .buf = undefined,
147147 .idx = 0,
148148 .len = 0,
149 .seek = 0,
149150 };
150151}
151152
......@@ -154,8 +155,28 @@ pub const Iterator = struct {
154155 buf: [1024]u8,
155156 idx: usize,
156157 len: usize,
158 seek: c_long,
157159
158160 pub fn next(iter: *Iterator) !?Entry {
161 if (os == .macos) {
162 if (iter.idx == iter.len) {
163 const len = try sys.getdirentries(@intFromEnum(iter.dir.fd), &iter.buf, &iter.seek);
164 if (len == 0) return null;
165 iter.idx = 0;
166 iter.len = len;
167 }
168 const ent: *align(1) sys.struct_dirent = @ptrCast(&iter.buf[iter.idx]);
169 iter.idx += ent.reclen;
170 ent.name[ent.namlen] = 0;
171 const name = ent.name[0..ent.namlen :0];
172 if (std.mem.eql(u8, name, ".")) return next(iter);
173 if (std.mem.eql(u8, name, "..")) return next(iter);
174 if (ent.ino == 0) return next(iter);
175 return .{
176 .name = name,
177 .type = ent.type,
178 };
179 }
159180 if (iter.idx == iter.len) {
160181 const len = try sys.getdents(@intFromEnum(iter.dir.fd), &iter.buf);
161182 if (len == 0) return null;
......@@ -328,3 +349,49 @@ pub const AccessMode = packed struct(c_uint) {
328349 executable: bool = false,
329350 _: u29 = 0,
330351};
352
353pub fn realpath(self: Dir, sub_path: [:0]const u8, buf: *[sys.PATH_MAX]u8) ![:0]u8 {
354 if (std.mem.eql(u8, sub_path, ".")) {
355 if (@intFromEnum(self.fd) == sys.AT.FDCWD) {
356 return nfs.cwdpath(buf);
357 }
358 return nfs.realdpath(self.fd, buf);
359 }
360 var file = try self.openFile(sub_path, .{});
361 defer file.close();
362 return nfs.realdpath(file.fd, buf);
363}
364
365pub fn realpathAlloc(self: Dir, allocator: std.mem.Allocator, sub_path: [:0]const u8) ![:0]u8 {
366 var buf: [sys.PATH_MAX]u8 = undefined;
367 const actual = try self.realpath(sub_path, &buf);
368 return allocator.dupeZ(u8, actual);
369}
370
371pub fn deleteFile(self: Dir, sub_path: [:0]const u8) !void {
372 return sys.unlinkat(@intFromEnum(self.fd), sub_path.ptr, 0);
373}
374
375pub fn deleteDir(self: Dir, sub_path: [:0]const u8) !void {
376 return sys.unlinkat(@intFromEnum(self.fd), sub_path.ptr, sys.AT.REMOVEDIR);
377}
378
379pub fn deleteTree(self: Dir, sub_path: [:0]const u8) !void {
380 var dir = try self.openDir(sub_path, .{});
381 {
382 errdefer dir.close();
383 var iter = dir.iterate();
384 while (try iter.next()) |entry| {
385 switch (entry.type) {
386 .DIR => {
387 try dir.deleteTree(entry.name);
388 },
389 else => {
390 try dir.deleteFile(entry.name);
391 },
392 }
393 }
394 dir.close();
395 }
396 try self.deleteDir(sub_path);
397}
File.zig+8
......@@ -211,3 +211,11 @@ pub fn mmap(self: File) ![]const u8 {
211211pub fn utime(self: File, times: [2]sys.struct_timespec) !void {
212212 return sys.futimens(@intFromEnum(self.fd), times);
213213}
214
215pub fn isatty(self: File) bool {
216 return sys.libc.isatty(@intFromEnum(self.fd)) == 1;
217}
218
219pub fn seekTo(self: File, pos: u64) !void {
220 return sys.lseek(@intFromEnum(self.fd), @bitCast(pos), sys.SEEK.SET);
221}
nfs.zig+22
......@@ -1,6 +1,7 @@
11const std = @import("std");
22const builtin = @import("builtin");
33const sys_linux = @import("sys-linux");
4const nio = @import("nio");
45
56pub const Dir = @import("./Dir.zig");
67pub const File = @import("./File.zig");
......@@ -25,6 +26,12 @@ pub fn cwd() Dir {
2526 return .{ .fd = @enumFromInt(sys.AT.FDCWD) };
2627}
2728
29pub fn cwdpath(buf: []u8) ![:0]u8 {
30 const ptr = try sys.getcwd(buf);
31 const str = std.mem.sliceTo(ptr, 0);
32 return str;
33}
34
2835pub fn stdin() File {
2936 return .{ .fd = @enumFromInt(0) };
3037}
......@@ -80,3 +87,18 @@ pub fn pipe2(flag: c_int) ![2]File {
8087pub fn dup2(fd1: Handle, fd2: Handle) !void {
8188 return sys.dup2(@intFromEnum(fd1), @intFromEnum(fd2));
8289}
90
91pub fn realdpath(fd: Handle, buf: *[sys.PATH_MAX]u8) ![:0]u8 {
92 if (os == .linux) {
93 var dbuf: [64]u8 = undefined;
94 const str = nio.fmt.bufPrintZ(&dbuf, "/proc/self/fd/{d}", .{fd}) catch unreachable;
95 return sys.readlinkat(@intFromEnum(cwd().fd), str, buf);
96 }
97 if (os == .macos) {
98 @memset(buf, 0);
99 const rc = sys.libc.fcntl(@intFromEnum(fd), sys.F.GETPATH, buf.ptr);
100 if (rc == -1) return sys.errno.fromInt(sys.errno.fromLibC());
101 const idx = std.mem.indexOfScalar(u8, buf, 0).?;
102 return buf[0..idx :0];
103 }
104}