diff --git a/lib/std/fs/Dir.zig b/lib/std/fs/Dir.zig index 8a1d38996e..0f996affcc 100644 --- a/lib/std/fs/Dir.zig +++ b/lib/std/fs/Dir.zig @@ -1125,9 +1125,17 @@ pub fn makePath(self: Dir, sub_path: []const u8) !void { while (true) { self.makeDir(component.path) catch |err| switch (err) { error.PathAlreadyExists => { - // TODO stat the file and return an error if it's not a directory + // stat the file and return an error if it's not a directory // this is important because otherwise a dangling symlink // could cause an infinite loop + check_dir: { + // workaround for windows, see https://github.com/ziglang/zig/issues/16738 + const fstat = self.statFile(component.path) catch |stat_err| switch (stat_err) { + error.IsDir => break :check_dir, + else => |e| return e, + }; + if (fstat.kind != .directory) return error.NotDir; + } }, error.FileNotFound => |e| { component = it.previous() orelse return e; diff --git a/lib/std/fs/test.zig b/lib/std/fs/test.zig index 0cdcd0a631..4a8cc19517 100644 --- a/lib/std/fs/test.zig +++ b/lib/std/fs/test.zig @@ -1089,6 +1089,16 @@ test "makePath in a directory that no longer exists" { try testing.expectError(error.FileNotFound, tmp.dir.makePath("sub-path")); } +test "makePath but sub_path contains pre-existing file" { + var tmp = tmpDir(.{}); + defer tmp.cleanup(); + + try tmp.dir.makeDir("foo"); + try tmp.dir.writeFile("foo/bar", ""); + + try testing.expectError(error.NotDir, tmp.dir.makePath("foo/bar/baz")); +} + fn expectDir(dir: Dir, path: []const u8) !void { var d = try dir.openDir(path, .{}); d.close();