Convince OpenBSD developers to allow an executable get the path to itself (2020)

2 hours ago 1

@andrewrk

OpenBSD takes the prize for the hackiest implementation of std.fs.selfExePath, a function which is readily available on Linux, Darwin/macOS, FreeBSD, DragonFlyBSD, NetBSD, and Microsoft Windows.

.openbsd => {
// OpenBSD doesn't support getting the path of a running process, so try to guess it
if (os.argv.len == 0)
return error.FileNotFound;
const argv0 = mem.span(os.argv[0]);
if (mem.indexOf(u8, argv0, "/") != null) {
// argv[0] is a path (relative or absolute): use realpath(3) directly
var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
const real_path = try os.realpathZ(os.argv[0], &real_path_buf);
if (real_path.len > out_buffer.len)
return error.NameTooLong;
mem.copy(u8, out_buffer, real_path);
return out_buffer[0..real_path.len];
} else if (argv0.len != 0) {
// argv[0] is not empty (and not a path): search it inside PATH
const PATH = std.os.getenvZ("PATH") orelse return error.FileNotFound;
var path_it = mem.tokenize(PATH, &[_]u8{path.delimiter});
while (path_it.next()) |a_path| {
var resolved_path_buf: [MAX_PATH_BYTES]u8 = undefined;
const resolved_path = std.fmt.bufPrintZ(&resolved_path_buf, "{s}/{s}", .{
a_path,
os.argv[0],
}) catch continue;
var real_path_buf: [MAX_PATH_BYTES]u8 = undefined;
if (os.realpathZ(&resolved_path_buf, &real_path_buf)) |real_path| {
// found a file, and hope it is the right file
if (real_path.len > out_buffer.len)
return error.NameTooLong;
mem.copy(u8, out_buffer, real_path);
return out_buffer[0..real_path.len];
} else |_| continue;
}
}
return error.FileNotFound;
},

Let's put some friendly pressure on the OpenBSD project to improve this use case.

Read Entire Article