summaryrefslogtreecommitdiffstats
path: root/src/build.cc
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-03-31 15:12:12 (GMT)
committerNico Weber <nicolasweber@gmx.de>2015-03-31 19:21:57 (GMT)
commit3beebde51a2089ecb01820f1428efe0263deaeea (patch)
tree55aec535c37434dbe5893e8ed37c69891b6d4b74 /src/build.cc
parenta88b75d9a9df1b3722ad649ae275d342f3b57b22 (diff)
downloadNinja-3beebde51a2089ecb01820f1428efe0263deaeea.zip
Ninja-3beebde51a2089ecb01820f1428efe0263deaeea.tar.gz
Ninja-3beebde51a2089ecb01820f1428efe0263deaeea.tar.bz2
Let Stat() have an err outparam instead of writing to stderr.
Also check for Stat() failure in a few more places. This way, ninja doesn't print two "ninja: error: " lines if stat() fails during a build. It also makes it easier to keep the stat tests quiet. Every caller of Stat() needs to explicitly log the error string if that's desired.
Diffstat (limited to 'src/build.cc')
-rw-r--r--src/build.cc27
1 files changed, 16 insertions, 11 deletions
diff --git a/src/build.cc b/src/build.cc
index 1e10c7c..d898929 100644
--- a/src/build.cc
+++ b/src/build.cc
@@ -560,10 +560,12 @@ void Builder::Cleanup() {
// need to rebuild an output because of a modified header file
// mentioned in a depfile, and the command touches its depfile
// but is interrupted before it touches its output file.)
- if (!depfile.empty() ||
- (*o)->mtime() != disk_interface_->Stat((*o)->path())) {
+ string err;
+ TimeStamp new_mtime = disk_interface_->Stat((*o)->path(), &err);
+ if (new_mtime == -1) // Log and ignore Stat() errors.
+ Error("%s", err.c_str());
+ if (!depfile.empty() || (*o)->mtime() != new_mtime)
disk_interface_->RemoveFile((*o)->path());
- }
}
if (!depfile.empty())
disk_interface_->RemoveFile(depfile);
@@ -760,7 +762,9 @@ bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
for (vector<Node*>::iterator o = edge->outputs_.begin();
o != edge->outputs_.end(); ++o) {
- TimeStamp new_mtime = disk_interface_->Stat((*o)->path());
+ TimeStamp new_mtime = disk_interface_->Stat((*o)->path(), err);
+ if (new_mtime == -1)
+ return false;
if ((*o)->mtime() == new_mtime) {
// The rule command did not change the output. Propagate the clean
// state through the build graph.
@@ -776,14 +780,18 @@ bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
// (existing) non-order-only input or the depfile.
for (vector<Node*>::iterator i = edge->inputs_.begin();
i != edge->inputs_.end() - edge->order_only_deps_; ++i) {
- TimeStamp input_mtime = disk_interface_->Stat((*i)->path());
+ TimeStamp input_mtime = disk_interface_->Stat((*i)->path(), err);
+ if (input_mtime == -1)
+ return false;
if (input_mtime > restat_mtime)
restat_mtime = input_mtime;
}
string depfile = edge->GetUnescapedDepfile();
if (restat_mtime != 0 && deps_type.empty() && !depfile.empty()) {
- TimeStamp depfile_mtime = disk_interface_->Stat(depfile);
+ TimeStamp depfile_mtime = disk_interface_->Stat(depfile, err);
+ if (depfile_mtime == -1)
+ return false;
if (depfile_mtime > restat_mtime)
restat_mtime = depfile_mtime;
}
@@ -812,12 +820,9 @@ bool Builder::FinishCommand(CommandRunner::Result* result, string* err) {
if (!deps_type.empty() && !config_.dry_run) {
assert(edge->outputs_.size() == 1 && "should have been rejected by parser");
Node* out = edge->outputs_[0];
- TimeStamp deps_mtime = disk_interface_->Stat(out->path());
- if (deps_mtime == -1) {
- // TODO: Let DiskInterface::Stat() take err instead of it calling Error().
- *err = "stat failed";
+ TimeStamp deps_mtime = disk_interface_->Stat(out->path(), err);
+ if (deps_mtime == -1)
return false;
- }
if (!scan_.deps_log()->RecordDeps(out, deps_mtime, deps_nodes)) {
*err = string("Error writing to deps log: ") + strerror(errno);
return false;