summaryrefslogtreecommitdiffstats
path: root/util.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'util.cxx')
-rw-r--r--util.cxx81
1 files changed, 50 insertions, 31 deletions
diff --git a/util.cxx b/util.cxx
index d57ef88c..a5f77c06 100644
--- a/util.cxx
+++ b/util.cxx
@@ -154,50 +154,69 @@ tokenize(const string& str, vector<string>& tokens,
}
-// Find an executable by name in $PATH.
-bool
-find_executable(const char *name, string& retpath)
+// Resolve an executable name to a canonical full path name, with the
+// same policy as execvp(). A program name not containing a slash
+// will be searched along the $PATH.
+
+string find_executable(const string& name)
{
- const char *p;
- string path;
- vector<string> dirs;
- struct stat st1, st2;
+ string retpath;
+
+ if (name.size() == 0)
+ return name;
+
+ struct stat st;
- if (*name == '/')
+ if (name.find('/') != string::npos) // slash in the path already?
{
retpath = name;
- return true;
+ }
+ else // Nope, search $PATH.
+ {
+ char *path = getenv("PATH");
+ if (path)
+ {
+ // Split PATH up.
+ vector<string> dirs;
+ tokenize(string(path), dirs, string(":"));
+
+ // Search the path looking for the first executable of the right name.
+ for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); i++)
+ {
+ string fname = *i + "/" + name;
+ const char *f = fname.c_str();
+
+ // Look for a normal executable file.
+ if (access(f, X_OK) == 0
+ && stat(f, &st) == 0
+ && S_ISREG(st.st_mode))
+ {
+ retpath = fname;
+ break;
+ }
+ }
+ }
}
- p = getenv("PATH");
- if (!p)
- return false;
- path = p;
- // Split PATH up.
- tokenize(path, dirs, string(":"));
+ // Could not find the program on the $PATH. We'll just fall back to
+ // the unqualified name, which our caller will probably fail with.
+ if (retpath == "")
+ retpath = name;
- // Search the path looking for the first executable of the right name.
- for (vector<string>::iterator i = dirs.begin(); i != dirs.end(); i++)
+ // Canonicalize the path name.
+ char *cf = canonicalize_file_name (retpath.c_str());
+ if (cf)
{
- string fname = *i + "/" + name;
- const char *f = fname.c_str();
-
- // Look for a normal executable file.
- if (access(f, X_OK) == 0
- && lstat(f, &st1) == 0
- && stat(f, &st2) == 0
- && S_ISREG(st2.st_mode))
- {
- // Found it!
- retpath = fname;
- return true;
- }
+ retpath = string(cf);
+ free (cf);
}
- return false;
+ return retpath;
}
+
+
const string cmdstr_quoted(const string& cmd)
{
// original cmd : substr1