From 97794c7889732bf9aa560bec4e7b263ed815fa82 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 7 Oct 2019 10:46:45 +0200 Subject: Add ability to specify custom path list in process::path_search() --- libbutl/process.cxx | 30 +++++++++++++++++++----------- libbutl/process.ixx | 24 ++++++++++++++---------- libbutl/process.mxx | 30 +++++++++++++++++++++++------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/libbutl/process.cxx b/libbutl/process.cxx index b82af3c..bc05c5c 100644 --- a/libbutl/process.cxx +++ b/libbutl/process.cxx @@ -183,12 +183,13 @@ namespace butl // process // static process_path - path_search (const char*, const dir_path&, bool); + path_search (const char*, const dir_path&, bool, const char*); process_path process:: - path_search (const char* f, bool init, const dir_path& fb, bool po) + path_search (const char* f, bool init, + const dir_path& fb, bool po, const char* ps) { - process_path r (try_path_search (f, init, fb, po)); + process_path r (try_path_search (f, init, fb, po, ps)); if (r.empty ()) throw process_error (ENOENT); @@ -197,9 +198,10 @@ namespace butl } process_path process:: - try_path_search (const char* f, bool init, const dir_path& fb, bool po) + try_path_search (const char* f, bool init, + const dir_path& fb, bool po, const char* ps) { - process_path r (butl::path_search (f, fb, po)); + process_path r (butl::path_search (f, fb, po, ps)); if (!init && !r.empty ()) { @@ -250,7 +252,7 @@ namespace butl #ifndef _WIN32 static process_path - path_search (const char* f, const dir_path& fb, bool) + path_search (const char* f, const dir_path& fb, bool, const char* paths) { // Note that there is a similar version for Win32. @@ -326,8 +328,11 @@ namespace butl // 2. We do not continue searching on EACCES from exec(). // 3. We do not execute via default shell on ENOEXEC from exec(). // - optional p (getenv ("PATH")); - for (const char* b (p ? p->c_str () : nullptr), *e; + optional paths_env; + if (paths == nullptr && (paths_env = getenv ("PATH"))) + paths = paths_env->c_str (); + + for (const char* b (paths), *e; b != nullptr; b = (e != nullptr ? e + 1 : e)) { @@ -930,7 +935,7 @@ namespace butl #else // _WIN32 static process_path - path_search (const char* f, const dir_path& fb, bool po) + path_search (const char* f, const dir_path& fb, bool po, const char* paths) { // Note that there is a similar version for Win32. @@ -1104,8 +1109,11 @@ namespace butl // Now search in PATH. Recall is unchanged. // - optional p (getenv ("PATH")); - for (const char* b (p ? p->c_str () : nullptr), *e; + optional paths_env; + if (paths == nullptr && (paths_env = getenv ("PATH"))) + paths = paths_env->c_str (); + + for (const char* b (paths), *e; b != nullptr; b = (e != nullptr ? e + 1 : e)) { diff --git a/libbutl/process.ixx b/libbutl/process.ixx index accc57b..c7459c8 100644 --- a/libbutl/process.ixx +++ b/libbutl/process.ixx @@ -106,9 +106,9 @@ namespace butl #endif inline process_path process:: - path_search (const char*& a0, const dir_path& fb, bool po) + path_search (const char*& a0, const dir_path& fb, bool po, const char* ps) { - process_path r (path_search (a0, true, fb, po)); + process_path r (path_search (a0, true, fb, po, ps)); if (!r.recall.empty ()) { @@ -120,27 +120,31 @@ namespace butl } inline process_path process:: - path_search (const std::string& f, bool i, const dir_path& fb, bool po) + path_search (const std::string& f, bool i, + const dir_path& fb, bool po, const char* ps) { - return path_search (f.c_str (), i, fb, po); + return path_search (f.c_str (), i, fb, po, ps); } inline process_path process:: - path_search (const path& f, bool i, const dir_path& fb, bool po) + path_search (const path& f, bool i, + const dir_path& fb, bool po, const char* ps) { - return path_search (f.string ().c_str (), i, fb, po); + return path_search (f.string ().c_str (), i, fb, po, ps); } inline process_path process:: - try_path_search (const std::string& f, bool i, const dir_path& fb, bool po) + try_path_search (const std::string& f, bool i, + const dir_path& fb, bool po, const char* ps) { - return try_path_search (f.c_str (), i, fb, po); + return try_path_search (f.c_str (), i, fb, po, ps); } inline process_path process:: - try_path_search (const path& f, bool i, const dir_path& fb, bool po) + try_path_search (const path& f, bool i, + const dir_path& fb, bool po, const char* ps) { - return try_path_search (f.string ().c_str (), i, fb, po); + return try_path_search (f.string ().c_str (), i, fb, po, ps); } inline process:: diff --git a/libbutl/process.mxx b/libbutl/process.mxx index 13438be..7a331da 100644 --- a/libbutl/process.mxx +++ b/libbutl/process.mxx @@ -405,10 +405,14 @@ LIBBUTL_MODEXPORT namespace butl // (or in CWD if there is a directory component) ignoring other places // (like calling process' directory and, gasp, CWD on Windows). // + // If the paths argument is not NULL, search in this list of paths rather + // than in the PATH environment variable. + // static process_path path_search (const char*& args0, const dir_path& fallback = dir_path (), - bool path_only = false); + bool path_only = false, + const char* paths = nullptr); // This version is primarily useful when you want to pre-search the // executable before creating the args[] array. In this case you will @@ -425,30 +429,42 @@ LIBBUTL_MODEXPORT namespace butl // static process_path path_search (const char* file, bool init, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); static process_path path_search (const std::string&, bool, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); static process_path path_search (const path&, bool, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); // As above but if not found return empty process_path instead of // throwing. // static process_path try_path_search (const char*, bool, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); static process_path try_path_search (const std::string&, bool, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); static process_path try_path_search (const path&, bool, - const dir_path& = dir_path (), bool = false); + const dir_path& = dir_path (), + bool = false, + const char* = nullptr); // Print process commmand line. If the number of elements is specified, // then it will print the piped multi-process command line, if present. -- cgit v1.1