diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-03-31 15:12:12 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-03-31 19:21:57 (GMT) |
commit | 3beebde51a2089ecb01820f1428efe0263deaeea (patch) | |
tree | 55aec535c37434dbe5893e8ed37c69891b6d4b74 /src/build.cc | |
parent | a88b75d9a9df1b3722ad649ae275d342f3b57b22 (diff) | |
download | Ninja-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.cc | 27 |
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; |