Skip to content

Commit

Permalink
Add support for OpenBSD.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mdempsky committed May 1, 2013
1 parent 4c552c2 commit 65a58e3
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 21 deletions.
2 changes: 1 addition & 1 deletion bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')

Expand Down
7 changes: 6 additions & 1 deletion platform_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -30,6 +30,8 @@ def __init__( self, platform):
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'):
Expand Down Expand Up @@ -59,5 +61,8 @@ def is_solaris(self):
def is_freebsd(self):
return self._platform == 'freebsd'

def is_openbsd(self):
return self._platform == 'openbsd'

def is_sunos5(self):
return self._platform == 'sunos5'
30 changes: 13 additions & 17 deletions src/subprocess-posix.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -155,8 +155,6 @@ void SubprocessSet::SetInterruptedFlag(int signum) {
}

SubprocessSet::SubprocessSet() {
interrupted_ = false;

sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGINT);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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();
Expand All @@ -277,9 +273,9 @@ bool SubprocessSet::DoWork() {
++i;
}

return false;
return interrupted_;
}
#endif // linux
#endif // linux || __OpenBSD__

Subprocess* SubprocessSet::NextFinished() {
if (finished_.empty())
Expand Down
4 changes: 2 additions & 2 deletions src/subprocess_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down

0 comments on commit 65a58e3

Please sign in to comment.