MCPcopy Create free account
hub / github.com/deathkiller/jazz2-native / GetExecutablePath

Method GetExecutablePath

Sources/Shared/IO/FileSystem.cpp:1308–1361  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1306 }
1307
1308 String FileSystem::GetExecutablePath()
1309 {
1310#if defined(DEATH_TARGET_EMSCRIPTEN)
1311 return "/"_s;
1312#elif defined(DEATH_TARGET_APPLE)
1313 // Get path size (need to set it to 0 to avoid filling nullptr with random data and crashing)
1314 std::uint32_t size = 0;
1315 if (_NSGetExecutablePath(nullptr, &size) != -1) {
1316 return {};
1317 }
1318
1319 // Allocate proper size and get the path. The size includes a null terminator which the String handles on its own, so subtract it
1320 String path{NoInit, size - 1};
1321 if (_NSGetExecutablePath(path.data(), &size) != 0) {
1322 return {};
1323 }
1324 return path;
1325#elif defined(__FreeBSD__)
1326 std::size_t size;
1327 static const std::int32_t mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
1328 sysctl(mib, 4, nullptr, &size, nullptr, 0);
1329 String path{NoInit, size};
1330 sysctl(mib, 4, path.data(), &size, nullptr, 0);
1331 return path;
1332#elif defined(DEATH_TARGET_UNIX)
1333 // Reallocate like hell until we have enough place to store the path. Can't use lstat because
1334 // the /proc/self/exe symlink is not a real symlink and so stat::st_size returns 0.
1335 static const char self[] = "/proc/self/exe";
1336 Array<char> path;
1337 arrayResize(path, NoInit, 16);
1338 ssize_t size;
1339 while ((size = ::readlink(self, path, path.size())) == ssize_t(path.size())) {
1340 arrayResize(path, NoInit, path.size() * 2);
1341 }
1342
1343 if (size == -1) {
1344 LOGE("Cannot read \"{}\" with error {}{}", self, errno, __GetUnixErrorSuffix(errno));
1345 return {};
1346 }
1347
1348 // readlink() doesn't put the null terminator into the array, do it ourselves. The above loop guarantees
1349 // that path.size() is always larger than size - if it would be equal, we'd try once more with a larger buffer
1350 path[size] = '\0';
1351 const auto deleter = path.deleter();
1352 return String{path.release(), std::size_t(size), deleter};
1353#elif defined(DEATH_TARGET_WINDOWS) && !defined(DEATH_TARGET_WINDOWS_RT)
1354 wchar_t path[MaxPathLength + 1];
1355 // Returns size *without* the null terminator
1356 const std::size_t size = ::GetModuleFileNameW(NULL, path, DWORD(arraySize(path)));
1357 return Utf8::FromUtf16(arrayView(path, size));
1358#else
1359 return {};
1360#endif
1361 }
1362
1363 String FileSystem::GetSavePath(StringView applicationName)
1364 {

Callers

nothing calls this directly

Calls 9

arrayResizeFunction · 0.85
__GetUnixErrorSuffixFunction · 0.85
arraySizeFunction · 0.50
FromUtf16Function · 0.50
arrayViewFunction · 0.50
dataMethod · 0.45
sizeMethod · 0.45
deleterMethod · 0.45
releaseMethod · 0.45

Tested by

no test coverage detected