From a607202a68085cee4d18894392be647d6cd4a53e Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Tue, 8 Sep 2009 19:50:27 +0000 Subject: [PATCH] Add a Kill() function to the Program class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81246 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/System/Program.h | 17 ++++++++++++++--- lib/System/Unix/Program.inc | 10 ++++++++++ lib/System/Win32/Program.inc | 29 ++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/include/llvm/System/Program.h b/include/llvm/System/Program.h index 7f96245130f..ae37ece4b60 100644 --- a/include/llvm/System/Program.h +++ b/include/llvm/System/Program.h @@ -30,7 +30,7 @@ namespace sys { /// @brief An abstraction for finding and executing programs. class Program { /// Opaque handle for target specific data. - void *Data; + void *Data; unsigned Pid_; @@ -43,8 +43,8 @@ namespace sys { public: Program(); - ~Program(); - + ~Program(); + /// Return process ID of this program. unsigned GetPid() { return Pid_; } @@ -103,6 +103,17 @@ namespace sys { ///< program. ); + /// This function terminates the program. + /// @returns true if an error occured. + /// @see Execute + /// @brief Terminates the program. + bool Kill + ( std::string* ErrMsg = 0 ///< 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 invoking the + ///< program. + ); + /// This static constructor (factory) will attempt to locate a program in /// the operating system's file system using some pre-determined set of /// locations to search (e.g. the PATH on Unix). diff --git a/lib/System/Unix/Program.inc b/lib/System/Unix/Program.inc index fca92923825..fdd0c25fd14 100644 --- a/lib/System/Unix/Program.inc +++ b/lib/System/Unix/Program.inc @@ -283,6 +283,16 @@ Program::Wait(unsigned secondsToWait, } +bool +Program::Kill(std::string* ErrMsg) { + if (Pid_ == 0) { + MakeErrMsg(ErrMsg, "Process not started!"); + return true; + } + + return (kill(Pid_, SIGKILL) == 0); +} + bool Program::ChangeStdinToBinary(){ // Do nothing, as Unix doesn't differentiate between text and binary. return false; diff --git a/lib/System/Win32/Program.inc b/lib/System/Win32/Program.inc index 804273bf23d..4f4b6b32b1d 100644 --- a/lib/System/Win32/Program.inc +++ b/lib/System/Win32/Program.inc @@ -28,11 +28,11 @@ using namespace sys; Program::Program() : Pid_(0), Data(0) {} Program::~Program() { - if (Data) { - HANDLE hProcess = (HANDLE) Data; - CloseHandle(hProcess); - Data = 0; - } + if (Data) { + HANDLE hProcess = (HANDLE) Data; + CloseHandle(hProcess); + Data = 0; + } } // This function just uses the PATH environment variable to find the program. @@ -121,7 +121,7 @@ static HANDLE RedirectIO(const Path *path, int fd, std::string* ErrMsg) { /// ArgNeedsQuotes - Check whether argument needs to be quoted when calling /// CreateProcess. -static bool ArgNeedsQuotes(const char *Str) { +static bool ArgNeedsQuotes(const char *Str) { return Str[0] == '\0' || strchr(Str, ' ') != 0; } @@ -137,7 +137,7 @@ Program::Execute(const Path& path, CloseHandle(Data); Data = 0; } - + if (!path.canExecute()) { if (ErrMsg) *ErrMsg = "program not executable"; @@ -266,7 +266,7 @@ Program::Execute(const Path& path, } Pid_ = pi.dwProcessId; Data = pi.hProcess; - + // Make sure these get closed no matter what. AutoHandle hThread(pi.hThread); @@ -307,7 +307,7 @@ Program::Wait(unsigned secondsToWait, } HANDLE hProcess = (HANDLE) Data; - + // Wait for the process to terminate. DWORD millisecondsToWait = INFINITE; if (secondsToWait > 0) @@ -335,6 +335,17 @@ Program::Wait(unsigned secondsToWait, return status; } +bool +Program::Kill(std::string* ErrMsg) { + if (Data == 0) { + MakeErrMsg(ErrMsg, "Process not started!"); + return true; + } + + HANDLE hProcess = reinterpret_cast(Data); + return TerminateProcess(hProcess, 1); +} + bool Program::ChangeStdinToBinary(){ int result = _setmode( _fileno(stdin), _O_BINARY ); return result == -1;