]> git.ipfire.org Git - thirdparty/ccache.git/commitdiff
Add Util::localtime, abstracting localtime_r
authorJoel Rosdahl <joel@rosdahl.net>
Thu, 30 Jul 2020 11:03:24 +0000 (13:03 +0200)
committerJoel Rosdahl <joel@rosdahl.net>
Thu, 30 Jul 2020 19:04:01 +0000 (21:04 +0200)
cmake/GenerateConfigurationFile.cmake
cmake/config.h.in
src/Util.cpp
src/Util.hpp
src/ccache.cpp
src/hashutil.cpp
src/legacy_util.cpp
src/legacy_util.hpp
src/logging.cpp
src/stats.cpp

index 0ef550728797990918abda849424549b7534970c..d169648760088a99936f99e9ef5493cf8780fa52 100644 (file)
@@ -23,7 +23,6 @@ set(functions
     getopt_long
     getpwuid
     gettimeofday
-    localtime_r
     mkstemp
     posix_fallocate
     realpath
index 4eeecdd8be716850920a984db3d064c3ad2b6be4..34935e05fcce48aff96d74ea83e9d89e60826dd6 100644 (file)
@@ -75,9 +75,6 @@
 /* Define to 1 if you have the <linux/fs.h> header file. */
 #cmakedefine HAVE_LINUX_FS_H
 
-/* Define to 1 if you have the `localtime_r' function. */
-#cmakedefine HAVE_LOCALTIME_R
-
 /* Define to 1 if the system has the type `long long'. */
 #cmakedefine HAVE_LONG_LONG
 
index 452104bb56951a9db36a9748b376f6fa9044450a..8678b1c62b5c2b982397bb9e1b42a19cb11f4bf5 100644 (file)
@@ -57,6 +57,8 @@
 #  endif
 #endif
 
+using nonstd::nullopt;
+using nonstd::optional;
 using nonstd::string_view;
 
 namespace {
@@ -720,6 +722,18 @@ is_precompiled_header(string_view path)
          || get_extension(dir_name(path)) == ".gch";
 }
 
+optional<tm>
+localtime(optional<time_t> time)
+{
+  time_t timestamp = time ? *time : ::time(nullptr);
+  tm result;
+  if (localtime_r(&timestamp, &result)) {
+    return result;
+  } else {
+    return nullopt;
+  }
+}
+
 std::string
 make_relative_path(const Context& ctx, string_view path)
 {
index c3485c5c8463fc74705aae3872f8ce4fe9ccca4b..0141f3faef555163f39d6175944bc6ae0ec1059f 100644 (file)
@@ -23,6 +23,7 @@
 #include "CacheFile.hpp"
 #include "Config.hpp"
 
+#include "third_party/nonstd/optional.hpp"
 #include "third_party/nonstd/string_view.hpp"
 
 #include <functional>
@@ -269,6 +270,10 @@ is_dir_separator(char ch)
 // Headers" in GCC docs).
 bool is_precompiled_header(nonstd::string_view path);
 
+// Thread-safe version of `localtime(3)`. If `time` is not specified the current
+// time of day is used.
+nonstd::optional<tm> localtime(nonstd::optional<time_t> time = {});
+
 // Make a relative path from current working directory to `path` if `path` is
 // under the base directory.
 std::string make_relative_path(const Context& ctx, nonstd::string_view path);
index e1e49cdc8efda9921db252442fc0afd6447f0d4d..2ecc1f10a4e313ffc838d59b5497cecc7c96c5df 100644 (file)
@@ -1898,8 +1898,7 @@ static enum stats do_cache_compilation(Context& ctx, const char* const* argv);
 static int
 cache_compilation(int argc, const char* const* argv)
 {
-  // Needed for portability when using localtime_r.
-  tzset();
+  tzset(); // Needed for localtime_r.
 
   auto ctx = std::make_unique<Context>();
   SignalHandler signal_handler(*ctx);
index 12f5761c87edf63e2ab0d13ded76c82b929af866..f76ba7b8b16b5750bedff682fda11ce865def818 100644 (file)
@@ -250,15 +250,14 @@ hash_source_code_string(const Context& ctx,
 
     // Make sure that the hash sum changes if the (potential) expansion of
     // __DATE__ changes.
-    time_t t = time(nullptr);
-    struct tm now;
     hash.hash_delimiter("date");
-    if (!localtime_r(&t, &now)) {
+    auto now = Util::localtime();
+    if (!now) {
       return HASH_SOURCE_CODE_ERROR;
     }
-    hash.hash(now.tm_year);
-    hash.hash(now.tm_mon);
-    hash.hash(now.tm_mday);
+    hash.hash(now->tm_year);
+    hash.hash(now->tm_mon);
+    hash.hash(now->tm_mday);
   }
   if (result & HASH_SOURCE_CODE_FOUND_TIME) {
     // We don't know for sure that the program actually uses the __TIME__ macro,
@@ -278,18 +277,16 @@ hash_source_code_string(const Context& ctx,
       return HASH_SOURCE_CODE_ERROR;
     }
 
-    time_t t = stat.mtime();
-    tm modified;
-    hash.hash_delimiter("timestamp");
-    if (!localtime_r(&t, &modified)) {
+    auto modified_time = Util::localtime(stat.mtime());
+    if (!modified_time) {
       return HASH_SOURCE_CODE_ERROR;
     }
-
+    hash.hash_delimiter("timestamp");
 #ifdef HAVE_ASCTIME_R
     char buffer[26];
-    auto timestamp = asctime_r(&modified, buffer);
+    auto timestamp = asctime_r(&*modified_time, buffer);
 #else
-    auto timestamp = asctime(&modified);
+    auto timestamp = asctime(&*modified_time);
 #endif
     if (!timestamp) {
       return HASH_SOURCE_CODE_ERROR;
index e77ee159eb641b26c8bef528796804edc53ffd88..ac5e0339c3bd7bea33d4b0f63e3792821507356b 100644 (file)
 #  include <sys/time.h>
 #endif
 
-#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R)
-// localtime_r replacement. (Mingw-w64 has an inline localtime_r which is not
-// detected by AC_CHECK_FUNCS.)
-struct tm*
-localtime_r(const time_t* timep, struct tm* result)
-{
-  struct tm* tm = localtime(timep);
-  if (tm) {
-    *result = *tm;
-    return result;
-  } else {
-    memset(result, 0, sizeof(*result));
-    return NULL;
-  }
-}
-#endif
-
 // Return current user's home directory, or throw FatalError if it can't be
 // determined.
 const char*
index 89e0973af35ed769e12366a561e3acb418798da7..1c37959c59d2171bfa7e7bfe99e04e3dcf88f914 100644 (file)
@@ -22,9 +22,6 @@
 
 #include <string>
 
-#ifndef HAVE_LOCALTIME_R
-struct tm* localtime_r(const time_t* timep, struct tm* result);
-#endif
 const char* get_home_directory();
 bool is_full_path(const char* path);
 void update_mtime(const char* path);
index dc277ba07cb5538673f00f79d213b0cdbb350adb..d2b62b5210c7b31b66aa80dc00310d61ff5d849c 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "Config.hpp"
 #include "File.hpp"
+#include "Util.hpp"
 #include "exceptions.hpp"
 #include "execute.hpp"
 
@@ -100,11 +101,11 @@ log_prefix(bool log_updated_time)
 #ifdef HAVE_GETTIMEOFDAY
   if (log_updated_time) {
     char timestamp[100];
-    struct tm tm;
     struct timeval tv;
     gettimeofday(&tv, nullptr);
-    if (localtime_r((time_t*)&tv.tv_sec, &tm) != nullptr) {
-      strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &tm);
+    auto tm = Util::localtime(tv.tv_sec);
+    if (tm) {
+      strftime(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", &*tm);
     } else {
       snprintf(timestamp, sizeof(timestamp), "%lu", tv.tv_sec);
     }
index dabc39ac2e83f3a7ba97e0009bca120285d37784..c57aaa2f5d0551512f14ce96f889a66900601337 100644 (file)
@@ -192,10 +192,11 @@ static std::string
 format_timestamp(uint64_t timestamp)
 {
   if (timestamp > 0) {
-    struct tm tm;
-    localtime_r(reinterpret_cast<time_t*>(&timestamp), &tm);
-    char buffer[100];
-    strftime(buffer, sizeof(buffer), "%c", &tm);
+    auto tm = Util::localtime(timestamp);
+    char buffer[100] = "?";
+    if (tm) {
+      strftime(buffer, sizeof(buffer), "%c", &*tm);
+    }
     return std::string("    ") + buffer;
   } else {
     return {};
@@ -405,10 +406,11 @@ stats_summary(const Context& ctx)
   fmt::print("secondary config (readonly)         {}\n",
              ctx.config.secondary_config_path());
   if (last_updated > 0) {
-    struct tm tm;
-    localtime_r(&last_updated, &tm);
-    char timestamp[100];
-    strftime(timestamp, sizeof(timestamp), "%c", &tm);
+    auto tm = Util::localtime(last_updated);
+    char timestamp[100] = "?";
+    if (tm) {
+      strftime(timestamp, sizeof(timestamp), "%c", &*tm);
+    }
     fmt::print("stats updated                       {}\n", timestamp);
   }