From 6e126ac30038502acf7016f0e76b3183f1304042 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Wed, 3 Apr 2019 21:19:50 +0300 Subject: Change depdb API and handle system_error thrown by butl::file_mtime() Previously, debdb operations threw system_error and io_error to signal errors, except for opening which issued diagnostics and failed. Now all operations print the diagnostics and fail on system and IO errors. --- build2/cc/common.cxx | 6 +++--- build2/cc/compile-rule.cxx | 3 ++- build2/cc/link-rule.cxx | 4 ++-- build2/cc/msvc.cxx | 2 +- build2/cc/pkgconfig.cxx | 2 +- build2/cc/windows-rpath.cxx | 4 ++-- build2/depdb.cxx | 17 +++++++++-------- build2/depdb.hxx | 14 ++++++-------- build2/filesystem.cxx | 14 ++++++++++++++ build2/filesystem.hxx | 13 +++++++++++++ build2/rule.cxx | 2 +- build2/search.cxx | 5 ++--- build2/target.cxx | 2 -- build2/target.ixx | 4 +++- build2/test/script/builtin.cxx | 2 +- 15 files changed, 60 insertions(+), 34 deletions(-) (limited to 'build2') diff --git a/build2/cc/common.cxx b/build2/cc/common.cxx index 7844a4e..aca1240 100644 --- a/build2/cc/common.cxx +++ b/build2/cc/common.cxx @@ -639,7 +639,7 @@ namespace build2 { f = d; f /= sn; - mt = file_mtime (f); + mt = mtime (f); if (mt != timestamp_nonexistent) { @@ -694,7 +694,7 @@ namespace build2 // se = string ("dll"); f = f.base (); // Remove .a from .dll.a. - mt = file_mtime (f); + mt = mtime (f); if (mt != timestamp_nonexistent) { @@ -715,7 +715,7 @@ namespace build2 f = d; f /= an; - if ((mt = file_mtime (f)) != timestamp_nonexistent) + if ((mt = mtime (f)) != timestamp_nonexistent) { // Enter the target. Note that because the search paths are // normalized, the result is automatically normalized as well. diff --git a/build2/cc/compile-rule.cxx b/build2/cc/compile-rule.cxx index eeaec83..aa1d6fb 100644 --- a/build2/cc/compile-rule.cxx +++ b/build2/cc/compile-rule.cxx @@ -13,6 +13,7 @@ #include #include #include +#include // mtime() #include #include @@ -823,7 +824,7 @@ namespace build2 // the target (interrupted update), then do unconditional update. // timestamp mt; - bool u (dd.writing () || dd.mtime > (mt = file_mtime (tp))); + bool u (dd.writing () || dd.mtime > (mt = mtime (tp))); if (u) mt = timestamp_nonexistent; // Treat as if it doesn't exist. diff --git a/build2/cc/link-rule.cxx b/build2/cc/link-rule.cxx index 6c6aa0d..cffd731 100644 --- a/build2/cc/link-rule.cxx +++ b/build2/cc/link-rule.cxx @@ -1689,7 +1689,7 @@ namespace build2 path& mf (p.first); bool mf_cf (p.second); // Changed flag (timestamp resolution). - timestamp mf_mt (file_mtime (mf)); + timestamp mf_mt (mtime (mf)); if (tsys == "mingw32") { @@ -1699,7 +1699,7 @@ namespace build2 // manifest = mf + ".o"; - if (mf_mt > file_mtime (manifest) || mf_cf) + if (mf_mt > mtime (manifest) || mf_cf) { path of (relative (manifest)); diff --git a/build2/cc/msvc.cxx b/build2/cc/msvc.cxx index 78c29e0..32805c7 100644 --- a/build2/cc/msvc.cxx +++ b/build2/cc/msvc.cxx @@ -396,7 +396,7 @@ namespace build2 // Check if the file exists and is of the expected type. // - timestamp mt (file_mtime (f)); + timestamp mt (mtime (f)); if (mt != timestamp_nonexistent && library_type (ld, f) == lt) { diff --git a/build2/cc/pkgconfig.cxx b/build2/cc/pkgconfig.cxx index 3e477d8..eef1271 100644 --- a/build2/cc/pkgconfig.cxx +++ b/build2/cc/pkgconfig.cxx @@ -1178,7 +1178,7 @@ namespace build2 // that, if we add it as a prerequisite (like we do above), the fallback // file rule won't match. // - lt.mtime (file_mtime (ipc.path)); + lt.mtime (mtime (ipc.path)); } #else diff --git a/build2/cc/windows-rpath.cxx b/build2/cc/windows-rpath.cxx index 8161cc4..46fe75b 100644 --- a/build2/cc/windows-rpath.cxx +++ b/build2/cc/windows-rpath.cxx @@ -102,7 +102,7 @@ namespace build2 // timestamp t (l != nullptr ? l->load_mtime () - : file_mtime (f.c_str ())); + : mtime (f.c_str ())); if (t > r) r = t; @@ -260,7 +260,7 @@ namespace build2 // through the "from scratch" update. Actually this can happen when // switching to update-for-install. // - if (ts != timestamp_nonexistent && ts <= file_mtime (am)) + if (ts != timestamp_nonexistent && ts <= mtime (am)) return; } diff --git a/build2/depdb.cxx b/build2/depdb.cxx index da56c8b..605ceb4 100644 --- a/build2/depdb.cxx +++ b/build2/depdb.cxx @@ -4,12 +4,11 @@ #include -#include // file_mtime() - #ifdef _WIN32 # include #endif +#include // mtime() #include using namespace std; @@ -91,7 +90,7 @@ namespace build2 depdb:: depdb (path_type p) - : depdb (move (p), file_mtime (p)) + : depdb (move (p), build2::mtime (p)) { } @@ -347,7 +346,7 @@ namespace build2 // mtime. This seems to force that layer to commit to a timestamp. // #if defined(__FreeBSD__) - mtime = file_mtime (path); // Save for debugging/check below. + mtime = build2::mtime (path); // Save for debugging/check below. #endif } @@ -357,8 +356,8 @@ namespace build2 // We could call the static version but then we would have lost additional // information for some platforms. // - timestamp t_mt (file_mtime (t)); - timestamp d_mt (file_mtime (path)); + timestamp t_mt (build2::mtime (t)); + timestamp d_mt (build2::mtime (path)); if (d_mt > t_mt) { @@ -382,8 +381,10 @@ namespace build2 const path_type& t, timestamp e) { - timestamp t_mt (file_mtime (t)); - timestamp d_mt (file_mtime (d)); + using build2::mtime; + + timestamp t_mt (mtime (t)); + timestamp d_mt (mtime (d)); if (d_mt > t_mt) { diff --git a/build2/depdb.hxx b/build2/depdb.hxx index f1e86a1..64ea627 100644 --- a/build2/depdb.hxx +++ b/build2/depdb.hxx @@ -12,9 +12,8 @@ namespace build2 { - // Auxiliary dependency database (those .d files). Uses io_error and - // system_error exceptions to signal errors except for openning (see - // below). + // Auxiliary dependency database (those .d files). Prints the diagnostics + // and fails on system and IO errors. // // This is a strange beast: a line-oriented, streaming database that can, at // some point, be switched from reading to (over)writing. The idea is to @@ -95,11 +94,10 @@ namespace build2 // has wrong format version, or is corrupt, then the database will be // immediately switched to writing. // - // If the database cannot be opened, issue diagnostics and throw failed. - // This commonly happens when the user tries to stash the target in a - // non-existent subdirectory but forgets to add the corresponding fsdir{} - // prerequisite. Handling this as io_error in every rule that uses depdb - // would be burdensome thus we issue the diagnostics here. + // The failure commonly happens when the user tries to stash the target in + // a non-existent subdirectory but forgets to add the corresponding fsdir{} + // prerequisite. That's why the issued diagnostics may provide the + // corresponding hint. // explicit depdb (path_type); diff --git a/build2/filesystem.cxx b/build2/filesystem.cxx index 97f540b..5e6df5f 100644 --- a/build2/filesystem.cxx +++ b/build2/filesystem.cxx @@ -27,6 +27,20 @@ namespace build2 } } + timestamp + mtime (const char* p) + { + try + { + return file_mtime (p); + } + catch (const system_error& e) + { + fail << "unable to obtain file " << p << " modification time: " << e + << endf; + } + } + fs_status mkdir (const dir_path& d, uint16_t v) { diff --git a/build2/filesystem.hxx b/build2/filesystem.hxx index ccc5a73..ed99685 100644 --- a/build2/filesystem.hxx +++ b/build2/filesystem.hxx @@ -38,6 +38,19 @@ namespace build2 bool touch (const path&, bool create, uint16_t verbosity = 1); + // Return the modification time for an existing regular file and + // timestamp_nonexistent otherwise. Print the diagnostics and fail on system + // error. + // + timestamp + mtime (const char*); + + inline timestamp + mtime (const path& p) + { + return mtime (p.string ().c_str ()); + } + // Create the directory and print the standard diagnostics starting from // the specified verbosity level. // diff --git a/build2/rule.cxx b/build2/rule.cxx index b702bab..2a10a90 100644 --- a/build2/rule.cxx +++ b/build2/rule.cxx @@ -83,7 +83,7 @@ namespace build2 p = &pt->derive_path (); } - ts = file_mtime (*p); + ts = mtime (*p); pt->mtime (ts); if (ts != timestamp_unknown && ts != timestamp_nonexistent) diff --git a/build2/search.cxx b/build2/search.cxx index c4b9ae3..7683ef6 100644 --- a/build2/search.cxx +++ b/build2/search.cxx @@ -4,11 +4,10 @@ #include -#include // file_mtime() - #include #include #include +#include // mtime() #include #include @@ -148,7 +147,7 @@ namespace build2 f += *ext; } - timestamp mt (file_mtime (f)); + timestamp mt (mtime (f)); if (mt == timestamp_nonexistent) { diff --git a/build2/target.cxx b/build2/target.cxx index b8e2a60..667933a 100644 --- a/build2/target.cxx +++ b/build2/target.cxx @@ -4,8 +4,6 @@ #include -#include // file_mtime() - #include #include #include diff --git a/build2/target.ixx b/build2/target.ixx index c3e2f63..dcbea32 100644 --- a/build2/target.ixx +++ b/build2/target.ixx @@ -4,6 +4,8 @@ #include // memcpy() +#include // mtime() + namespace build2 { // target @@ -314,7 +316,7 @@ namespace build2 { assert (!p.empty ()); - r = file_mtime (p).time_since_epoch ().count (); + r = build2::mtime (p).time_since_epoch ().count (); mtime_.store (r, memory_order_release); } diff --git a/build2/test/script/builtin.cxx b/build2/test/script/builtin.cxx index 657d8d4..e4eb895 100644 --- a/build2/test/script/builtin.cxx +++ b/build2/test/script/builtin.cxx @@ -996,7 +996,7 @@ namespace build2 check_wd (from); check_wd (to); - bool exists (entry_exists (to)); + bool exists (butl::entry_exists (to)); // Fail if the source and destination paths are the same. // -- cgit v1.1