summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--HACKING.md4
-rw-r--r--README6
-rw-r--r--RELEASING4
-rwxr-xr-xconfigure.py53
-rw-r--r--doc/manual.asciidoc1
-rw-r--r--misc/ninja.vim6
-rw-r--r--misc/packaging/ninja.spec2
-rw-r--r--src/build.cc7
-rw-r--r--src/build_log.cc11
-rw-r--r--src/build_test.cc8
-rw-r--r--src/depfile_parser.cc58
-rw-r--r--src/depfile_parser.in.cc4
-rw-r--r--src/depfile_parser_test.cc7
-rw-r--r--src/getopt.c2
-rw-r--r--src/getopt.h2
-rw-r--r--src/graph_test.cc4
-rwxr-xr-xsrc/inline.sh2
-rw-r--r--src/ninja.cc5
-rw-r--r--src/ninja_test.cc3
-rw-r--r--src/subprocess-posix.cc12
-rw-r--r--src/subprocess.h1
-rw-r--r--src/subprocess_test.cc24
-rw-r--r--src/util.cc12
24 files changed, 168 insertions, 71 deletions
diff --git a/.gitignore b/.gitignore
index f7fc044..5a85203 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ TAGS
/build
/build.ninja
/ninja
+/ninja.bootstrap
/build_log_perftest
/canon_perftest
/depfile_parser_perftest
diff --git a/HACKING.md b/HACKING.md
index 7fdb152..d8cb2a2 100644
--- a/HACKING.md
+++ b/HACKING.md
@@ -53,7 +53,7 @@ obvious exceptions (fixing typos in comments don't need tests).
I am very wary of changes that increase the complexity of Ninja (in
particular, new build file syntax or command-line flags) or increase
-the maintenance burden of Ninja. Ninja is already successfully in use
+the maintenance burden of Ninja. Ninja is already successfully used
by hundreds of developers for large projects and it already achieves
(most of) the goals I set out for it to do. It's probably best to
discuss new feature ideas on the mailing list before I shoot down your
@@ -74,7 +74,7 @@ build "all" before committing to verify the other source still works!
## Testing performance impact of changes
If you have a Chrome build handy, it's a good test case. Otherwise,
-[the github downoads page](https://github.com/martine/ninja/downloads)
+[the github downoads page](https://github.com/ninja-build/ninja/releases)
has a copy of the Chrome build files (and depfiles). You can untar
that, then run
diff --git a/README b/README
index 20630c4..59d7ff9 100644
--- a/README
+++ b/README
@@ -1,12 +1,12 @@
Ninja is a small build system with a focus on speed.
-http://martine.github.com/ninja/
+http://ninja-build.org/
-See the manual -- http://martine.github.com/ninja/manual.html or
+See the manual -- http://ninja-build.org/manual.html or
doc/manual.asciidoc included in the distribution -- for background
and more details.
Binaries for Linux, Mac, and Windows are available at
- https://github.com/martine/ninja/releases
+ https://github.com/ninja-build/ninja/releases
Run './ninja -h' for Ninja help.
To build your own binary, on many platforms it should be sufficient to
diff --git a/RELEASING b/RELEASING
index 4d08253..20da5d9 100644
--- a/RELEASING
+++ b/RELEASING
@@ -17,14 +17,14 @@ Push new release branch:
Release on github:
1. https://github.com/blog/1547-release-your-software
- Add binaries to https://github.com/martine/ninja/releases
+ Add binaries to https://github.com/ninja-build/ninja/releases
Make announcement on mailing list:
1. copy old mail
Update website:
1. Make sure your ninja checkout is on the v1.5.0 tag
-2. Clone https://github.com/martine/martine.github.io
+2. Clone https://github.com/ninja-build/ninja-build.github.io
3. In that repo, `cd ninja && ./update-docs.sh`
4. Update index.html with newest version and link to release notes
5. git commit -m 'run update-docs.sh, 1.5.0 release'
diff --git a/configure.py b/configure.py
index 64f940b..0710ea2 100755
--- a/configure.py
+++ b/configure.py
@@ -58,11 +58,13 @@ class Platform(object):
self._platform = 'bitrig'
elif self._platform.startswith('netbsd'):
self._platform = 'netbsd'
+ elif self._platform.startswith('aix'):
+ self._platform = 'aix'
@staticmethod
def known_platforms():
return ['linux', 'darwin', 'freebsd', 'openbsd', 'solaris', 'sunos5',
- 'mingw', 'msvc', 'gnukfreebsd', 'bitrig', 'netbsd']
+ 'mingw', 'msvc', 'gnukfreebsd', 'bitrig', 'netbsd', 'aix']
def platform(self):
return self._platform
@@ -81,7 +83,7 @@ class Platform(object):
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
out, err = popen.communicate()
- return '/FS ' in str(out)
+ return b'/FS ' in out
def is_windows(self):
return self.is_mingw() or self.is_msvc()
@@ -89,6 +91,9 @@ class Platform(object):
def is_solaris(self):
return self._platform == 'solaris'
+ def is_aix(self):
+ return self._platform == 'aix'
+
def uses_usr_local(self):
return self._platform in ('freebsd', 'openbsd', 'bitrig')
@@ -96,8 +101,12 @@ class Platform(object):
return self._platform in ('linux', 'openbsd', 'bitrig')
def supports_ninja_browse(self):
- return not self.is_windows() and not self.is_solaris()
+ return (not self.is_windows()
+ and not self.is_solaris()
+ and not self.is_aix())
+ def can_rebuild_in_place(self):
+ return not (self.is_windows() or self.is_aix())
class Bootstrap:
"""API shim for ninja_syntax.Writer that instead runs the commands.
@@ -346,6 +355,8 @@ if platform.is_mingw():
ldflags.append('-static')
elif platform.is_solaris():
cflags.remove('-fvisibility=hidden')
+elif platform.is_aix():
+ cflags.remove('-fvisibility=hidden')
elif platform.is_msvc():
pass
else:
@@ -486,6 +497,8 @@ if platform.is_windows():
objs += cc('getopt')
else:
objs += cxx('subprocess-posix')
+if platform.is_aix():
+ objs += cc('getopt')
if platform.is_msvc():
ninja_lib = n.build(built('ninja.lib'), 'ar', objs)
else:
@@ -497,6 +510,9 @@ if platform.is_msvc():
else:
libs.append('-lninja')
+if platform.is_aix():
+ libs.append('-lperfstat')
+
all_targets = []
n.comment('Main executable is library plus main() function.')
@@ -626,17 +642,28 @@ n.build('all', 'phony', all_targets)
n.close()
print('wrote %s.' % BUILD_FILENAME)
-verbose = ''
-if options.verbose:
- verbose = ' -v'
-
if options.bootstrap:
print('bootstrap complete. rebuilding...')
- if platform.is_windows():
- bootstrap_exe = 'ninja.bootstrap.exe'
+
+ rebuild_args = []
+
+ if platform.can_rebuild_in_place():
+ rebuild_args.append('./ninja')
+ else:
+ if platform.is_windows():
+ bootstrap_exe = 'ninja.bootstrap.exe'
+ final_exe = 'ninja.exe'
+ else:
+ bootstrap_exe = './ninja.bootstrap'
+ final_exe = './ninja'
+
if os.path.exists(bootstrap_exe):
os.unlink(bootstrap_exe)
- os.rename('ninja.exe', bootstrap_exe)
- subprocess.check_call('ninja.bootstrap.exe%s' % verbose, shell=True)
- else:
- subprocess.check_call('./ninja%s' % verbose, shell=True)
+ os.rename(final_exe, bootstrap_exe)
+
+ rebuild_args.append(bootstrap_exe)
+
+ if options.verbose:
+ rebuild_args.append('-v')
+
+ subprocess.check_call(rebuild_args)
diff --git a/doc/manual.asciidoc b/doc/manual.asciidoc
index 47b7456..3c193f1 100644
--- a/doc/manual.asciidoc
+++ b/doc/manual.asciidoc
@@ -1,6 +1,5 @@
Ninja
=====
-Evan Martin <martine@danga.com>
Introduction
diff --git a/misc/ninja.vim b/misc/ninja.vim
index f34588f..190d9ce 100644
--- a/misc/ninja.vim
+++ b/misc/ninja.vim
@@ -1,6 +1,6 @@
" ninja build file syntax.
" Language: ninja build file as described at
-" http://martine.github.com/ninja/manual.html
+" http://ninja-build.org/manual.html
" Version: 1.4
" Last Change: 2014/05/13
" Maintainer: Nicolas Weber <nicolasweber@gmx.de>
@@ -9,8 +9,8 @@
" upstream.
" ninja lexer and parser are at
-" https://github.com/martine/ninja/blob/master/src/lexer.in.cc
-" https://github.com/martine/ninja/blob/master/src/manifest_parser.cc
+" https://github.com/ninja-build/ninja/blob/master/src/lexer.in.cc
+" https://github.com/ninja-build/ninja/blob/master/src/manifest_parser.cc
if exists("b:current_syntax")
finish
diff --git a/misc/packaging/ninja.spec b/misc/packaging/ninja.spec
index fa244a6..05f5a07 100644
--- a/misc/packaging/ninja.spec
+++ b/misc/packaging/ninja.spec
@@ -4,7 +4,7 @@ Version: %{ver}
Release: %{rel}%{?dist}
Group: Development/Tools
License: Apache 2.0
-URL: https://github.com/martine/ninja
+URL: https://github.com/ninja-build/ninja
Source0: %{name}-%{version}-%{rel}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{rel}
diff --git a/src/build.cc b/src/build.cc
index e4820d0..0e9a399 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -96,7 +96,8 @@ void BuildStatus::BuildEdgeStarted(Edge* edge) {
running_edges_.insert(make_pair(edge, start_time));
++started_edges_;
- PrintStatus(edge);
+ if (edge->use_console() || printer_.is_smart_terminal())
+ PrintStatus(edge);
if (edge->use_console())
printer_.SetConsoleLocked(true);
@@ -121,7 +122,7 @@ void BuildStatus::BuildEdgeFinished(Edge* edge,
if (config_.verbosity == BuildConfig::QUIET)
return;
- if (!edge->use_console() && printer_.is_smart_terminal())
+ if (!edge->use_console())
PrintStatus(edge);
// Print the command that is spewing before printing its output.
@@ -362,7 +363,7 @@ void Plan::ScheduleWork(Edge* edge) {
if (pool->ShouldDelayEdge()) {
// The graph is not completely clean. Some Nodes have duplicate Out edges.
// We need to explicitly ignore these here, otherwise their work will get
- // scheduled twice (see https://github.com/martine/ninja/pull/519)
+ // scheduled twice (see https://github.com/ninja-build/ninja/pull/519)
if (ready_.count(edge)) {
return;
}
diff --git a/src/build_log.cc b/src/build_log.cc
index 589c6da..8a52514 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -12,6 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// On AIX, inttypes.h gets indirectly included by build_log.h.
+// It's easiest just to ask for the printf format macros right away.
+#ifndef _WIN32
+#ifndef __STDC_FORMAT_MACROS
+#define __STDC_FORMAT_MACROS
+#endif
+#endif
+
#include "build_log.h"
#include <errno.h>
@@ -19,9 +27,6 @@
#include <string.h>
#ifndef _WIN32
-#ifndef __STDC_FORMAT_MACROS
-#define __STDC_FORMAT_MACROS
-#endif
#include <inttypes.h>
#include <unistd.h>
#endif
diff --git a/src/build_test.cc b/src/build_test.cc
index 52a17c9..20fb664 100644
--- a/src/build_test.cc
+++ b/src/build_test.cc
@@ -718,7 +718,7 @@ TEST_F(BuildTest, TwoOutputs) {
}
// Test case from
-// https://github.com/martine/ninja/issues/148
+// https://github.com/ninja-build/ninja/issues/148
TEST_F(BuildTest, MultiOutIn) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule touch\n"
@@ -1299,7 +1299,7 @@ TEST_F(BuildWithLogTest, RestatSingleDependentOutputDirty) {
}
// Test scenario, in which an input file is removed, but output isn't changed
-// https://github.com/martine/ninja/issues/295
+// https://github.com/ninja-build/ninja/issues/295
TEST_F(BuildWithLogTest, RestatMissingInput) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule true\n"
@@ -2047,7 +2047,7 @@ TEST_F(BuildWithDepsLogTest, DepFileDepsLogCanonicalize) {
#endif
/// Check that a restat rule doesn't clear an edge if the depfile is missing.
-/// Follows from: https://github.com/martine/ninja/issues/603
+/// Follows from: https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildTest, RestatMissingDepfile) {
const char* manifest =
"rule true\n"
@@ -2071,7 +2071,7 @@ const char* manifest =
}
/// Check that a restat rule doesn't clear an edge if the deps are missing.
-/// https://github.com/martine/ninja/issues/603
+/// https://github.com/ninja-build/ninja/issues/603
TEST_F(BuildWithDepsLogTest, RestatMissingDepfileDepslog) {
string err;
const char* manifest =
diff --git a/src/depfile_parser.cc b/src/depfile_parser.cc
index 7268f31..7cee892 100644
--- a/src/depfile_parser.cc
+++ b/src/depfile_parser.cc
@@ -47,7 +47,7 @@ bool DepfileParser::Parse(string* content, string* err) {
const char* start = in;
{
- char yych;
+ unsigned char yych;
static const unsigned char yybm[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@@ -65,22 +65,22 @@ bool DepfileParser::Parse(string* content, string* err) {
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 128, 128, 128, 128,
128, 128, 128, 128, 0, 128, 128, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
+ 128, 128, 128, 128, 128, 128, 128, 128,
};
yych = *in;
@@ -106,24 +106,28 @@ bool DepfileParser::Parse(string* content, string* err) {
}
}
} else {
- if (yych <= '^') {
- if (yych <= 'Z') {
+ if (yych <= '_') {
+ if (yych <= '[') {
if (yych <= '?') goto yy9;
- goto yy5;
+ if (yych <= 'Z') goto yy5;
+ goto yy9;
} else {
- if (yych != '\\') goto yy9;
+ if (yych <= '\\') goto yy2;
+ if (yych <= '^') goto yy9;
+ goto yy5;
}
} else {
- if (yych <= '{') {
- if (yych == '`') goto yy9;
- goto yy5;
- } else {
- if (yych <= '|') goto yy9;
- if (yych <= '~') goto yy5;
+ if (yych <= '|') {
+ if (yych <= '`') goto yy9;
+ if (yych <= '{') goto yy5;
goto yy9;
+ } else {
+ if (yych == 0x7F) goto yy9;
+ goto yy5;
}
}
}
+yy2:
++in;
if ((yych = *in) <= '"') {
if (yych <= '\f') {
diff --git a/src/depfile_parser.in.cc b/src/depfile_parser.in.cc
index deaee5b..98c1621 100644
--- a/src/depfile_parser.in.cc
+++ b/src/depfile_parser.in.cc
@@ -45,7 +45,7 @@ bool DepfileParser::Parse(string* content, string* err) {
// start: beginning of the current parsed span.
const char* start = in;
/*!re2c
- re2c:define:YYCTYPE = "char";
+ re2c:define:YYCTYPE = "unsigned char";
re2c:define:YYCURSOR = in;
re2c:define:YYLIMIT = end;
@@ -73,7 +73,7 @@ bool DepfileParser::Parse(string* content, string* err) {
*out++ = yych;
continue;
}
- [a-zA-Z0-9+,/_:.~()}{@=!-]+ {
+ [a-zA-Z0-9+,/_:.~()}{@=!\x80-\xFF-]+ {
// Got a span of plain text.
int len = (int)(in - start);
// Need to shift it over if we're overwriting backslashes.
diff --git a/src/depfile_parser_test.cc b/src/depfile_parser_test.cc
index fe9424a..ee798f8 100644
--- a/src/depfile_parser_test.cc
+++ b/src/depfile_parser_test.cc
@@ -121,18 +121,21 @@ TEST_F(DepfileParserTest, SpecialChars) {
EXPECT_TRUE(Parse(
"C:/Program\\ Files\\ (x86)/Microsoft\\ crtdefs.h: \n"
" en@quot.header~ t+t-x!=1 \n"
-" openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
+" openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif\n"
+" Fu\303\244ball",
&err));
ASSERT_EQ("", err);
EXPECT_EQ("C:/Program Files (x86)/Microsoft crtdefs.h",
parser_.out_.AsString());
- ASSERT_EQ(3u, parser_.ins_.size());
+ ASSERT_EQ(4u, parser_.ins_.size());
EXPECT_EQ("en@quot.header~",
parser_.ins_[0].AsString());
EXPECT_EQ("t+t-x!=1",
parser_.ins_[1].AsString());
EXPECT_EQ("openldap/slapd.d/cn=config/cn=schema/cn={0}core.ldif",
parser_.ins_[2].AsString());
+ EXPECT_EQ("Fu\303\244ball",
+ parser_.ins_[3].AsString());
}
TEST_F(DepfileParserTest, UnifyMultipleOutputs) {
diff --git a/src/getopt.c b/src/getopt.c
index 3350fb9..0c2ef35 100644
--- a/src/getopt.c
+++ b/src/getopt.c
@@ -385,11 +385,13 @@ getopt_internal (int argc, char **argv, char *shortopts,
return optopt;
}
+#ifndef _AIX
int
getopt (int argc, char **argv, char *optstring)
{
return getopt_internal (argc, argv, optstring, NULL, NULL, 0);
}
+#endif
int
getopt_long (int argc, char **argv, const char *shortopts,
diff --git a/src/getopt.h b/src/getopt.h
index b4247fb..965dc29 100644
--- a/src/getopt.h
+++ b/src/getopt.h
@@ -39,7 +39,9 @@ extern "C"
extern int optopt;
/* function prototypes */
+#ifndef _AIX
int getopt (int argc, char **argv, char *optstring);
+#endif
int getopt_long (int argc, char **argv, const char *shortopts,
const GETOPT_LONG_OPTION_T * longopts, int *longind);
int getopt_long_only (int argc, char **argv, const char *shortopts,
diff --git a/src/graph_test.cc b/src/graph_test.cc
index e41f5cc..44be8a5 100644
--- a/src/graph_test.cc
+++ b/src/graph_test.cc
@@ -153,7 +153,7 @@ TEST_F(GraphTest, VarInOutPathEscaping) {
#endif
}
-// Regression test for https://github.com/martine/ninja/issues/380
+// Regression test for https://github.com/ninja-build/ninja/issues/380
TEST_F(GraphTest, DepfileWithCanonicalizablePath) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule catdep\n"
@@ -172,7 +172,7 @@ TEST_F(GraphTest, DepfileWithCanonicalizablePath) {
EXPECT_FALSE(GetNode("out.o")->dirty());
}
-// Regression test for https://github.com/martine/ninja/issues/404
+// Regression test for https://github.com/ninja-build/ninja/issues/404
TEST_F(GraphTest, DepfileRemoved) {
ASSERT_NO_FATAL_FAILURE(AssertParse(&state_,
"rule catdep\n"
diff --git a/src/inline.sh b/src/inline.sh
index 5acc17b..fa282fa 100755
--- a/src/inline.sh
+++ b/src/inline.sh
@@ -20,6 +20,6 @@
varname="$1"
echo "const char $varname[] ="
-od -t x1 -A n -v | sed -e 's| ||g; s|..|\\x&|g; s|^|"|; s|$|"|'
+od -t x1 -A n -v | sed -e 's|[ \t]||g; s|..|\\x&|g; s|^|"|; s|$|"|'
echo ";"
diff --git a/src/ninja.cc b/src/ninja.cc
index a3d963f..21dede6 100644
--- a/src/ninja.cc
+++ b/src/ninja.cc
@@ -22,6 +22,9 @@
#include "getopt.h"
#include <direct.h>
#include <windows.h>
+#elif defined(_AIX)
+#include "getopt.h"
+#include <unistd.h>
#else
#include <getopt.h>
#include <unistd.h>
@@ -254,7 +257,7 @@ bool NinjaMain::RebuildManifest(const char* input_file, string* err) {
// Even if the manifest was cleaned by a restat rule, claim that it was
// rebuilt. Not doing so can lead to crashes, see
- // https://github.com/martine/ninja/issues/874
+ // https://github.com/ninja-build/ninja/issues/874
return builder.Build(err);
}
diff --git a/src/ninja_test.cc b/src/ninja_test.cc
index 54d8784..11087b6 100644
--- a/src/ninja_test.cc
+++ b/src/ninja_test.cc
@@ -17,6 +17,9 @@
#ifdef _WIN32
#include "getopt.h"
+#elif defined(_AIX)
+#include "getopt.h"
+#include <unistd.h>
#else
#include <getopt.h>
#endif
diff --git a/src/subprocess-posix.cc b/src/subprocess-posix.cc
index f3baec2..2ddc709 100644
--- a/src/subprocess-posix.cc
+++ b/src/subprocess-posix.cc
@@ -64,6 +64,8 @@ bool Subprocess::Start(SubprocessSet* set, const string& command) {
break;
if (sigaction(SIGTERM, &set->old_term_act_, 0) < 0)
break;
+ if (sigaction(SIGHUP, &set->old_hup_act_, 0) < 0)
+ break;
if (sigprocmask(SIG_SETMASK, &set->old_mask_, 0) < 0)
break;
@@ -136,7 +138,8 @@ ExitStatus Subprocess::Finish() {
if (exit == 0)
return ExitSuccess;
} else if (WIFSIGNALED(status)) {
- if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM)
+ if (WTERMSIG(status) == SIGINT || WTERMSIG(status) == SIGTERM
+ || WTERMSIG(status) == SIGHUP)
return ExitInterrupted;
}
return ExitFailure;
@@ -167,6 +170,8 @@ void SubprocessSet::HandlePendingInterruption() {
interrupted_ = SIGINT;
else if (sigismember(&pending, SIGTERM))
interrupted_ = SIGTERM;
+ else if (sigismember(&pending, SIGHUP))
+ interrupted_ = SIGHUP;
}
SubprocessSet::SubprocessSet() {
@@ -174,6 +179,7 @@ SubprocessSet::SubprocessSet() {
sigemptyset(&set);
sigaddset(&set, SIGINT);
sigaddset(&set, SIGTERM);
+ sigaddset(&set, SIGHUP);
if (sigprocmask(SIG_BLOCK, &set, &old_mask_) < 0)
Fatal("sigprocmask: %s", strerror(errno));
@@ -184,6 +190,8 @@ SubprocessSet::SubprocessSet() {
Fatal("sigaction: %s", strerror(errno));
if (sigaction(SIGTERM, &act, &old_term_act_) < 0)
Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGHUP, &act, &old_hup_act_) < 0)
+ Fatal("sigaction: %s", strerror(errno));
}
SubprocessSet::~SubprocessSet() {
@@ -193,6 +201,8 @@ SubprocessSet::~SubprocessSet() {
Fatal("sigaction: %s", strerror(errno));
if (sigaction(SIGTERM, &old_term_act_, 0) < 0)
Fatal("sigaction: %s", strerror(errno));
+ if (sigaction(SIGHUP, &old_hup_act_, 0) < 0)
+ Fatal("sigaction: %s", strerror(errno));
if (sigprocmask(SIG_SETMASK, &old_mask_, 0) < 0)
Fatal("sigprocmask: %s", strerror(errno));
}
diff --git a/src/subprocess.h b/src/subprocess.h
index a001fc9..51f40b2 100644
--- a/src/subprocess.h
+++ b/src/subprocess.h
@@ -98,6 +98,7 @@ struct SubprocessSet {
struct sigaction old_int_act_;
struct sigaction old_term_act_;
+ struct sigaction old_hup_act_;
sigset_t old_mask_;
#endif
};
diff --git a/src/subprocess_test.cc b/src/subprocess_test.cc
index 07cc52f..066bbb7 100644
--- a/src/subprocess_test.cc
+++ b/src/subprocess_test.cc
@@ -122,6 +122,30 @@ TEST_F(SubprocessTest, InterruptParentWithSigTerm) {
ASSERT_FALSE("We should have been interrupted");
}
+TEST_F(SubprocessTest, InterruptChildWithSigHup) {
+ Subprocess* subproc = subprocs_.Add("kill -HUP $$");
+ ASSERT_NE((Subprocess *) 0, subproc);
+
+ while (!subproc->Done()) {
+ subprocs_.DoWork();
+ }
+
+ EXPECT_EQ(ExitInterrupted, subproc->Finish());
+}
+
+TEST_F(SubprocessTest, InterruptParentWithSigHup) {
+ Subprocess* subproc = subprocs_.Add("kill -HUP $PPID ; sleep 1");
+ ASSERT_NE((Subprocess *) 0, subproc);
+
+ while (!subproc->Done()) {
+ bool interrupted = subprocs_.DoWork();
+ if (interrupted)
+ return;
+ }
+
+ ASSERT_FALSE("We should have been interrupted");
+}
+
// A shell command to check if the current process is connected to a terminal.
// This is different from having stdin/stdout/stderr be a terminal. (For
// instance consider the command "yes < /dev/null > /dev/null 2>&1".
diff --git a/src/util.cc b/src/util.cc
index aa47f2f..d150fe2 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -45,6 +45,8 @@
#elif defined(__SVR4) && defined(__sun)
#include <unistd.h>
#include <sys/loadavg.h>
+#elif defined(_AIX)
+#include <libperfstat.h>
#elif defined(linux) || defined(__GLIBC__)
#include <sys/sysinfo.h>
#endif
@@ -573,6 +575,16 @@ double GetLoadAverage() {
return posix_compatible_load;
}
+#elif defined(_AIX)
+double GetLoadAverage() {
+ perfstat_cpu_total_t cpu_stats;
+ if (perfstat_cpu_total(NULL, &cpu_stats, sizeof(cpu_stats), 1) < 0) {
+ return -0.0f;
+ }
+
+ // Calculation taken from comment in libperfstats.h
+ return double(cpu_stats.loadavg[0]) / double(1 << SBITS);
+}
#else
double GetLoadAverage() {
double loadavg[3] = { 0.0f, 0.0f, 0.0f };