From d9736de16f58966ff0fd7f9e7391d6beba8d7366 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 9 Aug 2008 12:09:01 -0400 Subject: prep find_executable() for use by process() probes --- util.cxx | 76 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 34 deletions(-) (limited to 'util.cxx') diff --git a/util.cxx b/util.cxx index 97425d76..8be4ea5d 100644 --- a/util.cxx +++ b/util.cxx @@ -155,49 +155,57 @@ tokenize(const string& str, vector& tokens, // Find an executable by name in $PATH. -bool -find_executable(const char *name, string& retpath) +string find_executable(const string& name) { - const char *p; - string path; - vector dirs; - struct stat st1, st2; + string retpath; - if (*name == '/') - { - retpath = name; - return true; - } + if (name.size() == 0) + return name; - p = getenv("PATH"); - if (!p) - return false; - path = p; - - // Split PATH up. - tokenize(path, dirs, string(":")); - - // Search the path looking for the first executable of the right name. - for (vector::iterator i = dirs.begin(); i != dirs.end(); i++) + if (name[0] == '/') // already fully qualified + retpath = name; + else // need to search along $PATH { - 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)) + char *path = getenv("PATH"); + if (path) { - // Found it! - retpath = fname; - return true; - } + // Split PATH up. + vector dirs; + tokenize(string(path), dirs, string(":")); + + // Search the path looking for the first executable of the right name. + for (vector::iterator i = dirs.begin(); i != dirs.end(); i++) + { + string fname = *i + "/" + name; + const char *f = fname.c_str(); + struct stat st1, st2; + + // 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)) + { + retpath = fname; + break; + } + } + } } - return false; + // Canonicalize the path name. + char *cf = canonicalize_file_name (retpath.c_str()); + if (cf) + { + retpath = string(cf); + free (cf); + } + + return retpath; } + + const string cmdstr_quoted(const string& cmd) { // original cmd : substr1 -- cgit From d0a7f5a99a13b1aa347ccb11bd63a1ce50b84979 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Sat, 9 Aug 2008 13:59:44 -0400 Subject: PR4225 and PR6826: expand & canonicalize executable path names process probes --- util.cxx | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'util.cxx') diff --git a/util.cxx b/util.cxx index 8be4ea5d..ab0a1a91 100644 --- a/util.cxx +++ b/util.cxx @@ -154,7 +154,10 @@ tokenize(const string& str, vector& tokens, } -// Find an executable by name in $PATH. +// 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) { string retpath; @@ -162,9 +165,13 @@ string find_executable(const string& name) if (name.size() == 0) return name; - if (name[0] == '/') // already fully qualified - retpath = name; - else // need to search along $PATH + struct stat st; + + if (name.find('/') != string::npos) // slash in the path already? + { + retpath = name; + } + else // Nope, search $PATH. { char *path = getenv("PATH"); if (path) @@ -178,13 +185,11 @@ string find_executable(const string& name) { string fname = *i + "/" + name; const char *f = fname.c_str(); - struct stat st1, st2; // 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)) + && stat(f, &st) == 0 + && S_ISREG(st.st_mode)) { retpath = fname; break; @@ -193,6 +198,12 @@ string find_executable(const string& name) } } + + // 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; + // Canonicalize the path name. char *cf = canonicalize_file_name (retpath.c_str()); if (cf) -- cgit