| 23 | #endif |
| 24 | |
| 25 | inline std::filesystem::path getExecutablePath() { |
| 26 | #ifdef _WIN32 |
| 27 | std::wstring path(MAX_PATH, L'\0'); |
| 28 | DWORD size = GetModuleFileNameW(nullptr, path.data(), static_cast<DWORD>(path.size())); |
| 29 | |
| 30 | while (size == path.size() && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { |
| 31 | if (path.size() >= MAX_PATH_EXTENDED) { |
| 32 | throw std::runtime_error("Executable path exceeds maximum length"); |
| 33 | } |
| 34 | path.resize(path.size() * 2); |
| 35 | size = GetModuleFileNameW(nullptr, path.data(), static_cast<DWORD>(path.size())); |
| 36 | } |
| 37 | |
| 38 | if (size == 0) { |
| 39 | throw std::runtime_error("GetModuleFileNameW failed"); |
| 40 | } |
| 41 | |
| 42 | path.resize(size); |
| 43 | return std::filesystem::path(path); |
| 44 | #else |
| 45 | char path[PATH_MAX]; |
| 46 | const ssize_t count = readlink("/proc/self/exe", path, PATH_MAX - 1); |
| 47 | if (count > 0 && count < PATH_MAX - 1) { |
| 48 | path[count] = '\0'; |
| 49 | return std::filesystem::path(path); |
| 50 | } |
| 51 | throw std::runtime_error("readlink(/proc/self/exe) failed"); |
| 52 | #endif |
| 53 | } |
| 54 | |
| 55 | inline std::filesystem::path getExecutableDir() { |
| 56 | return getExecutablePath().parent_path(); |
no test coverage detected