From 65a58e37a7dd48cb336668351d1cab3db0e4d5fe Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 1 May 2013 11:03:27 -0700 Subject: Add support for OpenBSD. 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 | 2 +- platform_helper.py | 7 ++++++- src/subprocess-posix.cc | 30 +++++++++++++----------------- src/subprocess_test.cc | 4 ++-- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/bootstrap.py b/bootstrap.py index a7a8ba6..0f6aa59 100755 --- a/bootstrap.py +++ b/bootstrap.py @@ -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') diff --git a/platform_helper.py b/platform_helper.py index 052c969..cd7298b 100644 --- a/platform_helper.py +++ b/platform_helper.py @@ -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' diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc index 8f1a04e..fb6d272 100644 --- a/src/subprocess-posix.cc +++ b/src/subprocess-posix.cc @@ -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(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 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::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()) diff --git a/src/subprocess_test.cc b/src/subprocess_test.cc index c3175da..afd9008 100644 --- a/src/subprocess_test.cc +++ b/src/subprocess_test.cc @@ -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. -- cgit v0.12