blob: 9edb5d38d122fbf9d11f766c143f515c7e291260 [file]
/*
* Copyright (c) 2025 The Khronos Group Inc.
* Copyright (c) 2025 Valve Corporation
* Copyright (c) 2025 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
*/
#include "get_executable_path.h"
#if defined(__linux__) || defined(__GNU__)
#include <unistd.h>
// find application path + name. Path cannot be longer than 1024, returns NULL if it is greater than that.
std::string test_platform_executable_path() {
std::string buffer;
buffer.resize(1024);
ssize_t count = readlink("/proc/self/exe", &buffer[0], buffer.size());
if (count == -1) return NULL;
if (count == 0) return NULL;
buffer[count] = '\0';
buffer.resize(count);
return buffer;
}
#elif defined(__APPLE__)
#include <libproc.h>
#include <unistd.h>
std::string test_platform_executable_path() {
std::string buffer;
buffer.resize(1024);
pid_t pid = getpid();
int ret = proc_pidpath(pid, &buffer[0], static_cast<uint32_t>(buffer.size()));
if (ret <= 0) return NULL;
buffer[ret] = '\0';
buffer.resize(ret);
return buffer;
}
#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__)
#include <sys/sysctl.h>
std::string test_platform_executable_path() {
int mib[] = {
CTL_KERN,
#if defined(__NetBSD__)
KERN_PROC_ARGS,
-1,
KERN_PROC_PATHNAME,
#else
KERN_PROC,
KERN_PROC_PATHNAME,
-1,
#endif
};
std::string buffer;
buffer.resize(1024);
size_t size = buffer.size();
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), &buffer[0], &size, NULL, 0) < 0) {
return NULL;
}
buffer.resize(size);
return buffer;
}
#elif defined(__Fuchsia__) || defined(__OpenBSD__)
std::string test_platform_executable_path() { return {}; }
#elif defined(__QNX__)
#ifndef SYSCONFDIR
#define SYSCONFDIR "/etc"
#endif
#include <fcntl.h>
#include <sys/stat.h>
std::string test_platform_executable_path() {
std::string buffer;
buffer.resize(1024);
int fd = open("/proc/self/exefile", O_RDONLY);
ssize_t rdsize;
if (fd == -1) {
return NULL;
}
rdsize = read(fd, &buffer[0], buffer.size());
if (rdsize < 0) {
return NULL;
}
buffer[rdsize] = 0x00;
close(fd);
buffer.resize(rdsize);
return buffer;
}
#endif // defined (__QNX__)
#if defined(_WIN32)
#include <filesystem>
#include <Windows.h>
#include "wide_char_handling.h"
std::string test_platform_executable_path() {
std::string buffer;
buffer.resize(1024);
DWORD ret = GetModuleFileName(NULL, static_cast<LPSTR>(&buffer[0]), (DWORD)buffer.size());
if (ret == 0) return NULL;
if (ret > buffer.size()) return NULL;
buffer.resize(ret);
buffer[ret] = '\0';
return narrow(std::filesystem::path(buffer).native());
}
#endif