From 9900f94afe5556db048b4b147bbf75ff0e0c9974 Mon Sep 17 00:00:00 2001 From: Marcio Giaxa Date: Tue, 18 Dec 2018 16:22:20 -0200 Subject: [PATCH] freebsd: use sysctl to get the current executable path FreeBSD doesn't mount procfs as default on the base system, so we can't depend on it to get the current path, In this case, we use sysctl(3) to retrieves the system information and get the same information. - CTL_KERN: High kernel limits - KERN_PROC: Return selected information about specific running processes. - KERN_PROC_PATHNAME: The path of the process - Process ID: a process ID of -1 implies the current process. --- std/os/freebsd/index.zig | 6 ++++++ std/os/index.zig | 15 ++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/std/os/freebsd/index.zig b/std/os/freebsd/index.zig index 9f9f7f9de04b41929bd81e6bd6e8c2ce6a837544..47f4e8e267f13c8a3065943a7cb40697e1106109 100644 --- a/std/os/freebsd/index.zig +++ b/std/os/freebsd/index.zig @@ -9,6 +9,12 @@ const assert = std.debug.assert; const maxInt = std.math.maxInt; pub const Kevent = c.Kevent; +pub const CTL_KERN = 1; +pub const CTL_DEBUG = 5; + +pub const KERN_PROC = 14; // struct: process entries +pub const KERN_PROC_PATHNAME = 12; // path to executable + pub const PATH_MAX = 1024; pub const STDIN_FILENO = 0; diff --git a/std/os/index.zig b/std/os/index.zig index b49b46e8e55e81a7d46689a631ce0fbd12ea8de3..817f11493c9f136062e778aa9b4ee1655b838cb7 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -2291,7 +2291,20 @@ pub fn selfExePathW(out_buffer: *[windows_util.PATH_MAX_WIDE]u16) ![]u16 { pub fn selfExePath(out_buffer: *[MAX_PATH_BYTES]u8) ![]u8 { switch (builtin.os) { Os.linux => return readLink(out_buffer, "/proc/self/exe"), - Os.freebsd => return readLink(out_buffer, "/proc/curproc/file"), + Os.freebsd => { + var mib = [4]c_int{ posix.CTL_KERN, posix.KERN_PROC, posix.KERN_PROC_PATHNAME, -1}; + var out_len: usize = out_buffer.len; + const err = posix.getErrno(posix.sysctl(&mib, 4, out_buffer, &out_len, null, 0)); + + if (err == 0 ) return mem.toSlice(u8, out_buffer); + + return switch (err) { + posix.EFAULT => error.BadAdress, + posix.EPERM => error.PermissionDenied, + else => unexpectedErrorPosix(err), + }; + + }, Os.windows => { var utf16le_buf: [windows_util.PATH_MAX_WIDE]u16 = undefined; const utf16le_slice = try selfExePathW(&utf16le_buf); -- 2.54.0