From e5f77cda25169fcbadc32f0f0b3da2e00ba86b7c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 29 Oct 2010 16:54:25 +0000 Subject: [PATCH] Make Program::Wait differentiate execution failure due to the file being not found from the file being not executable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@117664 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/System/Program.h | 5 +++-- lib/System/Program.cpp | 2 +- lib/System/Unix/Program.inc | 17 ++++++++++------- lib/System/Win32/Program.inc | 3 ++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/include/llvm/System/Program.h b/include/llvm/System/Program.h index 7017305a2eb..0c14076e309 100644 --- a/include/llvm/System/Program.h +++ b/include/llvm/System/Program.h @@ -90,12 +90,13 @@ namespace sys { /// @see Execute /// @brief Waits for the program to exit. int Wait - ( unsigned secondsToWait = 0, ///< If non-zero, this specifies the amount + ( const Path& path, ///< The path to the child process executable. + unsigned secondsToWait, ///< If non-zero, this specifies the amount ///< of time to wait for the child process to exit. If the time ///< expires, the child is killed and this call returns. If zero, ///< this function will wait until the child finishes or forever if ///< it doesn't. - std::string* ErrMsg = 0 ///< If non-zero, provides a pointer to a string + std::string* ErrMsg ///< If non-zero, provides a pointer to a string ///< instance in which error messages will be returned. If the string ///< is non-empty upon return an error occurred while waiting. ); diff --git a/lib/System/Program.cpp b/lib/System/Program.cpp index cd58c2cc578..90aba763fa9 100644 --- a/lib/System/Program.cpp +++ b/lib/System/Program.cpp @@ -31,7 +31,7 @@ Program::ExecuteAndWait(const Path& path, std::string* ErrMsg) { Program prg; if (prg.Execute(path, args, envp, redirects, memoryLimit, ErrMsg)) - return prg.Wait(secondsToWait, ErrMsg); + return prg.Wait(path, secondsToWait, ErrMsg); else return -1; } diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc index 76012afcbaa..b92d080bab4 100644 --- a/lib/System/Unix/Program.inc +++ b/lib/System/Unix/Program.inc @@ -228,12 +228,6 @@ Program::Execute(const Path &path, const char **args, const char **envp, } #endif - if (!path.canExecute()) { - if (ErrMsg) - *ErrMsg = path.str() + " is not executable"; - return false; - } - // Create a child process. int child = fork(); switch (child) { @@ -297,7 +291,8 @@ Program::Execute(const Path &path, const char **args, const char **envp, } int -Program::Wait(unsigned secondsToWait, +Program::Wait(const sys::Path &path, + unsigned secondsToWait, std::string* ErrMsg) { #ifdef HAVE_SYS_WAIT_H @@ -355,6 +350,14 @@ Program::Wait(unsigned secondsToWait, int result = 0; if (WIFEXITED(status)) { result = WEXITSTATUS(status); +#ifdef HAVE_POSIX_SPAWN + // The posix_spawn child process returns 127 on any kind of error. + // Following the POSIX convention for command-line tools (which posix_spawn + // itself apparently does not), check to see if the failure was due to some + // reason other than the file not existing, and return 126 in this case. + if (result == 127 && path.exists()) + result = 126; +#endif if (result == 127) { *ErrMsg = llvm::sys::StrError(ENOENT); return -1; diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc index ea1b5a6a069..b55aa2fa80f 100644 --- a/lib/System/Win32/Program.inc +++ b/lib/System/Win32/Program.inc @@ -337,7 +337,8 @@ Program::Execute(const Path& path, } int -Program::Wait(unsigned secondsToWait, +Program::Wait(const Path &path, + unsigned secondsToWait, std::string* ErrMsg) { if (Data_ == 0) { MakeErrMsg(ErrMsg, "Process not started!"); -- 2.34.1