[cmake-commits] king committed cmSystemTools.cxx 1.332 1.333

cmake-commits at cmake.org cmake-commits at cmake.org
Thu Dec 14 10:03:27 EST 2006


Update of /cvsroot/CMake/CMake/Source
In directory public:/mounts/ram/cvs-serv12807

Modified Files:
	cmSystemTools.cxx 
Log Message:
ENH: Changes from Ryan C. Gordon to fix old process execution on BeOS.


Index: cmSystemTools.cxx
===================================================================
RCS file: /cvsroot/CMake/CMake/Source/cmSystemTools.cxx,v
retrieving revision 1.332
retrieving revision 1.333
diff -u -d -r1.332 -r1.333
--- cmSystemTools.cxx	5 Dec 2006 14:14:32 -0000	1.332
+++ cmSystemTools.cxx	14 Dec 2006 15:03:25 -0000	1.333
@@ -713,6 +713,22 @@
 
 #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 @@
     }
   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 @@
     }
 
   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);



More information about the Cmake-commits mailing list