aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2025-12-23 23:31:47 -0800
committerAndrew Kelley <andrew@ziglang.org>2025-12-23 23:31:47 -0800
commita901e9241396a11f807bf40bbd548e25f120deab (patch)
tree9213c467a66e4ff9f6df940f398448e5fb10912a /lib/std
parent2708a3c1ac9f63cce10b70c780dd7b1530d9c26b (diff)
downloadzig-a901e9241396a11f807bf40bbd548e25f120deab.tar.gz
zig-a901e9241396a11f807bf40bbd548e25f120deab.zip
std.Io.Threaded: implement process executable path on darwin
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/Io/Threaded.zig43
-rw-r--r--lib/std/c/darwin.zig2
2 files changed, 32 insertions, 13 deletions
diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig
index 8d383d1c01..086139445f 100644
--- a/lib/std/Io/Threaded.zig
+++ b/lib/std/Io/Threaded.zig
@@ -7152,7 +7152,30 @@ fn processExecutableOpen(userdata: ?*anyopaque, flags: File.OpenFlags) std.proce
const prefixed_path_w = try windows.wToPrefixedFileW(null, image_path_name);
return dirOpenFileWtf16(t, null, prefixed_path_w.span(), flags);
},
- else => @panic("TODO implement processExecutableOpen"),
+ .driverkit,
+ .ios,
+ .maccatalyst,
+ .macos,
+ .tvos,
+ .visionos,
+ .watchos,
+ => {
+ // _NSGetExecutablePath() returns a path that might be a symlink to
+ // the executable. Here it does not matter since we open it.
+ var symlink_path_buf: [posix.PATH_MAX + 1]u8 = undefined;
+ var n: u32 = symlink_path_buf.len;
+ const rc = std.c._NSGetExecutablePath(&symlink_path_buf, &n);
+ if (rc != 0) return error.NameTooLong;
+ const symlink_path = std.mem.sliceTo(&symlink_path_buf, 0);
+ return dirOpenFilePosix(t, .cwd(), symlink_path, flags);
+ },
+ else => {
+ var buffer: [Dir.max_path_bytes]u8 = undefined;
+ const n = try processExecutablePath(t, &buffer);
+ buffer[n] = 0;
+ const executable_path = buffer[0..n :0];
+ return dirOpenFilePosix(t, .cwd(), executable_path, flags);
+ },
}
}
@@ -7168,21 +7191,17 @@ fn processExecutablePath(userdata: ?*anyopaque, out_buffer: []u8) std.process.Ex
.visionos,
.watchos,
=> {
- // Note that _NSGetExecutablePath() will return "a path" to
- // the executable not a "real path" to the executable.
- var symlink_path_buf: [posix.PATH_MAX:0]u8 = undefined;
- var u32_len: u32 = posix.PATH_MAX + 1; // include the sentinel
- const rc = std.c._NSGetExecutablePath(&symlink_path_buf, &u32_len);
+ // _NSGetExecutablePath() returns a path that might be a symlink to
+ // the executable.
+ var symlink_path_buf: [posix.PATH_MAX + 1]u8 = undefined;
+ var n: u32 = symlink_path_buf.len;
+ const rc = std.c._NSGetExecutablePath(&symlink_path_buf, &n);
if (rc != 0) return error.NameTooLong;
-
- var real_path_buf: [posix.PATH_MAX]u8 = undefined;
- const n = Io.Dir.realPathFileAbsolute(ioBasic(t), &symlink_path_buf, &real_path_buf) catch |err| switch (err) {
+ const symlink_path = std.mem.sliceTo(&symlink_path_buf, 0);
+ return Io.Dir.realPathFileAbsolute(ioBasic(t), symlink_path, out_buffer) catch |err| switch (err) {
error.NetworkNotFound => unreachable, // Windows-only
else => |e| return e,
};
- if (n > out_buffer.len) return error.NameTooLong;
- @memcpy(out_buffer[0..n], real_path_buf[0..n]);
- return n;
},
.linux, .serenity => return Io.Dir.readLinkAbsolute(ioBasic(t), "/proc/self/exe", out_buffer) catch |err| switch (err) {
error.UnsupportedReparsePointType => unreachable, // Windows-only
diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig
index f0c4f4c278..d4a7dfd5db 100644
--- a/lib/std/c/darwin.zig
+++ b/lib/std/c/darwin.zig
@@ -349,7 +349,7 @@ pub const VM = struct {
pub const exception_type_t = c_int;
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
-pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int;
+pub extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
pub extern "c" fn _dyld_image_count() u32;
pub extern "c" fn _dyld_get_image_header(image_index: u32) ?*mach_header;
pub extern "c" fn _dyld_get_image_vmaddr_slide(image_index: u32) usize;