| ... | @@ -63,3 +63,34 @@ pub fn statFile(self: Dir, sub_path: [:0]const u8) !File.Stat { | ... | @@ -63,3 +63,34 @@ pub fn statFile(self: Dir, sub_path: [:0]const u8) !File.Stat { |
| 63 | if (os == .linux) | 63 | if (os == .linux) |
| 64 | return .fromPosix(try sys_linux.fstatat(@intFromEnum(self.fd), sub_path, 0)); | 64 | return .fromPosix(try sys_linux.fstatat(@intFromEnum(self.fd), sub_path, 0)); |
| 65 | } | 65 | } |
| | 66 | |
| | 67 | pub 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 | } |