Add support for OpenBSD.
authorMatthew Dempsky <mdempsky@google.com>
Wed, 1 May 2013 18:03:27 +0000 (11:03 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Wed, 1 May 2013 18:09:38 +0000 (11:09 -0700)
Use ppoll() on OpenBSD.  Also, fix interrupt handling to recognize
that on FreeBSD and OpenBSD, an interrupt might have been delivered
even if pselect()/ppoll() don't return -1/EINTR.

bootstrap.py
platform_helper.py
src/subprocess-posix.cc
src/subprocess_test.cc

index a7a8ba6..0f6aa59 100755 (executable)
@@ -52,7 +52,7 @@ def run(*args, **kwargs):
 # g++ call as well as in the later configure.py.
 cflags = os.environ.get('CFLAGS', '').split()
 ldflags = os.environ.get('LDFLAGS', '').split()
-if platform.is_freebsd():
+if platform.is_freebsd() or platform.is_openbsd():
     cflags.append('-I/usr/local/include')
     ldflags.append('-L/usr/local/lib')
 
index 052c969..cd7298b 100644 (file)
@@ -18,7 +18,7 @@
 import sys
 
 def platforms():
-    return ['linux', 'freebsd', 'solaris', 'sunos5', 'mingw', 'msvc']
+    return ['linux', 'freebsd', 'openbsd', 'solaris', 'sunos5', 'mingw', 'msvc']
 
 class Platform( object ):
     def __init__( self, platform):
@@ -30,6 +30,8 @@ class Platform( object ):
             self._platform = 'linux'
         elif self._platform.startswith('freebsd'):
             self._platform = 'freebsd'
+        elif self._platform.startswith('openbsd'):
+            self._platform = 'openbsd'
         elif self._platform.startswith('solaris'):
             self._platform = 'solaris'
         elif self._platform.startswith('mingw'):
@@ -59,5 +61,8 @@ class Platform( object ):
     def is_freebsd(self):
         return self._platform == 'freebsd'
 
+    def is_openbsd(self):
+        return self._platform == 'openbsd'
+
     def is_sunos5(self):
         return self._platform == 'sunos5'
index 8f1a04e..fb6d272 100644 (file)
@@ -49,12 +49,12 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
   if (pipe(output_pipe) < 0)
     Fatal("pipe: %s", strerror(errno));
   fd_ = output_pipe[0];
-#if !defined(linux)
-  // On linux we use ppoll in DoWork(); elsewhere we use pselect and so must
-  // avoid overly-large FDs.
+#if !defined(linux) && !defined(__OpenBSD__)
+  // On Linux and OpenBSD, we use ppoll in DoWork(); elsewhere we use pselect
+  // and so must avoid overly-large FDs.
   if (fd_ >= static_cast<int>(FD_SETSIZE))
     Fatal("pipe: %s", strerror(EMFILE));
-#endif  // !linux
+#endif  // !linux && !__OpenBSD__
   SetCloseOnExec(fd_);
 
   pid_ = fork();
@@ -155,8 +155,6 @@ void SubprocessSet::SetInterruptedFlag(int signum) {
 }
 
 SubprocessSet::SubprocessSet() {
-  interrupted_ = false;
-
   sigset_t set;
   sigemptyset(&set);
   sigaddset(&set, SIGINT);
@@ -189,7 +187,7 @@ Subprocess *SubprocessSet::Add(const string& command) {
   return subprocess;
 }
 
-#ifdef linux
+#if defined(linux) || defined(__OpenBSD__)
 bool SubprocessSet::DoWork() {
   vector<pollfd> fds;
   nfds_t nfds = 0;
@@ -204,15 +202,14 @@ bool SubprocessSet::DoWork() {
     ++nfds;
   }
 
+  interrupted_ = false;
   int ret = ppoll(&fds.front(), nfds, NULL, &old_mask_);
   if (ret == -1) {
     if (errno != EINTR) {
       perror("ninja: ppoll");
       return false;
     }
-    bool interrupted = interrupted_;
-    interrupted_ = false;
-    return interrupted;
+    return interrupted_;
   }
 
   nfds_t cur_nfd = 0;
@@ -233,10 +230,10 @@ bool SubprocessSet::DoWork() {
     ++i;
   }
 
-  return false;
+  return interrupted_;
 }
 
-#else  // linux
+#else  // linux || __OpenBSD__
 bool SubprocessSet::DoWork() {
   fd_set set;
   int nfds = 0;
@@ -252,15 +249,14 @@ bool SubprocessSet::DoWork() {
     }
   }
 
+  interrupted_ = false;
   int ret = pselect(nfds, &set, 0, 0, 0, &old_mask_);
   if (ret == -1) {
     if (errno != EINTR) {
       perror("ninja: pselect");
       return false;
     }
-    bool interrupted = interrupted_;
-    interrupted_ = false;
-    return interrupted;
+    return interrupted_;
   }
 
   for (vector<Subprocess*>::iterator i = running_.begin();
@@ -277,9 +273,9 @@ bool SubprocessSet::DoWork() {
     ++i;
   }
 
-  return false;
+  return interrupted_;
 }
-#endif  // linux
+#endif  // linux || __OpenBSD__
 
 Subprocess* SubprocessSet::NextFinished() {
   if (finished_.empty())
index c3175da..afd9008 100644 (file)
@@ -152,7 +152,7 @@ TEST_F(SubprocessTest, SetWithMulti) {
 
 // OS X's process limit is less than 1025 by default
 // (|sysctl kern.maxprocperuid| is 709 on 10.7 and 10.8 and less prior to that).
-#ifdef linux
+#if defined(linux) || defined(__OpenBSD__)
 TEST_F(SubprocessTest, SetWithLots) {
   // Arbitrary big number; needs to be over 1024 to confirm we're no longer
   // hostage to pselect.
@@ -179,7 +179,7 @@ TEST_F(SubprocessTest, SetWithLots) {
   }
   ASSERT_EQ(kNumProcs, subprocs_.finished_.size());
 }
-#endif  // linux
+#endif  // linux || __OpenBSD__
 
 // TODO: this test could work on Windows, just not sure how to simply
 // read stdin.