Commit 6b2709616e

Andrew Kelley <andrew@ziglang.org>
2023-12-30 00:51:20
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
1 parent a89d687
Changed files (2)
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) {
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");