From a50652b3e3323a9492c32d2ca6e97befd7d9755b Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 28 Nov 2021 09:40:25 +0200 Subject: Generalize depdb::touch functionality to support custom timestamp --- libbuild2/adhoc-rule-buildscript.cxx | 2 +- libbuild2/cc/compile-rule.cxx | 2 +- libbuild2/depdb.cxx | 27 ++++++++++++++++++++++----- libbuild2/depdb.hxx | 13 ++++++++++--- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/libbuild2/adhoc-rule-buildscript.cxx b/libbuild2/adhoc-rule-buildscript.cxx index 78f87ae..e8bc20d 100644 --- a/libbuild2/adhoc-rule-buildscript.cxx +++ b/libbuild2/adhoc-rule-buildscript.cxx @@ -503,7 +503,7 @@ namespace build2 } if (update && dd.reading () && !ctx.dry_run) - dd.touch = true; + dd.touch = timestamp_unknown; dd.close (); md->dd = move (dd.path); diff --git a/libbuild2/cc/compile-rule.cxx b/libbuild2/cc/compile-rule.cxx index 525821f..3c77ad3 100644 --- a/libbuild2/cc/compile-rule.cxx +++ b/libbuild2/cc/compile-rule.cxx @@ -1422,7 +1422,7 @@ namespace build2 // on the real run). // if (u && dd.reading () && !ctx.dry_run) - dd.touch = true; + dd.touch = timestamp_unknown; dd.close (); md.dd = move (dd.path); diff --git a/libbuild2/depdb.cxx b/libbuild2/depdb.cxx index 657c772..1215e78 100644 --- a/libbuild2/depdb.cxx +++ b/libbuild2/depdb.cxx @@ -72,8 +72,7 @@ namespace build2 depdb (path_type&& p, timestamp mt) : depdb_base (p, mt), path (move (p)), - mtime (mt != timestamp_nonexistent ? mt : timestamp_unknown), - touch (false) + mtime (mt != timestamp_nonexistent ? mt : timestamp_unknown) { // Read/write the database format version. // @@ -290,6 +289,10 @@ namespace build2 // the rest, and then add the "end marker" (we cannot have anything in the // write mode since we truncate in change()). // + // Note that we handle touch with timestamp_unknown specially by making a + // modification to the file (which happens naturally in the write mode) + // and letting the filesystem update its mtime. + // if (state_ == state::read_eof) { if (!touch) @@ -314,8 +317,11 @@ namespace build2 // Note also that utime() on Windows is a bad idea (see touch_file() for // details). // - pos_ = buf_->tellg (); // The last line is accepted. - change (false /* truncate */); // Write end marker below. + if (*touch == timestamp_unknown) + { + pos_ = buf_->tellg (); // The last line is accepted. + change (false /* truncate */); // Write end marker below. + } } else if (state_ != state::write) { @@ -326,6 +332,7 @@ namespace build2 if (mtime_check ()) start_ = system_clock::now (); + if (state_ == state::write) try { os_.put ('\0'); // The "end marker". @@ -333,7 +340,17 @@ namespace build2 } catch (const io_error& e) { - fail << "unable to flush " << path << ": " << e; + fail << "unable to flush file " << path << ": " << e; + } + + if (touch && *touch != timestamp_unknown) + try + { + file_mtime (path, *touch); + } + catch (const system_error& e) + { + fail << "unable to touch file " << path << ": " << e; } // On some platforms (currently confirmed on FreeBSD running as VMs) one diff --git a/libbuild2/depdb.hxx b/libbuild2/depdb.hxx index c3e60a2..9cff281 100644 --- a/libbuild2/depdb.hxx +++ b/libbuild2/depdb.hxx @@ -90,9 +90,16 @@ namespace build2 // close() even if otherwise no modifications are necessary (i.e., the // database is in the read mode and is at eof). // - path_type path; - timestamp mtime; - bool touch; + // If touch is present then update the database modification time in + // close() even if otherwise no modifications are necessary (i.e., the + // database is in the read mode and is at eof). Specifically, if touch is + // timestamp_unknown, then set mtime to the current (filesystem) time. + // Otherwise, set it to the specified time (which should be sourced from + // the filesystem, see touch_file() for details). + // + path_type path; + timestamp mtime; + optional touch; // Open the database for reading. Note that if the file does not exist, // has wrong format version, or is corrupt, then the database will be -- cgit v1.1