From 80448440e9d3af11cfd31fd8a219c80a923da3da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tam=C3=A1s=20B=C3=A1lint=20Misius?= Date: Sun, 1 Jan 2023 17:27:14 +0100 Subject: [PATCH] Redo Platform::ExecutableName --- src/common/Platform.cpp | 123 +++++++++++++++++----------------------- src/common/Platform.h | 2 - 2 files changed, 51 insertions(+), 74 deletions(-) diff --git a/src/common/Platform.cpp b/src/common/Platform.cpp index fd91ab9c8..b0230f0e6 100644 --- a/src/common/Platform.cpp +++ b/src/common/Platform.cpp @@ -58,66 +58,6 @@ ByteString GetCwd() return cwd; } -ByteString ExecutableName() -{ - ByteString ret; -#if defined(WIN) - wchar_t *name = (wchar_t *)malloc(sizeof(wchar_t) * 64); - DWORD max = 64, res; - while ((res = GetModuleFileNameW(NULL, name, max)) >= max) - { -#elif defined MACOSX - char *fn = (char*)malloc(64),*name = (char*)malloc(PATH_MAX); - uint32_t max = 64, res; - if (_NSGetExecutablePath(fn, &max) != 0) - { - char *realloced_fn = (char*)realloc(fn, max); - assert(realloced_fn != NULL); - fn = realloced_fn; - _NSGetExecutablePath(fn, &max); - } - if (realpath(fn, name) == NULL) - { - free(fn); - free(name); - return ""; - } - res = 1; -#else - char fn[64], *name = (char *)malloc(64); - size_t max = 64, res; - sprintf(fn, "/proc/self/exe"); - memset(name, 0, max); - while ((res = readlink(fn, name, max)) >= max-1) - { -#endif -#ifndef MACOSX -#if defined(WIN) - using Char = wchar_t; -#else - using Char = char; -#endif - max *= 2; - Char* realloced_name = (Char *)realloc(name, sizeof(Char) * max); - assert(realloced_name != NULL); - name = realloced_name; - memset(name, 0, sizeof(Char) * max); - } -#endif - if (res <= 0) - { - free(name); - return ""; - } -#if defined(WIN) - ret = WinNarrow(name); -#else - ret = name; -#endif - free(name); - return ret; -} - void DoRestart() { ByteString exename = ExecutableName(); @@ -198,18 +138,6 @@ long unsigned int GetTime() #endif } - -void LoadFileInResource(int name, int type, unsigned int& size, const char*& data) -{ -#ifdef _MSC_VER - HMODULE handle = ::GetModuleHandle(NULL); - HRSRC rc = ::FindResource(handle, MAKEINTRESOURCE(name), MAKEINTRESOURCE(type)); - HGLOBAL rcData = ::LoadResource(handle, rc); - size = ::SizeofResource(handle, rc); - data = static_cast(::LockResource(rcData)); -#endif -} - bool Stat(ByteString filename) { #ifdef WIN @@ -574,4 +502,55 @@ bool WriteFile(std::vector fileData, ByteString filename) return true; } +ByteString ExecutableName() +{ +#ifdef WIN + std::wstring buf(L"?"); + while (true) + { + SetLastError(ERROR_SUCCESS); + if (!GetModuleFileNameW(NULL, &buf[0], DWORD(buf.size()))) + { + std::cerr << "GetModuleFileNameW: " << GetLastError() << std::endl; + return ""; + } + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + break; + } + buf.resize(buf.size() * 2); + } + return WinNarrow(&buf[0]); // Pass pointer to copy only up to the zero terminator. +#else +# ifdef MACOSX + ByteString firstApproximation("?"); + { + auto bufSize = uint32_t(firstApproximation.size()); + auto ret = _NSGetExecutablePath(&firstApproximation[0], &bufSize); + if (ret == -1) + { + // Buffer not large enough; likely to happen since it's initially a single byte. + firstApproximation.resize(bufSize); + ret = _NSGetExecutablePath(&firstApproximation[0], &bufSize); + } + if (ret != 0) + { + // Can't even get a first approximation. + std::cerr << "_NSGetExecutablePath: " << ret << std::endl; + return ""; + } + } +# else + ByteString firstApproximation("/proc/self/exe"); +# endif + auto rp = std::unique_ptr(realpath(&firstApproximation[0], NULL), std::free); + if (!rp) + { + std::cerr << "realpath: " << errno << std::endl; + return ""; + } + return rp.get(); +#endif +} + } diff --git a/src/common/Platform.h b/src/common/Platform.h index e39ddce42..39d99c292 100644 --- a/src/common/Platform.h +++ b/src/common/Platform.h @@ -19,8 +19,6 @@ namespace Platform void Millisleep(long int t); long unsigned int GetTime(); - void LoadFileInResource(int name, int type, unsigned int& size, const char*& data); - bool Stat(ByteString filename); bool FileExists(ByteString filename); bool DirectoryExists(ByteString directory);