From f1a8c565f1cc1ff8b0b8e1415362f307e62c4a58 Mon Sep 17 00:00:00 2001 From: Yamagi Burmeister Date: Mon, 31 Jul 2017 20:27:52 +0200 Subject: [PATCH] Implement a generic case in Sys_GetBinaryDir(). Several platforms - OpenBSD being a prominent example - don't provide a way to get the executable path. Don't abort, just return the current dir ./ executable dir. This is just a work around, of course. The user needs to supply a script that calls ./quake2 in the correct directory. --- src/backends/generic/misc.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/backends/generic/misc.c b/src/backends/generic/misc.c index 61c3ccc3..c41198f7 100644 --- a/src/backends/generic/misc.c +++ b/src/backends/generic/misc.c @@ -29,6 +29,8 @@ #if defined(__linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) #include // readlink(), amongst others +#include "../../common/header/shared.h" + #endif #ifdef __FreeBSD__ @@ -64,11 +66,12 @@ static void SetExecutablePath(char* exePath) exePath[0] = '\0'; } -#elif defined(__linux) || defined(__NetBSD__) || defined(__OpenBSD__) +#elif defined(__linux) || defined(__NetBSD__) // all the platforms that have /proc/$pid/exe or similar that symlink the // real executable - basiscally Linux and the BSDs except for FreeBSD which - // doesn't enable proc by default and has a sysctl() for this + // doesn't enable proc by default and has a sysctl() for this. OpenBSD once + // had /proc but removed it for security reasons. char buf[PATH_MAX] = {0}; #ifdef __linux snprintf(buf, sizeof(buf), "/proc/%d/exe", getpid()); @@ -115,7 +118,13 @@ static void SetExecutablePath(char* exePath) #else -#error "Unsupported Platform!" // feel free to add implementation for your platform and send me a patch + // Several platforms (for example OpenBSD) donn't provide a + // reliable way to determine the executable path. Just return + // an empty string. + exePath[0] = '\0'; + +// feel free to add implementation for your platform and send a pull request. +#warning "SetExecutablePath() is unimplemented on this platform" #endif } @@ -124,18 +133,25 @@ const char *Sys_GetBinaryDir(void) { static char exeDir[PATH_MAX] = {0}; - if(exeDir[0] != '\0') return exeDir; + if(exeDir[0] != '\0') { + return exeDir; + } SetExecutablePath(exeDir); - // cut off executable name - char* lastSlash = strrchr(exeDir, '/'); + if (exeDir[0] == '\0') { + Com_Printf("Couldn't determine executable path. Using ./ instead.\n"); + Q_strlcpy(exeDir, "./", sizeof(exeDir)); + } else { + // cut off executable name + char *lastSlash = strrchr(exeDir, '/'); #ifdef _WIN32 - char* lastBackSlash = strrchr(exeDir, '\\'); - if(lastSlash == NULL || lastBackSlash > lastSlash) lastSlash = lastBackSlash; + char* lastBackSlash = strrchr(exeDir, '\\'); + if(lastSlash == NULL || lastBackSlash > lastSlash) lastSlash = lastBackSlash; #endif // _WIN32 - if(lastSlash != NULL) lastSlash[1] = '\0'; // cut off after last (back)slash + if (lastSlash != NULL) lastSlash[1] = '\0'; // cut off after last (back)slash + } return exeDir; }