summaryrefslogtreecommitdiffstats
path: root/Source/cmSystemTools.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2006-12-14 15:03:25 (GMT)
committerBrad King <brad.king@kitware.com>2006-12-14 15:03:25 (GMT)
commit0fcccb151fc6c8b803eff19af94ace1f8db773f2 (patch)
tree11c9903aff9f3ec903bfa7852d3188f6db3aedc5 /Source/cmSystemTools.cxx
parent3106262ec0928e0c39eac7e81a53f97847f4c5ac (diff)
downloadCMake-0fcccb151fc6c8b803eff19af94ace1f8db773f2.zip
CMake-0fcccb151fc6c8b803eff19af94ace1f8db773f2.tar.gz
CMake-0fcccb151fc6c8b803eff19af94ace1f8db773f2.tar.bz2
ENH: Changes from Ryan C. Gordon to fix old process execution on BeOS.
Diffstat (limited to 'Source/cmSystemTools.cxx')
-rw-r--r--Source/cmSystemTools.cxx38
1 files changed, 38 insertions, 0 deletions
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 5684a5a..3144f5a 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -713,6 +713,22 @@ bool RunCommandViaSystem(const char* command,
#else // We have popen
+// BeOS seems to return from a successful pclose() before the process has
+// legitimately exited, or at least before SIGCHLD is thrown...the signal may
+// come quite some time after pclose returns! This causes havoc with later
+// parts of CMake that expect to catch the signal from other child processes,
+// so we explicitly wait to catch it here. This should be safe to do with
+// popen() so long as we don't actually collect the zombie process ourselves.
+#ifdef __BEOS__
+#include <signal.h>
+#undef SIGBUS // this is the same as SIGSEGV on BeOS and causes issues below.
+static volatile bool beos_seen_signal = false;
+static void beos_popen_workaround(int sig)
+{
+ beos_seen_signal = true;
+}
+#endif
+
bool RunCommandViaPopen(const char* command,
const char* dir,
std::string& output,
@@ -745,9 +761,18 @@ bool RunCommandViaPopen(const char* command,
}
fflush(stdout);
fflush(stderr);
+
+#ifdef __BEOS__
+ beos_seen_signal = false;
+ signal(SIGCHLD, beos_popen_workaround);
+#endif
+
FILE* cpipe = popen(command, "r");
if(!cpipe)
{
+#ifdef __BEOS__
+ signal(SIGCHLD, SIG_DFL);
+#endif
return false;
}
fgets(buffer, BUFFER_SIZE, cpipe);
@@ -762,6 +787,19 @@ bool RunCommandViaPopen(const char* command,
}
retVal = pclose(cpipe);
+
+#ifdef __BEOS__
+ for (int i = 0; (!beos_seen_signal) && (i < 3); i++)
+ {
+ ::sleep(1); // signals should interrupt this...
+ }
+
+ if (!beos_seen_signal)
+ {
+ signal(SIGCHLD, SIG_DFL); // oh well, didn't happen. Go on anyhow.
+ }
+#endif
+
if (WIFEXITED(retVal))
{
retVal = WEXITSTATUS(retVal);