aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-07-24 07:41:31 +0000
committerChris Lattner <sabre@nondot.org>2004-07-24 07:41:31 +0000
commitde0213b9f551fa1fb0743f6b1150205180be5c9c (patch)
tree89e2aec7e6ed381849a5a79a915572cd69311fe7 /lib/Support
parent060913cce42d8b746194c7ebd8b19c9789a03909 (diff)
downloadexternal_llvm-de0213b9f551fa1fb0743f6b1150205180be5c9c.zip
external_llvm-de0213b9f551fa1fb0743f6b1150205180be5c9c.tar.gz
external_llvm-de0213b9f551fa1fb0743f6b1150205180be5c9c.tar.bz2
Add support for killing the program if it executes for too long.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@15158 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/SystemUtils.cpp54
1 files changed, 42 insertions, 12 deletions
diff --git a/lib/Support/SystemUtils.cpp b/lib/Support/SystemUtils.cpp
index 00dcd46..f232d61 100644
--- a/lib/Support/SystemUtils.cpp
+++ b/lib/Support/SystemUtils.cpp
@@ -125,9 +125,14 @@ static void RedirectFD(const std::string &File, int FD) {
close(InFD); // Close the original FD
}
+static bool Timeout = false;
+static void TimeOutHandler(int Sig) {
+ Timeout = true;
+}
+
/// RunProgramWithTimeout - This function executes the specified program, with
/// the specified null-terminated argument array, with the stdin/out/err fd's
-/// redirected, with a timeout specified on the command line. This terminates
+/// redirected, with a timeout specified by the last argument. This terminates
/// the calling program if there is an error executing the specified program.
/// It returns the return value of the program, or -1 if a timeout is detected.
///
@@ -135,9 +140,8 @@ int llvm::RunProgramWithTimeout(const std::string &ProgramPath,
const char **Args,
const std::string &StdInFile,
const std::string &StdOutFile,
- const std::string &StdErrFile) {
- // FIXME: install sigalarm handler here for timeout...
-
+ const std::string &StdErrFile,
+ unsigned NumSeconds) {
#ifdef HAVE_SYS_WAIT_H
int Child = fork();
switch (Child) {
@@ -165,24 +169,50 @@ int llvm::RunProgramWithTimeout(const std::string &ProgramPath,
// Make sure all output has been written while waiting
std::cout << std::flush;
+ // Install a timeout handler.
+ Timeout = false;
+ struct sigaction Act, Old;
+ Act.sa_sigaction = 0;
+ Act.sa_handler = TimeOutHandler;
+ Act.sa_flags = SA_NOMASK;
+ sigaction(SIGALRM, &Act, &Old);
+
+ // Set the timeout if one is set.
+ if (NumSeconds)
+ alarm(NumSeconds);
+
int Status;
- if (wait(&Status) != Child) {
+ while (wait(&Status) != Child) {
if (errno == EINTR) {
- static bool FirstTimeout = true;
- if (FirstTimeout) {
- std::cout <<
+ if (Timeout) {
+ static bool FirstTimeout = true;
+ if (FirstTimeout) {
+ std::cout <<
"*** Program execution timed out! This mechanism is designed to handle\n"
" programs stuck in infinite loops gracefully. The -timeout option\n"
" can be used to change the timeout threshold or disable it completely\n"
" (with -timeout=0). This message is only displayed once.\n";
- FirstTimeout = false;
+ FirstTimeout = false;
+ }
}
+
+ // Kill the child.
+ kill(Child, SIGKILL);
+
+ if (wait(&Status) != Child)
+ std::cerr << "Something funny happened waiting for the child!\n";
+
+ alarm(0);
+ sigaction(SIGALRM, &Old, 0);
return -1; // Timeout detected
+ } else {
+ std::cerr << "Error waiting for child process!\n";
+ exit(1);
}
-
- std::cerr << "Error waiting for child process!\n";
- exit(1);
}
+
+ alarm(0);
+ sigaction(SIGALRM, &Old, 0);
return Status;
#else