authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-06 23:08:59-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-01-07 11:03:37-08:00
log1ddae8585a00e5c6d283336b7421caf480611123
treeec4cfd1542f33a413befadffc6790f08eb852947
parent7e8c7e56964f8d9d20be04e314324f84f9db6146

std.Io.Threaded: add procfs fallback for fileHardLink

oof what a clunky set of functionality we have here

2 files changed, 12 insertions(+), 3 deletions(-)

lib/std/Io/File/Atomic.zig+1-1
...@@ -37,7 +37,7 @@ pub fn deinit(af: *Atomic, io: Io) void {...@@ -37,7 +37,7 @@ pub fn deinit(af: *Atomic, io: Io) void {
37 af.* = undefined;37 af.* = undefined;
38}38}
3939
40pub const LinkError = Dir.HardLinkError || Dir.RenamePreserveError;40pub const LinkError = File.HardLinkError || Dir.RenamePreserveError;
4141
42/// Atomically materializes the file into place, failing with42/// Atomically materializes the file into place, failing with
43/// `error.PathAlreadyExists` if something already exists there.43/// `error.PathAlreadyExists` if something already exists there.
lib/std/Io/Threaded.zig+11-2
...@@ -3525,7 +3525,7 @@ fn dirCreateFileAtomic(...@@ -3525,7 +3525,7 @@ fn dirCreateFileAtomic(
3525 if (dest_dirname) |dirname| {3525 if (dest_dirname) |dirname| {
3526 // This has a nice side effect of preemptively triggering EISDIR or3526 // This has a nice side effect of preemptively triggering EISDIR or
3527 // ENOENT, avoiding the ambiguity below.3527 // ENOENT, avoiding the ambiguity below.
3528 dir.createDirPath(t_io, dirname) catch |err| switch (err) {3528 if (options.make_path) dir.createDirPath(t_io, dirname) catch |err| switch (err) {
3529 // None of these make sense in this context.3529 // None of these make sense in this context.
3530 error.IsDir,3530 error.IsDir,
3531 error.Streaming,3531 error.Streaming,
...@@ -5254,7 +5254,16 @@ fn fileHardLink(...@@ -5254,7 +5254,16 @@ fn fileHardLink(
5254 else5254 else
5255 posix.AT.EMPTY_PATH;5255 posix.AT.EMPTY_PATH;
52565256
5257 return linkat(file.handle, "", new_dir.handle, new_sub_path_posix, flags);5257 return linkat(file.handle, "", new_dir.handle, new_sub_path_posix, flags) catch |err| switch (err) {
5258 error.FileNotFound => {
5259 if (options.follow_symlinks) return error.FileNotFound;
5260 var proc_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
5261 const proc_path = std.fmt.bufPrintSentinel(&proc_buf, "/proc/self/fd/{d}", .{file.handle}, 0) catch
5262 unreachable;
5263 return linkat(posix.AT.FDCWD, proc_path, new_dir.handle, new_sub_path_posix, posix.AT.SYMLINK_FOLLOW);
5264 },
5265 else => |e| return e,
5266 };
5258}5267}
52595268
5260fn linkat(5269fn linkat(