authorgravatar for jagt@live.comjagt <jagt@live.com> 2022-04-12 12:01:47+08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-04-12 06:01:25-04:00
logb9d86c6bc8e5d475ed8613bb241d1520377e629c
tree20371ff709d5653d4c24fae485b6fad1be6b5392
parentc4aac28a426351c7718c605e0c06d9e69b60772e

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.

1 files changed, 30 insertions(+), 11 deletions(-)

src/link.zig+30-11
...@@ -717,19 +717,38 @@ pub const File = struct {...@@ -717,19 +717,38 @@ pub const File = struct {
717 // directly, and remove this function from link.zig.717 // directly, and remove this function from link.zig.
718 _ = base;718 _ = base;
719 while (true) {719 while (true) {
720 std.fs.rename(720 if (builtin.os.tag == .windows) {
721 cache_directory.handle,721 // workaround windows `renameW` can't fail with `PathAlreadyExists`
722 tmp_dir_sub_path,722 // See https://github.com/ziglang/zig/issues/8362
723 cache_directory.handle,723 if (cache_directory.handle.access(o_sub_path, .{})) |_| {
724 o_sub_path,
725 ) catch |err| switch (err) {
726 error.PathAlreadyExists => {
727 try cache_directory.handle.deleteTree(o_sub_path);724 try cache_directory.handle.deleteTree(o_sub_path);
728 continue;725 continue;
729 },726 } else |err| switch (err) {
730 else => |e| return e,727 error.FileNotFound => {},
731 };728 else => |e| return e,
732 break;729 }
730 try std.fs.rename(
731 cache_directory.handle,
732 tmp_dir_sub_path,
733 cache_directory.handle,
734 o_sub_path,
735 );
736 break;
737 } else {
738 std.fs.rename(
739 cache_directory.handle,
740 tmp_dir_sub_path,
741 cache_directory.handle,
742 o_sub_path,
743 ) catch |err| switch (err) {
744 error.PathAlreadyExists => {
745 try cache_directory.handle.deleteTree(o_sub_path);
746 continue;
747 },
748 else => |e| return e,
749 };
750 break;
751 }
733 }752 }
734 }753 }
735754