diff options
| author | Colin Cross <ccross@android.com> | 2015-09-14 15:11:45 -0700 |
|---|---|---|
| committer | Colin Cross <ccross@android.com> | 2015-09-14 15:21:31 -0700 |
| commit | 0850f7d9192fa5dda7030617a9d7d28d4ea91226 (patch) | |
| tree | 83befb03e924e1f390d4c97557860bcc7c812edb /ninja.cc | |
| parent | 36b6582e5690f473f8ebbd6e255df92b955c696e (diff) | |
Write .kati_stamp file atomically
It is possible to get a mismatch between the .kati_stamp file and the
build.ninja file by exiting due to error or interrupt after the ninja
file is written but before the stamp file is written. If the change
that caused the previous stamp file verification to fail are then
reverted, for example an environment variable set back to what it was in
the stamp file, the next run of kati could see the old stamp file and
not rewrite the non-matching ninja file.
To avoid stamp and ninja file mismatches, delete the old stamp file just
before starting to write any new files. To avoid a partially written
stamp file write the stamp file to .kati_stamp.tmp, and then atomically
rename it to .kati_stamp.
Change-Id: Id5c7d7ab2b7f051a430ebbf919b8535b219ca290
Diffstat (limited to 'ninja.cc')
| -rw-r--r-- | ninja.cc | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -194,6 +194,7 @@ class NinjaGenerator { void Generate(const vector<DepNode*>& nodes, bool build_all_targets, const string& orig_args) { + unlink(GetStampFilename().c_str()); GenerateNinja(nodes, build_all_targets, orig_args); GenerateShell(); GenerateStamp(orig_args); @@ -206,6 +207,11 @@ class NinjaGenerator { ninja_suffix ? ninja_suffix : ""); } + static string GetStampTempFilename(const char* ninja_dir, + const char* ninja_suffix) { + return StringPrintf("%s.tmp", GetStampFilename(ninja_dir, ninja_suffix).c_str()); + } + private: string GenRuleName() { return StringPrintf("rule%d", rule_id_++); @@ -559,6 +565,10 @@ class NinjaGenerator { return GetStampFilename(ninja_dir_.c_str(), ninja_suffix_.c_str()); } + string GetStampTempFilename() const { + return GetStampTempFilename(ninja_dir_.c_str(), ninja_suffix_.c_str()); + } + void GenerateNinja(const vector<DepNode*>& nodes, bool build_all_targets, const string& orig_args) { @@ -639,7 +649,7 @@ class NinjaGenerator { } void GenerateStamp(const string& orig_args) { - FILE* fp = fopen(GetStampFilename().c_str(), "wb"); + FILE* fp = fopen(GetStampTempFilename().c_str(), "wb"); CHECK(fp); size_t r = fwrite(&start_time_, sizeof(start_time_), 1, fp); @@ -716,6 +726,8 @@ class NinjaGenerator { DumpString(fp, orig_args); fclose(fp); + + rename(GetStampTempFilename().c_str(), GetStampFilename().c_str()); } CommandEvaluator ce_; |
