zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

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:
Mlib/std/Io/Threaded.zig | 31+++++++++++++++++++++++++++++++
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;