| author | |
| committer | |
| log | cb635e084b0c36e3c7a6bf63f49f7e7e9918532d |
| tree | 92d53f835566b630fd39f44a5e8c8ef9b3339add |
| parent | 9ee4530b9b38805f88a1e3df4b4b74db240f05df |
Windows gives AccessDenied if you delete a directory which contains open
file handles. This could be triggered when using CacheMode.whole when
cross compiling macho test binaries.2 files changed, 20 insertions(+), 10 deletions(-)
src/Compilation.zig+14-2| ... | ... | @@ -2390,9 +2390,21 @@ pub fn update(comp: *Compilation) !void { |
| 2390 | 2390 | const o_sub_path = try std.fs.path.join(comp.gpa, &[_][]const u8{ "o", &digest }); |
| 2391 | 2391 | defer comp.gpa.free(o_sub_path); |
| 2392 | 2392 | |
| 2393 | // Work around windows `AccessDenied` if any files within this directory are open | |
| 2394 | // by doing the makeExecutable/makeWritable dance. | |
| 2395 | const need_writable_dance = builtin.os.tag == .windows and comp.bin_file.file != null; | |
| 2396 | if (need_writable_dance) { | |
| 2397 | try comp.bin_file.makeExecutable(); | |
| 2398 | } | |
| 2399 | ||
| 2393 | 2400 | try comp.bin_file.renameTmpIntoCache(comp.local_cache_directory, tmp_dir_sub_path, o_sub_path); |
| 2394 | 2401 | comp.wholeCacheModeSetBinFilePath(&digest); |
| 2395 | 2402 | |
| 2403 | // Has to be after the `wholeCacheModeSetBinFilePath` above. | |
| 2404 | if (need_writable_dance) { | |
| 2405 | try comp.bin_file.makeWritable(); | |
| 2406 | } | |
| 2407 | ||
| 2396 | 2408 | // This is intentionally sandwiched between renameTmpIntoCache() and writeManifest(). |
| 2397 | 2409 | if (comp.bin_file.options.module) |module| { |
| 2398 | 2410 | // We need to set the zig_cache_artifact_directory for -femit-asm, -femit-llvm-ir, |
| ... | ... | @@ -3207,8 +3219,8 @@ fn processOneJob(comp: *Compilation, job: Job) !void { |
| 3207 | 3219 | // TODO Surface more error details. |
| 3208 | 3220 | comp.lockAndSetMiscFailure( |
| 3209 | 3221 | .mingw_crt_file, |
| 3210 | "unable to build mingw-w64 CRT file: {s}", | |
| 3211 | .{@errorName(err)}, | |
| 3222 | "unable to build mingw-w64 CRT file {s}: {s}", | |
| 3223 | .{ @tagName(crt_file), @errorName(err) }, | |
| 3212 | 3224 | ); |
| 3213 | 3225 | }; |
| 3214 | 3226 | }, |
src/link.zig+6-8| ... | ... | @@ -403,10 +403,8 @@ pub const File = struct { |
| 403 | 403 | try emit.directory.handle.copyFile(emit.sub_path, emit.directory.handle, emit.sub_path, .{}); |
| 404 | 404 | } |
| 405 | 405 | } |
| 406 | if (base.intermediary_basename == null) { | |
| 407 | f.close(); | |
| 408 | base.file = null; | |
| 409 | } | |
| 406 | f.close(); | |
| 407 | base.file = null; | |
| 410 | 408 | }, |
| 411 | 409 | .coff, .elf, .plan9, .wasm => if (base.file) |f| { |
| 412 | 410 | if (base.intermediary_basename != null) { |
| ... | ... | @@ -777,7 +775,7 @@ pub const File = struct { |
| 777 | 775 | _ = base; |
| 778 | 776 | while (true) { |
| 779 | 777 | if (builtin.os.tag == .windows) { |
| 780 | // workaround windows `renameW` can't fail with `PathAlreadyExists` | |
| 778 | // Work around windows `renameW` can't fail with `PathAlreadyExists` | |
| 781 | 779 | // See https://github.com/ziglang/zig/issues/8362 |
| 782 | 780 | if (cache_directory.handle.access(o_sub_path, .{})) |_| { |
| 783 | 781 | try cache_directory.handle.deleteTree(o_sub_path); |
| ... | ... | @@ -791,9 +789,9 @@ pub const File = struct { |
| 791 | 789 | tmp_dir_sub_path, |
| 792 | 790 | cache_directory.handle, |
| 793 | 791 | o_sub_path, |
| 794 | ) catch |err| switch (err) { | |
| 795 | error.AccessDenied => unreachable, // We are most likely trying to move a dir with open handles to its resources | |
| 796 | else => |e| return e, | |
| 792 | ) catch |err| { | |
| 793 | log.err("unable to rename cache dir {s} to {s}: {s}", .{ tmp_dir_sub_path, o_sub_path, @errorName(err) }); | |
| 794 | return err; | |
| 797 | 795 | }; |
| 798 | 796 | break; |
| 799 | 797 | } else { |