aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2016-08-21 13:23:14 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2016-08-21 13:23:14 +0200
commit91a5ccf011c569dabc6cc79997ddd5f4e04592b1 (patch)
tree0cbb50172df6d2904d62b9eecf727f6b766b6687
parente930d5c9cb4176c6055bde2b4ff196f4b5f92f69 (diff)
Add support for process fallback search directory
-rw-r--r--butl/process8
-rw-r--r--butl/process.cxx40
2 files changed, 43 insertions, 5 deletions
diff --git a/butl/process b/butl/process
index 75f3c66..c967c44 100644
--- a/butl/process
+++ b/butl/process
@@ -208,8 +208,12 @@ namespace butl
//
// process p (pp, args);
//
- process_path
- path_search (const char*& args0);
+ // You can also specify the fallback directory which will be tried last.
+ // This, for example, can be used to implement the Windows "search in the
+ // parent executable's directory" semantics across platforms.
+ //
+ static process_path
+ path_search (const char*& args0, const dir_path& fallback = dir_path ());
public:
#ifndef _WIN32
diff --git a/butl/process.cxx b/butl/process.cxx
index cceceed..dcb4bc9 100644
--- a/butl/process.cxx
+++ b/butl/process.cxx
@@ -93,7 +93,7 @@ namespace butl
#ifndef _WIN32
process_path process::
- path_search (const char*& args0)
+ path_search (const char*& args0, const dir_path& fb)
{
// Note that there is a similar version for Win32.
@@ -161,6 +161,20 @@ namespace butl
break;
}
+ // If we were given a fallback, try that.
+ //
+ if (!fb.empty ())
+ {
+ if (search (fb.string ().c_str (), fb.string ().size ()))
+ {
+ // In this case we have to set the recall path.
+ //
+ rp = fb;
+ rp /= f;
+ break;
+ }
+ }
+
// Did not find anything.
//
throw process_error (ENOENT, false);
@@ -347,7 +361,7 @@ namespace butl
#else // _WIN32
process_path process::
- path_search (const char*& args0)
+ path_search (const char*& args0, const dir_path& fb)
{
// Note that there is a similar version for Win32.
@@ -460,7 +474,7 @@ namespace butl
if (search ("", 0))
break;
- // Finally, search in PATH. Recall is unchanged.
+ // Now search in PATH. Recall is unchanged.
//
{
const char* b (getenv ("PATH"));
@@ -480,6 +494,26 @@ namespace butl
break;
}
+ // Finally, if we were given a fallback, try that. This case is similar
+ // to searching in the parent executable's directory.
+ //
+ if (!fb.empty ())
+ {
+ // I would have been nice to preserve trailing slash (by using
+ // representation() instead of string()), but that would involve
+ // a copy. Oh, well, can't always win.
+ //
+ if (search (fb.string ().c_str (), fb.string ().size ()))
+ {
+ // In this case we have to set the recall path. At least here we
+ // got to keep the original slash.
+ //
+ rp = fb;
+ rp /= f;
+ break;
+ }
+ }
+
// Did not find anything.
//
throw process_error (ENOENT);