210 lines
4.6 KiB
C++
210 lines
4.6 KiB
C++
|
/***
|
||
|
Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved.
|
||
|
|
||
|
File: Paths.cpp
|
||
|
Date: 2021-6-12
|
||
|
Author: Reece
|
||
|
***/
|
||
|
#include <RuntimeInternal.hpp>
|
||
|
#include "Paths.hpp"
|
||
|
|
||
|
#if defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_APPLE) || defined(__FreeBSD__)
|
||
|
#include <stdlib.h>
|
||
|
#include <unistd.h>
|
||
|
#define _USE_GET_CWD
|
||
|
#endif
|
||
|
|
||
|
namespace Aurora::Process
|
||
|
{
|
||
|
AUKN_SYM bool GetWorkingDirectory(AuString &path)
|
||
|
{
|
||
|
path.resize(2048);
|
||
|
if (path.empty())
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#if defined(AURORA_PLATFORM_WIN32)
|
||
|
|
||
|
std::wstring eh;
|
||
|
eh.resize(2048);
|
||
|
|
||
|
auto length = ::GetCurrentDirectoryW(eh.size(), eh.data());
|
||
|
if (length == 0)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path = Locale::ConvertFromWChar(eh.data(), length);
|
||
|
|
||
|
return true;
|
||
|
|
||
|
#elif defined(AURORA_PLATFORM_ANDROID)
|
||
|
|
||
|
return false;
|
||
|
|
||
|
#elif defined(_USE_GET_CWD)
|
||
|
|
||
|
if (getcwd(path.data(), path.size()) == nullptr)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path.resize(strlen(path.data()));
|
||
|
|
||
|
return true;
|
||
|
|
||
|
#endif
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
static bool GetModulePathSlow(AuString &path, char &splitter)
|
||
|
{
|
||
|
path.clear();
|
||
|
splitter = 0;
|
||
|
|
||
|
#if defined(AURORA_PLATFORM_WIN32)
|
||
|
|
||
|
wchar_t chungus[0x4000];
|
||
|
auto len = GetModuleFileNameW(
|
||
|
NULL,
|
||
|
chungus,
|
||
|
ArraySize(chungus)
|
||
|
);
|
||
|
|
||
|
if (!len)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path = Aurora::Locale::ConvertFromWChar(chungus, len);
|
||
|
splitter = '\\';
|
||
|
|
||
|
return true;
|
||
|
|
||
|
#elif defined(AURORA_PLATFORM_LINUX) || defined(AURORA_PLATFORM_BSD)
|
||
|
|
||
|
static const AuList<AuString> procFsPaths = {
|
||
|
"/proc/self/exe",
|
||
|
"/proc/self/file",
|
||
|
"/proc/curproc/exe",
|
||
|
"/proc/curproc/file"
|
||
|
};
|
||
|
|
||
|
for (const auto &name : procFsPaths)
|
||
|
{
|
||
|
if (Aurora::IO::FS::ReadString(name, path))
|
||
|
{
|
||
|
splitter = '/';
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
|
||
|
#elif defined(AURORA_PLATFORM_APPLE) || defined(AURORA_PLATFORM_IOS)
|
||
|
|
||
|
CFURLRef bundleURL = CFBundleCopyExecutableURL(CFBundleGetMainBundle());
|
||
|
CFStringRef pathRef = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
|
||
|
|
||
|
auto utf16length = CFStringGetLength(pathRef);
|
||
|
auto maxUtf8len = CFStringGetMaximumSizeForEncoding(utf16length, kCFStringEncodingUTF8);
|
||
|
|
||
|
path.resize(maxUtf8len);
|
||
|
|
||
|
if (!CFStringGetCString(pathRef, path.data(), maxUtf8len, kCFStringEncodingUTF8))
|
||
|
{
|
||
|
path.clear();
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path.resize(std::strlen(path.c_str()));
|
||
|
splitter = '\\';
|
||
|
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static bool GetModulePath(AuString &module, AuString &partialPath, AuString &fullPath)
|
||
|
{
|
||
|
static AuString cachedModule, cachedPartialPath, cachedFullPath;
|
||
|
static bool init = false;
|
||
|
char spitter;
|
||
|
|
||
|
if (std::exchange(init, true))
|
||
|
{
|
||
|
if (!cachedModule.size())
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
goto returnCached;
|
||
|
}
|
||
|
|
||
|
if (!GetModulePathSlow(cachedFullPath, spitter))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// required for c++20, bleh
|
||
|
{
|
||
|
auto indexA = cachedFullPath.find_last_of(spitter);
|
||
|
if (indexA == AuString::npos)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
cachedModule = cachedFullPath.substr(indexA + 1);
|
||
|
cachedPartialPath = cachedFullPath.substr(0, indexA);
|
||
|
}
|
||
|
|
||
|
returnCached:
|
||
|
module = cachedModule;
|
||
|
fullPath = cachedFullPath;
|
||
|
partialPath = cachedPartialPath;
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool GetProcName(AuString &executable)
|
||
|
{
|
||
|
AuString module, partial, full;
|
||
|
|
||
|
if (!GetModulePath(module, partial, full))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
executable = module;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool GetProcPath(AuString &path)
|
||
|
{
|
||
|
AuString module, partial, full;
|
||
|
|
||
|
if (!GetModulePath(module, partial, full))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path = partial;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
AUKN_SYM bool GetProcFullPath(AuString &path)
|
||
|
{
|
||
|
AuString module, partial, full;
|
||
|
|
||
|
if (!GetModulePath(module, partial, full))
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
path = full;
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
}
|