summaryrefslogtreecommitdiff
path: root/src/self_exe.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/self_exe.zig')
-rw-r--r--src/self_exe.zig90
1 files changed, 0 insertions, 90 deletions
diff --git a/src/self_exe.zig b/src/self_exe.zig
deleted file mode 100644
index 6eda92d..0000000
--- a/src/self_exe.zig
+++ /dev/null
@@ -1,90 +0,0 @@
-//! Resolve the absolute path of the currently running executable.
-//!
-//! Used to find the panto binary so we can launch ourselves as `panto
-//! lua` from inside the bootstrap (the embedded luarocks shells out to
-//! its configured `LUA` interpreter, which we point at a wrapper script
-//! that exec's panto's `lua` subcommand).
-//!
-//! Zig's standard library doesn't expose a portable `selfExePath` in
-//! the current API, so this module wraps the per-OS syscall.
-//!
-//! Supported:
-//! - macOS / iOS / tvOS / watchOS: `_NSGetExecutablePath` + realpath
-//! - Linux: `readlink("/proc/self/exe")`
-//! - FreeBSD / NetBSD / DragonFly: `readlink("/proc/curproc/file")`
-//!
-//! Other targets currently return `error.SelfExePathUnavailable`.
-
-const std = @import("std");
-const builtin = @import("builtin");
-
-const Allocator = std.mem.Allocator;
-
-pub const ResolveError = error{
- SelfExePathUnavailable,
- SelfExePathTooLong,
- SelfExePathReadFailed,
- OutOfMemory,
-};
-
-/// Return the absolute, symlink-resolved path of the current process's
-/// executable. Caller owns the returned slice.
-pub fn selfExePathAlloc(allocator: Allocator) ResolveError![]u8 {
- var buf: [std.fs.max_path_bytes]u8 = undefined;
- const path = try selfExePath(&buf);
- return allocator.dupe(u8, path);
-}
-
-/// Fill `buf` with the absolute path. Returns the slice that was used.
-pub fn selfExePath(buf: []u8) ResolveError![]u8 {
- return switch (builtin.os.tag) {
- .macos, .ios, .tvos, .watchos => try macosSelfExePath(buf),
- .linux => try readLinkSelfExe(buf, "/proc/self/exe"),
- .freebsd, .netbsd, .dragonfly => try readLinkSelfExe(buf, "/proc/curproc/file"),
- else => return ResolveError.SelfExePathUnavailable,
- };
-}
-
-fn readLinkSelfExe(buf: []u8, link_path: []const u8) ResolveError![]u8 {
- const link_z = std.posix.toPosixPath(link_path) catch return ResolveError.SelfExePathTooLong;
- const n = posixReadlink(&link_z, buf) catch return ResolveError.SelfExePathReadFailed;
- return buf[0..n];
-}
-
-/// Thin wrapper around the POSIX `readlink` syscall using libc directly,
-/// since std.posix's surface here has been in flux. libc is linked into
-/// panto already (Lua needs it), so this stays cheap.
-extern "c" fn readlink(path: [*:0]const u8, buf: [*]u8, bufsize: usize) isize;
-
-fn posixReadlink(path: [*:0]const u8, buf: []u8) !usize {
- const n = readlink(path, buf.ptr, buf.len);
- if (n < 0) return error.SelfExePathReadFailed;
- return @intCast(n);
-}
-
-extern "c" fn _NSGetExecutablePath(buf: [*]u8, bufsize: *u32) c_int;
-
-fn macosSelfExePath(buf: []u8) ResolveError![]u8 {
- var stage: [std.fs.max_path_bytes]u8 = undefined;
- var size: u32 = @intCast(stage.len);
- if (_NSGetExecutablePath(&stage, &size) != 0) return ResolveError.SelfExePathTooLong;
- // _NSGetExecutablePath populates `size` on overflow; on success
- // we need to find the NUL ourselves.
- const len = std.mem.indexOfScalar(u8, &stage, 0) orelse return ResolveError.SelfExePathTooLong;
-
- // The returned path may include `..` and symlinks; canonicalize so
- // downstream consumers don't have to. realpath(3) on POSIX, both
- // libc-resident on macOS and Linux.
- const path_z = std.posix.toPosixPath(stage[0..len]) catch return ResolveError.SelfExePathTooLong;
-
- // libc realpath: NULL second arg => malloc; we want stack buffer.
- var real_buf: [std.fs.max_path_bytes]u8 = undefined;
- if (libc_realpath(&path_z, &real_buf) == null) return ResolveError.SelfExePathReadFailed;
- const real_len = std.mem.indexOfScalar(u8, &real_buf, 0) orelse return ResolveError.SelfExePathTooLong;
- if (real_len > buf.len) return ResolveError.SelfExePathTooLong;
- @memcpy(buf[0..real_len], real_buf[0..real_len]);
- return buf[0..real_len];
-}
-
-extern "c" fn realpath(path: [*:0]const u8, resolved: [*]u8) ?[*]u8;
-const libc_realpath = realpath;