aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorMichael Dusan <michael.dusan@gmail.com>2025-12-20 18:25:04 -0500
committerAndrew Kelley <andrew@ziglang.org>2025-12-23 22:15:11 -0800
commit7014976d3dc38320257871f0e218ded987843bc1 (patch)
treeeeb499671f16a669982bbc3dffa86e1e6794a995 /lib/std
parent8fdfeb624dae7d60187c7a2c44c9624cca1bd461 (diff)
downloadzig-7014976d3dc38320257871f0e218ded987843bc1.tar.gz
zig-7014976d3dc38320257871f0e218ded987843bc1.zip
openbsd: avoid error.OperationUnsupported
- realPathPosix does not support OpenBSD - change processExecutablePath OpenBSD section to use std.c.realpath
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Io/Threaded.zig72
1 files changed, 47 insertions, 25 deletions
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
index 0e67fd1a9d..c40ce3866c 100644
--- a/lib/std/Io/Threaded.zig
+++ b/lib/std/Io/Threaded.zig
@@ -7191,35 +7191,57 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
return error.FileNotFound;
const argv0 = std.mem.span(std.os.argv[0]);
- if (std.mem.indexOf(u8, argv0, "/") != null) {
+ if (std.mem.findScalar(u8, argv0, std.fs.path.sep_posix) != null) {
// argv[0] is a path (relative or absolute): use realpath(3) directly
- var real_path_buf: [posix.PATH_MAX]u8 = undefined;
- const real_path_len = Io.Dir.realPathFileAbsolute(ioBasic(t), argv0, &real_path_buf) catch |err| switch (err) {
- error.NetworkNotFound => unreachable, // Windows-only
- else => |e| return e,
- };
- if (real_path_len > out_buffer.len)
+ const current_thread = Thread.getCurrent(t);
+ var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
+ {
+ try current_thread.beginSyscall();
+ defer current_thread.endSyscall();
+ _ = std.c.realpath(std.os.argv[0], &resolved_buf) orelse switch (@as(std.c.E, @enumFromInt(std.c._errno().*))) {
+ .SUCCESS => unreachable,
+ .ACCES => return error.AccessDenied,
+ .INVAL => unreachable, // the pathname argument is a null pointer
+ .IO => return error.InputOutput,
+ .LOOP => return error.SymLinkLoop,
+ .NAMETOOLONG => return error.NameTooLong,
+ .NOENT => return error.FileNotFound,
+ .NOTDIR => return error.NotDir,
+ .NOMEM => unreachable, // sufficient storage space is unavailable for allocation
+ else => |err| return posix.unexpectedErrno(err),
+ };
+ }
+ const resolved = std.mem.sliceTo(&resolved_buf, 0);
+ if (resolved.len > out_buffer.len)
return error.NameTooLong;
- @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]);
- return real_path_len;
+ @memcpy(out_buffer[0..resolved.len], resolved);
+ return resolved.len;
} else if (argv0.len != 0) {
- // argv[0] is not empty (and not a path): search it inside PATH
+ // argv[0] is not empty (and not a path): search PATH
+ const current_thread = Thread.getCurrent(t);
const PATH = posix.getenvZ("PATH") orelse return error.FileNotFound;
- var path_it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter);
- while (path_it.next()) |a_path| {
- var resolved_path_buf: [posix.PATH_MAX - 1:0]u8 = undefined;
- const resolved_path = std.fmt.bufPrintSentinel(&resolved_path_buf, "{s}/{s}", .{
- a_path, std.os.argv[0],
- }, 0) catch continue;
-
- var real_path_buf: [posix.PATH_MAX]u8 = undefined;
- if (Io.Dir.realPathFileAbsolute(ioBasic(t), resolved_path, &real_path_buf)) |real_path_len| {
- // found a file, and hope it is the right file
- if (real_path_len > out_buffer.len)
- return error.NameTooLong;
- @memcpy(out_buffer[0..real_path_len], real_path_buf[0..real_path_len]);
- return real_path_len;
- } else |_| continue;
+ var it = std.mem.tokenizeScalar(u8, PATH, std.fs.path.delimiter);
+ while (it.next()) |dir| {
+ var prospect_buf: [std.c.PATH_MAX]u8 = undefined;
+ _ = std.fmt.bufPrintSentinel(
+ &prospect_buf,
+ "{s}" ++ std.fs.path.sep_str_posix ++ "{s}",
+ .{ dir, std.os.argv[0] },
+ 0,
+ ) catch continue;
+
+ var resolved_buf: [std.c.PATH_MAX]u8 = undefined;
+ try current_thread.beginSyscall();
+ _ = std.c.realpath(@ptrCast(&prospect_buf), &resolved_buf) orelse {
+ current_thread.endSyscall();
+ continue;
+ };
+ current_thread.endSyscall();
+ const resolved = std.mem.sliceTo(&resolved_buf, 0);
+ if (resolved.len > out_buffer.len)
+ return error.NameTooLong;
+ @memcpy(out_buffer[0..resolved.len], resolved);
+ return resolved.len;
}
}
return error.FileNotFound;