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.
This commit is contained in:
Marcio Giaxa 2018-12-18 16:22:20 -02:00
parent 1811e7e6c9
commit 9900f94afe
2 changed files with 20 additions and 1 deletions

View File

@ -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;

View File

@ -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);