fix link.renameTmpIntoCache on windows when dest dir exists.

Previously it would fail as `renameW` do not ever fail with
`PathAlreadyExists`.

As a workaround we check for dest dir existence before rename
on Windows.
This commit is contained in:
jagt 2022-04-12 12:01:47 +08:00 committed by Andrew Kelley
parent c4aac28a42
commit b9d86c6bc8

View File

@ -717,19 +717,38 @@ pub const File = struct {
// directly, and remove this function from link.zig.
_ = base;
while (true) {
std.fs.rename(
cache_directory.handle,
tmp_dir_sub_path,
cache_directory.handle,
o_sub_path,
) catch |err| switch (err) {
error.PathAlreadyExists => {
if (builtin.os.tag == .windows) {
// workaround windows `renameW` can't fail with `PathAlreadyExists`
// See https://github.com/ziglang/zig/issues/8362
if (cache_directory.handle.access(o_sub_path, .{})) |_| {
try cache_directory.handle.deleteTree(o_sub_path);
continue;
},
else => |e| return e,
};
break;
} else |err| switch (err) {
error.FileNotFound => {},
else => |e| return e,
}
try std.fs.rename(
cache_directory.handle,
tmp_dir_sub_path,
cache_directory.handle,
o_sub_path,
);
break;
} else {
std.fs.rename(
cache_directory.handle,
tmp_dir_sub_path,
cache_directory.handle,
o_sub_path,
) catch |err| switch (err) {
error.PathAlreadyExists => {
try cache_directory.handle.deleteTree(o_sub_path);
continue;
},
else => |e| return e,
};
break;
}
}
}