Common: Add a function to get the path to the running program
This commit is contained in:
@ -144,6 +144,11 @@ void CanonicalizePath(String& Destination, bool OSPath /* = true */)
|
||||
CanonicalizePath(Destination, Destination);
|
||||
}
|
||||
|
||||
void CanonicalizePath(std::string& path, bool OSPath /*= true*/)
|
||||
{
|
||||
CanonicalizePath(path.data(), static_cast<u32>(path.size() + 1), path.c_str(), OSPath);
|
||||
}
|
||||
|
||||
static inline bool FileSystemCharacterIsSane(char c, bool StripSlashes)
|
||||
{
|
||||
if (!(c >= 'a' && c <= 'z') && !(c >= 'A' && c <= 'Z') && !(c >= '0' && c <= '9') && c != ' ' && c != ' ' &&
|
||||
@ -217,6 +222,34 @@ void SanitizeFileName(String& Destination, bool StripSlashes /* = true */)
|
||||
return SanitizeFileName(Destination, Destination, StripSlashes);
|
||||
}
|
||||
|
||||
std::string GetPathDirectory(const char* path)
|
||||
{
|
||||
#ifdef WIN32
|
||||
const char* forwardslash_ptr = std::strrchr(path, '/');
|
||||
const char* backslash_ptr = std::strrchr(path, '\\');
|
||||
const char* slash_ptr;
|
||||
if (forwardslash_ptr && backslash_ptr)
|
||||
slash_ptr = std::max(forwardslash_ptr, backslash_ptr);
|
||||
else if (backslash_ptr)
|
||||
slash_ptr = backslash_ptr;
|
||||
else if (forwardslash_ptr)
|
||||
slash_ptr = forwardslash_ptr;
|
||||
else
|
||||
return {};
|
||||
#else
|
||||
const char* slash_ptr = std::strrchr(path, '/');
|
||||
if (!slash_ptr)
|
||||
return {};
|
||||
#endif
|
||||
|
||||
if (slash_ptr == path)
|
||||
return {};
|
||||
|
||||
std::string str;
|
||||
str.append(path, slash_ptr - path);
|
||||
return str;
|
||||
}
|
||||
|
||||
void BuildPathRelativeToFile(char* Destination, u32 cbDestination, const char* CurrentFileName, const char* NewFileName,
|
||||
bool OSPath /* = true */, bool Canonicalize /* = true */)
|
||||
{
|
||||
@ -957,6 +990,31 @@ bool FileSystem::DeleteDirectory(const char* Path, bool Recursive)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string GetProgramPath()
|
||||
{
|
||||
const HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
std::string buffer;
|
||||
buffer.resize(MAX_PATH);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
DWORD nChars = static_cast<DWORD>(buffer.size());
|
||||
if (!QueryFullProcessImageNameA(GetCurrentProcess(), 0, buffer.data(), &nChars) &&
|
||||
GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
buffer.resize(buffer.size() * 2);
|
||||
continue;
|
||||
}
|
||||
|
||||
buffer.resize(nChars);
|
||||
break;
|
||||
}
|
||||
|
||||
CanonicalizePath(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
std::unique_ptr<ChangeNotifier> CreateChangeNotifier(const char* path, bool recursiveWatch)
|
||||
@ -1270,6 +1328,72 @@ bool DeleteDirectory(const char* Path, bool Recursive)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetProgramPath()
|
||||
{
|
||||
#if defined(__linux__)
|
||||
static const char* exeFileName = "/proc/self/exe";
|
||||
|
||||
int curSize = PATH_MAX;
|
||||
char* buffer = static_cast<char*>(std::realloc(nullptr, curSize));
|
||||
for (;;)
|
||||
{
|
||||
int len = readlink(exeFileName, buffer, curSize);
|
||||
if (len < 0)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
else if (len < curSize)
|
||||
{
|
||||
buffer[len] = '\0';
|
||||
std::string ret(buffer, len);
|
||||
std::free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
curSize *= 2;
|
||||
buffer = static_cast<char*>(std::realloc(buffer, curSize));
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
int curSize = PATH_MAX;
|
||||
char* buffer = static_cast<char*>(std::realloc(nullptr, curSize + 1));
|
||||
for (;;)
|
||||
{
|
||||
uint32 nChars = PATH_MAX - 1;
|
||||
int res = _NSGetExecutablePath(buffer, &nChars);
|
||||
if (res == 0)
|
||||
{
|
||||
buffer[nChars] = 0;
|
||||
|
||||
char* resolvedBuffer = realpath(buffer, nullptr);
|
||||
if (resolvedBuffer == nullptr)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string ret(buffer, len);
|
||||
std::free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (curSize >= 1048576)
|
||||
{
|
||||
std::free(buffer);
|
||||
return {};
|
||||
}
|
||||
|
||||
curSize *= 2;
|
||||
buffer = static_cast<char*>(std::realloc(buffer, curSize + 1));
|
||||
}
|
||||
|
||||
#else
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace FileSystem
|
||||
Reference in New Issue
Block a user