Index: vendor/libbase/file.cpp --- vendor/libbase/file.cpp.orig +++ vendor/libbase/file.cpp @@ -26,6 +26,9 @@ #include #include #include +#ifdef __OpenBSD__ +#include +#endif #include #include @@ -508,6 +511,48 @@ std::string GetExecutablePath() { return path; #elif defined(__EMSCRIPTEN__) abort(); +#elif defined(__OpenBSD__) + // Try /proc/curproc/file if procfs is mounted. + { + std::string path; + if (android::base::Readlink("/proc/curproc/file", &path) && !path.empty()) { + return path; + } + } + // Fall back to sysctl(KERN_PROC_ARGV) to recover argv[0] and resolve it. + { + int mib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV}; + size_t len = 0; + if (sysctl(mib, 4, nullptr, &len, nullptr, 0) != -1 && len > 0) { + std::vector buf(len); + if (sysctl(mib, 4, buf.data(), &len, nullptr, 0) != -1) { + char* argv0 = reinterpret_cast(buf.data())[0]; + if (argv0 != nullptr) { + if (argv0[0] == '/') { + return argv0; // Already absolute. + } + // Search PATH directories for argv0. + if (const char* path_env = getenv("PATH")) { + const char* p = path_env; + while (*p) { + const char* q = strchr(p, ':'); + size_t dirlen = q ? (size_t)(q - p) : strlen(p); + std::string full(p, dirlen); + full += '/'; + full += argv0; + char resolved[PATH_MAX]; + if (realpath(full.c_str(), resolved) != nullptr) { + return resolved; + } + p += dirlen; + if (*p == ':') ++p; + } + } + } + } + } + } + return ""; #else #error unknown OS #endif