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.
.png)
