summaryrefslogtreecommitdiff
path: root/src/build_log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/build_log.cc')
-rw-r--r--src/build_log.cc70
1 files changed, 64 insertions, 6 deletions
diff --git a/src/build_log.cc b/src/build_log.cc
index c4a08a0..98543b6 100644
--- a/src/build_log.cc
+++ b/src/build_log.cc
@@ -21,6 +21,7 @@
#endif
#include "build_log.h"
+#include "disk_interface.h"
#include <errno.h>
#include <stdlib.h>
@@ -241,14 +242,14 @@ struct LineReader {
char* line_end_;
};
-bool BuildLog::Load(const string& path, string* err) {
+LoadStatus BuildLog::Load(const string& path, string* err) {
METRIC_RECORD(".ninja_log load");
FILE* file = fopen(path.c_str(), "r");
if (!file) {
if (errno == ENOENT)
- return true;
+ return LOAD_NOT_FOUND;
*err = strerror(errno);
- return false;
+ return LOAD_ERROR;
}
int log_version = 0;
@@ -269,7 +270,7 @@ bool BuildLog::Load(const string& path, string* err) {
unlink(path.c_str());
// Don't report this as a failure. An empty build log will cause
// us to rebuild the outputs anyway.
- return true;
+ return LOAD_SUCCESS;
}
}
@@ -339,7 +340,7 @@ bool BuildLog::Load(const string& path, string* err) {
fclose(file);
if (!line_start) {
- return true; // file was empty
+ return LOAD_SUCCESS; // file was empty
}
// Decide whether it's time to rebuild the log:
@@ -354,7 +355,7 @@ bool BuildLog::Load(const string& path, string* err) {
needs_recompaction_ = true;
}
- return true;
+ return LOAD_SUCCESS;
}
BuildLog::LogEntry* BuildLog::LookupByOutput(const string& path) {
@@ -418,3 +419,60 @@ bool BuildLog::Recompact(const string& path, const BuildLogUser& user,
return true;
}
+
+bool BuildLog::Restat(const StringPiece path,
+ const DiskInterface& disk_interface,
+ const int output_count, char** outputs,
+ std::string* const err) {
+ METRIC_RECORD(".ninja_log restat");
+
+ Close();
+ std::string temp_path = path.AsString() + ".restat";
+ FILE* f = fopen(temp_path.c_str(), "wb");
+ if (!f) {
+ *err = strerror(errno);
+ return false;
+ }
+
+ if (fprintf(f, kFileSignature, kCurrentVersion) < 0) {
+ *err = strerror(errno);
+ fclose(f);
+ return false;
+ }
+ for (Entries::iterator i = entries_.begin(); i != entries_.end(); ++i) {
+ bool skip = output_count > 0;
+ for (int j = 0; j < output_count; ++j) {
+ if (i->second->output == outputs[j]) {
+ skip = false;
+ break;
+ }
+ }
+ if (!skip) {
+ const TimeStamp mtime = disk_interface.Stat(i->second->output, err);
+ if (mtime == -1) {
+ fclose(f);
+ return false;
+ }
+ i->second->mtime = mtime;
+ }
+
+ if (!WriteEntry(f, *i->second)) {
+ *err = strerror(errno);
+ fclose(f);
+ return false;
+ }
+ }
+
+ fclose(f);
+ if (unlink(path.str_) < 0) {
+ *err = strerror(errno);
+ return false;
+ }
+
+ if (rename(temp_path.c_str(), path.str_) < 0) {
+ *err = strerror(errno);
+ return false;
+ }
+
+ return true;
+}