authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-24 12:57:18-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-24 12:57:18-08:00
log315bc10a0cbdb6e1cfa5c7786d7f128e19d2cd39
tree1124d465c7e9bd6930f3462b442b5f30516a9cd9
parent02e560d9ef7885f39e401d9e30ba2c5119ea1891

std.Io.Threaded: dirRealPathFilePosix use libc realpath sometimes

When linking libc, and the directory is the cwd. This avoids bugs on FreeBSD.

1 files changed, 31 insertions(+), 0 deletions(-)

lib/std/Io/Threaded.zig+31
...@@ -4085,6 +4085,37 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o...@@ -4085,6 +4085,37 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
4085 var path_buffer: [posix.PATH_MAX]u8 = undefined;4085 var path_buffer: [posix.PATH_MAX]u8 = undefined;
4086 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);4086 const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
40874087
4088 if (builtin.link_libc and dir.handle == posix.AT.FDCWD) {
4089 if (out_buffer.len < posix.PATH_MAX) return error.NameTooLong;
4090 try current_thread.beginSyscall();
4091 while (true) {
4092 if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| {
4093 current_thread.endSyscall();
4094 assert(redundant_pointer == out_buffer.ptr);
4095 return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len;
4096 }
4097 const err: posix.E = @enumFromInt(std.c._errno().*);
4098 if (err == .INTR) {
4099 try current_thread.checkCancel();
4100 continue;
4101 }
4102 current_thread.endSyscall();
4103 switch (err) {
4104 .INVAL => return errnoBug(err),
4105 .BADF => return errnoBug(err),
4106 .FAULT => return errnoBug(err),
4107 .ACCES => return error.AccessDenied,
4108 .NOENT => return error.FileNotFound,
4109 .OPNOTSUPP => return error.OperationUnsupported,
4110 .NOTDIR => return error.NotDir,
4111 .NAMETOOLONG => return error.NameTooLong,
4112 .LOOP => return error.SymLinkLoop,
4113 .IO => return error.InputOutput,
4114 else => return posix.unexpectedErrno(err),
4115 }
4116 }
4117 }
4118
4088 var flags: posix.O = .{};4119 var flags: posix.O = .{};
4089 if (@hasField(posix.O, "NONBLOCK")) flags.NONBLOCK = true;4120 if (@hasField(posix.O, "NONBLOCK")) flags.NONBLOCK = true;
4090 if (@hasField(posix.O, "CLOEXEC")) flags.CLOEXEC = true;4121 if (@hasField(posix.O, "CLOEXEC")) flags.CLOEXEC = true;