diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2025-12-23 23:31:47 -0800 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2025-12-23 23:31:47 -0800 |
| commit | a901e9241396a11f807bf40bbd548e25f120deab (patch) | |
| tree | 9213c467a66e4ff9f6df940f398448e5fb10912a /lib/std | |
| parent | 2708a3c1ac9f63cce10b70c780dd7b1530d9c26b (diff) | |
| download | zig-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.zig | 43 | ||||
| -rw-r--r-- | lib/std/c/darwin.zig | 2 |
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; |
