From 22f8c9254bb91b5c207afd618096f6b6d28cddcf Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 29 Dec 2023 16:51:20 -0700 Subject: [PATCH] frontend: ignore AccessDenied when writing builtin.zig This issue already existed in master branch, however, the more aggressive caching of builtin.zig in this branch made it happen more often. I added doc comments to AtomicFile to explain when this problem can occur. For the compiler's use case, error.AccessDenied can be simply swallowed because it means the destination file already exists and there is nothing else to do besides proceed with the AtomicFile cleanup. I never solved the mystery of why the log statements weren't printing but those are temporary debugging instruments anyway, and I am already too many yaks deep to whip out another razor. closes #14978 --- lib/std/fs/AtomicFile.zig | 4 ++++ src/Builtin.zig | 30 +++++++++++++----------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/std/fs/AtomicFile.zig b/lib/std/fs/AtomicFile.zig index b090bc95828e..c95ae9bcf2bb 100644 --- a/lib/std/fs/AtomicFile.zig +++ b/lib/std/fs/AtomicFile.zig @@ -65,6 +65,10 @@ pub fn deinit(self: *AtomicFile) void { pub const FinishError = posix.RenameError; +/// On Windows, this function introduces a period of time where some file +/// system operations on the destination file will result in +/// `error.AccessDenied`, including rename operations (such as the one used in +/// this function). pub fn finish(self: *AtomicFile) FinishError!void { assert(self.file_exists); if (self.file_open) { diff --git a/src/Builtin.zig b/src/Builtin.zig index 21681c7ac638..3211dd3a690b 100644 --- a/src/Builtin.zig +++ b/src/Builtin.zig @@ -280,24 +280,19 @@ pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void { fn writeFile(file: *File, mod: *Module) !void { var buf: [std.fs.MAX_PATH_BYTES]u8 = undefined; - var af = mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf) catch |err| { - std.log.warn("unable to create builtin atomic file '{}{s}'", .{ - mod.root, mod.root_src_path, - }); - return err; - }; + var af = try mod.root.atomicFile(mod.root_src_path, .{ .make_path = true }, &buf); defer af.deinit(); - af.file.writeAll(file.source) catch |err| { - std.log.warn("unable to write builtin file data to '{}{s}'", .{ - mod.root, mod.root_src_path, - }); - return err; - }; - af.finish() catch |err| { - std.log.warn("unable to rename atomic builtin file into '{}{s}'", .{ - mod.root, mod.root_src_path, - }); - return err; + try af.file.writeAll(file.source); + af.finish() catch |err| switch (err) { + error.AccessDenied => switch (builtin.os.tag) { + .windows => { + // Very likely happened due to another process or thread + // simultaneously creating the same, correct builtin.zig file. + // This is not a problem; ignore it. + }, + else => return err, + }, + else => return err, }; file.stat = .{ @@ -307,6 +302,7 @@ fn writeFile(file: *File, mod: *Module) !void { }; } +const builtin = @import("builtin"); const std = @import("std"); const Allocator = std.mem.Allocator; const build_options = @import("build_options");