Commit 66724af8 authored by Vladimir's avatar Vladimir Committed by Brad King
Browse files

SystemTools: Teach FindProgram to find non-readable programs

This commit fixes FindProgram failing to detect executable without
read bit set. find_program internally uses SystemTools::FileExists which
calls access(R_OK) instead of access(X_OK).
Replacing SystemTools::FileExists with SystemTools::TestFileAccess fixes
this issue.

Fine example of such program is sudo.
parent 25694819
......@@ -2804,7 +2804,7 @@ std::string SystemTools::FindProgram(const std::string& name,
for (std::string const& ext : extensions) {
tryPath = name;
tryPath += ext;
if (SystemTools::FileExists(tryPath, true)) {
if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
......@@ -2812,7 +2812,7 @@ std::string SystemTools::FindProgram(const std::string& name,
#endif
// now try just the name
if (SystemTools::FileExists(name, true)) {
if (SystemTools::FileIsExecutable(name)) {
return SystemTools::CollapseFullPath(name);
}
// now construct the path
......@@ -2842,7 +2842,7 @@ std::string SystemTools::FindProgram(const std::string& name,
tryPath = p;
tryPath += name;
tryPath += ext;
if (SystemTools::FileExists(tryPath, true)) {
if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
......@@ -2850,7 +2850,7 @@ std::string SystemTools::FindProgram(const std::string& name,
// now try it without them
tryPath = p;
tryPath += name;
if (SystemTools::FileExists(tryPath, true)) {
if (SystemTools::FileIsExecutable(tryPath)) {
return SystemTools::CollapseFullPath(tryPath);
}
}
......@@ -3005,6 +3005,11 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
}
}
bool SystemTools::FileIsExecutable(const std::string& name)
{
return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
}
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
......@@ -3171,7 +3176,7 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
failures.push_back(self);
SystemTools::ConvertToUnixSlashes(self);
self = SystemTools::FindProgram(self);
if (!SystemTools::FileExists(self)) {
if (!SystemTools::FileIsExecutable(self)) {
if (buildDir) {
std::string intdir = ".";
#ifdef CMAKE_INTDIR
......@@ -3186,14 +3191,14 @@ bool SystemTools::FindProgramPath(const char* argv0, std::string& pathOut,
}
}
if (installPrefix) {
if (!SystemTools::FileExists(self)) {
if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
self = installPrefix;
self += "/bin/";
self += exeName;
}
}
if (!SystemTools::FileExists(self)) {
if (!SystemTools::FileIsExecutable(self)) {
failures.push_back(self);
std::ostringstream msg;
msg << "Can not find the command line program ";
......
......@@ -676,6 +676,11 @@ public:
*/
static bool FileIsDirectory(const std::string& name);
/**
* Return true if the file is an executable
*/
static bool FileIsExecutable(const std::string& name);
/**
* Return true if the file is a symlink
*/
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment