authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2025-12-28 22:18:56 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2025-12-28 22:18:56 -08:00
logfc99d96ee5bccb61b06c94470ae0ef5f930e0df2
treebc3bd1f81945816ee95b46296426cbedbc6bb28f
parentcf9642a62718e1275e7ff2b3aad7c62345cadccd

Dir: add makePath


1 files changed, 31 insertions(+), 0 deletions(-)

Dir.zig+31
......@@ -63,3 +63,34 @@ pub fn statFile(self: Dir, sub_path: [:0]const u8) !File.Stat {
6363 if (os == .linux)
6464 return .fromPosix(try sys_linux.fstatat(@intFromEnum(self.fd), sub_path, 0));
6565}
66
67pub fn makePath(self: Dir, sub_path: [:0]const u8) !void {
68 var it = try std.fs.path.componentIterator(sub_path);
69 var component = it.last() orelse return;
70 var zuffer: [sys_linux.NAME_MAX + 1]u8 = undefined;
71 while (true) {
72 @memcpy(zuffer[0..component.path.len], component.path);
73 zuffer[component.path.len] = 0;
74 self.makeDir(zuffer[0..component.path.len :0]) catch |err| switch (err) {
75 error.EEXIST => {
76 // stat the file and return an error if it's not a directory
77 // this is important because otherwise a dangling symlink
78 // could cause an infinite loop
79 check_dir: {
80 // workaround for windows, see https://github.com/ziglang/zig/issues/16738
81 const fstat = self.statFile(zuffer[0..component.path.len :0]) catch |stat_err| switch (stat_err) {
82 error.EISDIR => break :check_dir,
83 else => |e| return e,
84 };
85 if (fstat.kind() != .directory) return error.NotDir;
86 }
87 },
88 error.ENOENT => |e| {
89 component = it.previous() orelse return e;
90 continue;
91 },
92 else => |e| return e,
93 };
94 component = it.next() orelse return;
95 }
96}