From 488820e29161e011ed114dcce13917f0bc562fa8 Mon Sep 17 00:00:00 2001 From: Cody Northrop Date: Tue, 18 Jul 2017 15:51:18 -0600 Subject: [PATCH] FileIO: Move PATH searching into its own function --- renderdoc/os/os_specific.h | 1 + renderdoc/os/posix/posix_process.cpp | 39 +++++-------------------- renderdoc/os/posix/posix_stringio.cpp | 32 ++++++++++++++++++++ renderdoc/os/win32/win32_stringio.cpp | 42 +++++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 31 deletions(-) diff --git a/renderdoc/os/os_specific.h b/renderdoc/os/os_specific.h index 18f877649..fdb38db12 100644 --- a/renderdoc/os/os_specific.h +++ b/renderdoc/os/os_specific.h @@ -244,6 +244,7 @@ void CreateParentDirectory(const string &filename); bool IsRelativePath(const string &path); string GetFullPathname(const string &filename); +string FindFileInPath(const string &fileName); void GetExecutableFilename(string &selfName); diff --git a/renderdoc/os/posix/posix_process.cpp b/renderdoc/os/posix/posix_process.cpp index 74025e41c..0c3de45ba 100644 --- a/renderdoc/os/posix/posix_process.cpp +++ b/renderdoc/os/posix/posix_process.cpp @@ -39,6 +39,12 @@ char **GetCurrentEnvironment(); int GetIdentPort(pid_t childPid); +namespace FileIO +{ +void ReleaseFDAfterFork(); +string FindFileInPath(const string &fileName); +}; + static const string GetAbsoluteAppPathFromName(const string &appName) { string appPath; @@ -55,32 +61,8 @@ static const string GetAbsoluteAppPathFromName(const string &appName) return appPath; } - // Search the PATH directory list for the application (like shell which) to get the absolute path - // Return "" if no exectuable found in the PATH list - char *pathEnvVar = getenv("PATH"); - if(!pathEnvVar) - return appPath; - - // Make a copy of our PATH so strtok can insert NULL without actually changing env - char *localPath = new char[strlen(pathEnvVar) + 1]; - strcpy(localPath, pathEnvVar); - - const char *pathSeparator = ":"; - const char *path = strtok(localPath, pathSeparator); - while(path) - { - string testPath(path); - testPath += "/" + appName; - if(!access(testPath.c_str(), X_OK)) - { - appPath = testPath; - break; - } - path = strtok(NULL, pathSeparator); - } - - delete[] localPath; - return appPath; + // Otherwise, go search PATH for it + return FileIO::FindFileInPath(appName); } static vector &GetEnvModifications() @@ -230,11 +212,6 @@ void Process::ApplyEnvironmentModification() modifications.clear(); } -namespace FileIO -{ -void ReleaseFDAfterFork(); -}; - static pid_t RunProcess(const char *app, const char *workingDir, const char *cmdLine, char **envp, int stdoutPipe[2] = NULL, int stderrPipe[2] = NULL) { diff --git a/renderdoc/os/posix/posix_stringio.cpp b/renderdoc/os/posix/posix_stringio.cpp index 4c8bef9d9..eceea0253 100644 --- a/renderdoc/os/posix/posix_stringio.cpp +++ b/renderdoc/os/posix/posix_stringio.cpp @@ -104,6 +104,38 @@ string GetFullPathname(const string &filename) return string(path); } +string FindFileInPath(const string &fileName) +{ + string filePath; + + // Search the PATH directory list for the application (like shell which) to get the absolute path + // Return "" if no exectuable found in the PATH list + char *pathEnvVar = getenv("PATH"); + if(!pathEnvVar) + return filePath; + + // Make a copy of our PATH so strtok can insert NULL without actually changing env + char *localPath = new char[strlen(pathEnvVar) + 1]; + strcpy(localPath, pathEnvVar); + + const char *pathSeparator = ":"; + const char *path = strtok(localPath, pathSeparator); + while(path) + { + string testPath(path); + testPath += "/" + fileName; + if(!access(testPath.c_str(), X_OK)) + { + filePath = testPath; + break; + } + path = strtok(NULL, pathSeparator); + } + + delete[] localPath; + return filePath; +} + string GetReplayAppFilename() { // look up the shared object's path via dladdr diff --git a/renderdoc/os/win32/win32_stringio.cpp b/renderdoc/os/win32/win32_stringio.cpp index ae927d7fc..a1795c4a1 100644 --- a/renderdoc/os/win32/win32_stringio.cpp +++ b/renderdoc/os/win32/win32_stringio.cpp @@ -186,6 +186,48 @@ string GetFullPathname(const string &filename) return StringFormat::Wide2UTF8(wstring(path)); } +string FindFileInPath(const string &file) +{ + string filePath; + + // Search the PATH directory list for the application (like shell where) to get the absolute path + // Return "" if no exectuable found in the PATH list + const DWORD size = 65535; + char envPath[size]; + if(GetEnvironmentVariableA("PATH", envPath, size) == 0) + return filePath; + + char *next = NULL; + const char *pathSeparator = ";"; + const char *path = strtok_s(envPath, pathSeparator, &next); + wstring fileName = StringFormat::UTF82Wide(file); + + while(path) + { + wstring testPath = StringFormat::UTF82Wide(path); + + // Check for the following extensions. If fileName already has one, they will be ignored. + std::vector extensions; + extensions.push_back(L".exe"); + extensions.push_back(L".bat"); + + for(uint32_t i = 0; i < extensions.size(); i++) + { + wchar_t foundPath[512] = {0}; + if(SearchPathW(testPath.c_str(), fileName.c_str(), extensions[i].c_str(), + ARRAY_COUNT(foundPath) - 1, foundPath, NULL) != 0) + { + filePath = StringFormat::Wide2UTF8(wstring(foundPath)); + break; + } + } + + path = strtok_s(NULL, pathSeparator, &next); + } + + return filePath; +} + void CreateParentDirectory(const string &filename) { wstring wfn = StringFormat::UTF82Wide(filename);