authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2025-12-20 18:25:04-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-12-23 22:15:11-08:00
log7014976d3dc38320257871f0e218ded987843bc1
treeeeb499671f16a669982bbc3dffa86e1e6794a995
parent8fdfeb624dae7d60187c7a2c44c9624cca1bd461

openbsd: avoid error.OperationUnsupported

- realPathPosix does not support OpenBSD - change processExecutablePath OpenBSD section to use std.c.realpath

1 files changed, 47 insertions(+), 25 deletions(-)

lib/std/Io/Threaded.zig+47-25
......@@ -7191,35 +7191,57 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
71917191 return error.FileNotFound;
71927192
71937193 const argv0 = std.mem.span(std.os.argv[0]);
7194 if (std.mem.indexOf(u8, argv0, "/") != null) {
7194 if (std.mem.findScalar(u8, argv0, std.fs.path.sep_posix) != null) {
71957195 // argv[0] is a path (relative or absolute): use realpath(3) directly
7196 var real_path_buf: [posix.PATH_MAX]u8 = undefined;
7197 const real_path_len = Io.Dir.realPathFileAbsolute(ioBasic(t), argv0, &real_path_buf) catch |err| switch (err) {
7198 error.NetworkNotFound => unreachable, // Windows-only
7199 else => |e| return e,
7200 };
7201 if (real_path_len > out_buffer.len)
7196 const current_thread = Thread.getCurrent(t);
7197 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7198 {
7199 try current_thread.beginSyscall();
7200 defer current_thread.endSyscall();
7201 _ = std.c.realpath(std.os.argv[0], &resolved_buf) orelse switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
7202 .SUCCESS => unreachable,
7203 .ACCES => return error.AccessDenied,
7204 .INVAL => unreachable, // the pathname argument is a null pointer
7205 .IO => return error.InputOutput,
7206 .LOOP => return error.SymLinkLoop,
7207 .NAMETOOLONG => return error.NameTooLong,
7208 .NOENT => return error.FileNotFound,
7209 .NOTDIR => return error.NotDir,
7210 .NOMEM => unreachable, // sufficient storage space is unavailable for allocation
7211 else => |err| return posix.unexpectedErrno(err),
7212 };
7213 }
7214 const resolved = std.mem.sliceTo(&resolved_buf, 0);
7215 if (resolved.len > out_buffer.len)
72027216 return error.NameTooLong;
7203 @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]);
7204 return real_path_len;
7217 @memcpy(out_buffer[0..resolved.len], resolved);
7218 return resolved.len;
72057219 } else if (argv0.len != 0) {
7206 // argv[0] is not empty (and not a path): search it inside PATH
7220 // argv[0] is not empty (and not a path): search PATH
7221 const current_thread = Thread.getCurrent(t);
72077222 const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound;
7208 var path_it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter);
7209 while (path_it.next()) |a_path| {
7210 var resolved_path_buf: [posix.PATH_MAX - 1:0]u8 = undefined;
7211 const resolved_path = std.fmt.bufPrintSentinel(&resolved_path_buf, "{s}/{s}", .{
7212 a_path, std.os.argv[0],
7213 }, 0) catch continue;
7214
7215 var real_path_buf: [posix.PATH_MAX]u8 = undefined;
7216 if (Io.Dir.realPathFileAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path_len| {
7217 // found a file, and hope it is the right file
7218 if (real_path_len > out_buffer.len)
7219 return error.NameTooLong;
7220 @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]);
7221 return real_path_len;
7222 } else |_| continue;
7223 var it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter);
7224 while (it.next()) |dir| {
7225 var prospect_buf: [std.c.PATH_MAX]u8 = undefined;
7226 _ = std.fmt.bufPrintSentinel(
7227 &prospect_buf,
7228 "{s}" ++ std.fs.path.sep_str_posix ++ "{s}",
7229 .{ dir, std.os.argv[0] },
7230 0,
7231 ) catch continue;
7232
7233 var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
7234 try current_thread.beginSyscall();
7235 _ = std.c.realpath(@ptrCast(&prospect_buf), &resolved_buf) orelse {
7236 current_thread.endSyscall();
7237 continue;
7238 };
7239 current_thread.endSyscall();
7240 const resolved = std.mem.sliceTo(&resolved_buf, 0);
7241 if (resolved.len > out_buffer.len)
7242 return error.NameTooLong;
7243 @memcpy(out_buffer[0..resolved.len], resolved);
7244 return resolved.len;
72237245 }
72247246 }
72257247 return error.FileNotFound;