diff --git a/CMakeLists.txt b/CMakeLists.txt index d2e4addda..8be5030a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1689,6 +1689,13 @@ if(FreeBSD OR OpenBSD OR NetBSD) unset(CMAKE_REQUIRED_DEFINITIONS) endif() +if(OpenBSD) + check_symbol_exists("getexecpath" "unistd.h" HAVE_GETEXECPATH) + if(HAVE_GETEXECPATH) + target_compile_definitions(libfastfetch PUBLIC FF_HAVE_GETEXECPATH=1) + endif() +endif() + if(HAVE_PIPE2) target_compile_definitions(libfastfetch PUBLIC FF_HAVE_PIPE2) endif() diff --git a/src/common/impl/FFPlatform_unix.c b/src/common/impl/FFPlatform_unix.c index de483c463..8ec80ab0b 100644 --- a/src/common/impl/FFPlatform_unix.c +++ b/src/common/impl/FFPlatform_unix.c @@ -64,7 +64,11 @@ static void getExePath(FFPlatform* platform) { exePathLen--; // remove terminating NUL } #elif defined(__OpenBSD__) - // OpenBSD doesn't have a reliable way to get the executable path. +#if FF_HAVE_GETEXECPATH + // https://man.openbsd.org/getexecpath.3 + size_t exePathLen = getexecpath(exePath, sizeof(exePath)) == 0 ? strlen(exePath) : 0; +#else + // OpenBSD (before 8.0) doesn't have a reliable way to get the executable path. // Current implementation uses argv[0], which can be easily spoofed. // See #2195 size_t exePathLen = 0; @@ -165,6 +169,7 @@ static void getExePath(FFPlatform* platform) { } } } +#endif #elif defined(__sun) ssize_t exePathLen = readlink("/proc/self/path/a.out", exePath, sizeof(exePath) - 1); if (exePathLen > 0) {