From 176bdc0016b9f0bdbf23b111f135e3ff1931fdf7 Mon Sep 17 00:00:00 2001 From: Joel Rosdahl Date: Wed, 8 Jun 2022 14:04:55 +0200 Subject: [PATCH] enhance: Add util::set_timestamps function for setting mtime/atime --- cmake/GenerateConfigurationFile.cmake | 3 ++- cmake/config.h.in | 4 +-- src/ResultRetriever.cpp | 3 ++- src/Util.cpp | 16 ----------- src/Util.hpp | 3 --- src/storage/primary/PrimaryStorage.cpp | 4 +-- src/storage/secondary/FileStorage.cpp | 2 +- src/util/file.cpp | 37 +++++++++++++++++++++++++- src/util/file.hpp | 9 ++++++- 9 files changed, 53 insertions(+), 28 deletions(-) diff --git a/cmake/GenerateConfigurationFile.cmake b/cmake/GenerateConfigurationFile.cmake index df909337f..f80258b0f 100644 --- a/cmake/GenerateConfigurationFile.cmake +++ b/cmake/GenerateConfigurationFile.cmake @@ -36,7 +36,8 @@ set(functions strndup syslog unsetenv - utimes) + utimensat +) foreach(func IN ITEMS ${functions}) string(TOUPPER ${func} func_var) set(func_var HAVE_${func_var}) diff --git a/cmake/config.h.in b/cmake/config.h.in index 729a1d4af..bbc1397f5 100644 --- a/cmake/config.h.in +++ b/cmake/config.h.in @@ -172,8 +172,8 @@ // Define if you have the "unsetenv" function. #cmakedefine HAVE_UNSETENV -// Define if you have the "utimes" function. -#cmakedefine HAVE_UTIMES +// Define if you have the "utimensat" function. +#cmakedefine HAVE_UTIMENSAT // Define if you have the "PTHREAD_MUTEX_ROBUST" constant. #cmakedefine HAVE_PTHREAD_MUTEX_ROBUST diff --git a/src/ResultRetriever.cpp b/src/ResultRetriever.cpp index c1c584ebc..6f079e1a9 100644 --- a/src/ResultRetriever.cpp +++ b/src/ResultRetriever.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -121,7 +122,7 @@ ResultRetriever::on_entry_start(uint8_t entry_number, // Update modification timestamp to save the file from LRU cleanup (and, if // hard-linked, to make the object file newer than the source file). - Util::update_mtime(*raw_file); + util::set_timestamps(*raw_file); } else { LOG("Writing to {}", dest_path); m_dest_fd = Fd( diff --git a/src/Util.cpp b/src/Util.cpp index 501e2c3d2..7770fabd4 100644 --- a/src/Util.cpp +++ b/src/Util.cpp @@ -64,12 +64,6 @@ extern "C" { # include #endif -#ifdef HAVE_UTIME_H -# include -#elif defined(HAVE_SYS_UTIME_H) -# include -#endif - #ifdef HAVE_LINUX_FS_H # include # include @@ -1500,16 +1494,6 @@ unsetenv(const std::string& name) #endif } -void -update_mtime(const std::string& path) -{ -#ifdef HAVE_UTIMES - utimes(path.c_str(), nullptr); -#else - utime(path.c_str(), nullptr); -#endif -} - void wipe_path(const std::string& path) { diff --git a/src/Util.hpp b/src/Util.hpp index 6e299f583..0cf845677 100644 --- a/src/Util.hpp +++ b/src/Util.hpp @@ -401,9 +401,6 @@ bool unlink_tmp(const std::string& path, // Unset environment variable `name`. void unsetenv(const std::string& name); -// Set mtime of `path` to the current timestamp. -void update_mtime(const std::string& path); - // Remove `path` (and its contents if it's a directory). A nonexistent path is // not considered an error. // diff --git a/src/storage/primary/PrimaryStorage.cpp b/src/storage/primary/PrimaryStorage.cpp index c89ebb723..b3e709bb1 100644 --- a/src/storage/primary/PrimaryStorage.cpp +++ b/src/storage/primary/PrimaryStorage.cpp @@ -196,7 +196,7 @@ PrimaryStorage::get(const Digest& key, const core::CacheEntryType type) const "Retrieved {} from primary storage ({})", key.to_string(), cache_file.path); // Update modification timestamp to save file from LRU cleanup. - Util::update_mtime(cache_file.path); + util::set_timestamps(cache_file.path); return cache_file.path; } @@ -310,7 +310,7 @@ PrimaryStorage::clean_internal_tempdir() return; } - Util::update_mtime(m_config.cache_dir()); + util::set_timestamps(m_config.cache_dir()); const std::string& temp_dir = m_config.temporary_dir(); if (!Stat::lstat(temp_dir)) { diff --git a/src/storage/secondary/FileStorage.cpp b/src/storage/secondary/FileStorage.cpp index 6b3f55ee6..f1d550c34 100644 --- a/src/storage/secondary/FileStorage.cpp +++ b/src/storage/secondary/FileStorage.cpp @@ -108,7 +108,7 @@ FileStorageBackend::get(const Digest& key) if (m_update_mtime) { // Update modification timestamp for potential LRU cleanup by some external // mechanism. - Util::update_mtime(path); + util::set_timestamps(path); } try { diff --git a/src/util/file.cpp b/src/util/file.cpp index 85c62c16a..5616afb7a 100644 --- a/src/util/file.cpp +++ b/src/util/file.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -23,6 +23,18 @@ #include #include +#ifdef HAVE_UTIMENSAT +# include +# include +#else +# include +# ifdef HAVE_UTIME_H +# include +# elif defined(HAVE_SYS_UTIME_H) +# include +# endif +#endif + namespace util { void @@ -46,4 +58,27 @@ create_cachedir_tag(const std::string& dir) } } +void +set_timestamps(const std::string& path, + std::optional mtime, + std::optional atime) +{ +#ifdef HAVE_UTIMENSAT + timespec atime_mtime[2]; + if (mtime) { + atime_mtime[0] = atime ? *atime : *mtime; + atime_mtime[1] = *mtime; + } + const timespec* const timespecs = mtime ? atime_mtime : nullptr; + utimensat(AT_FDCWD, path.c_str(), timespecs, 0); +#else + utimbuf atime_mtime; + if (mtime) { + atime_mtime.actime = atime ? atime->tv_sec : mtime->tv_sec; + atime_mtime.modtime = mtime->tv_sec; + } + utime(path.c_str(), &atime_mtime); +#endif +} + } // namespace util diff --git a/src/util/file.hpp b/src/util/file.hpp index e0af9dd58..d9adfbbda 100644 --- a/src/util/file.hpp +++ b/src/util/file.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 Joel Rosdahl and other contributors +// Copyright (C) 2021-2022 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,6 +18,7 @@ #pragma once +#include #include namespace util { @@ -26,4 +27,10 @@ namespace util { void create_cachedir_tag(const std::string& dir); +// Set atime/mtime of `path`. If `mtime` is std::nullopt, set to the current +// time. If `atime` is std::nullopt, set to what `mtime` specifies. +void set_timestamps(const std::string& path, + std::optional mtime = std::nullopt, + std::optional atime = std::nullopt); + } // namespace util -- 2.47.2