commit 315bc10a0cbdb6e1cfa5c7786d7f128e19d2cd39 (tree)
parent 02e560d9ef7885f39e401d9e30ba2c5119ea1891
Author: Andrew Kelley <andrew@ziglang.org>
Date: Wed, 24 Dec 2025 12:57:18 -0800
std.Io.Threaded: dirRealPathFilePosix use libc realpath sometimes
When linking libc, and the directory is the cwd.
This avoids bugs on FreeBSD.
Diffstat:
1 file changed, 31 insertions(+), 0 deletions(-)
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
@@ -4085,6 +4085,37 @@ fn dirRealPathFilePosix(userdata: ?*anyopaque, dir: Dir, sub_path: []const u8, o
var path_buffer: [posix.PATH_MAX]u8 = undefined;
const sub_path_posix = try pathToPosix(sub_path, &path_buffer);
+ if (builtin.link_libc and dir.handle == posix.AT.FDCWD) {
+ if (out_buffer.len < posix.PATH_MAX) return error.NameTooLong;
+ try current_thread.beginSyscall();
+ while (true) {
+ if (std.c.realpath(sub_path_posix, out_buffer.ptr)) |redundant_pointer| {
+ current_thread.endSyscall();
+ assert(redundant_pointer == out_buffer.ptr);
+ return std.mem.indexOfScalar(u8, out_buffer, 0) orelse out_buffer.len;
+ }
+ const err: posix.E = @enumFromInt(std.c._errno().*);
+ if (err == .INTR) {
+ try current_thread.checkCancel();
+ continue;
+ }
+ current_thread.endSyscall();
+ switch (err) {
+ .INVAL => return errnoBug(err),
+ .BADF => return errnoBug(err),
+ .FAULT => return errnoBug(err),
+ .ACCES => return error.AccessDenied,
+ .NOENT => return error.FileNotFound,
+ .OPNOTSUPP => return error.OperationUnsupported,
+ .NOTDIR => return error.NotDir,
+ .NAMETOOLONG => return error.NameTooLong,
+ .LOOP => return error.SymLinkLoop,
+ .IO => return error.InputOutput,
+ else => return posix.unexpectedErrno(err),
+ }
+ }
+ }
+
var flags: posix.O = .{};
if (@hasField(posix.O, "NONBLOCK")) flags.NONBLOCK = true;
if (@hasField(posix.O, "CLOEXEC")) flags.CLOEXEC = true;