Extend `last_write_time` implementation by special-casing file touching (#2141)

* feat(fs): Replace 'last_write_time' by underlying 'utimesat' to support ACL's
* Add error handling and fix linting errors
* Detect utimensat availability by UTIME_OMIT constant

Co-authored-by: Bourdon Olivier <mail@olivier-bourdon.fr>
This commit is contained in:
Jonas Hörsch 2023-01-03 13:18:22 +01:00 committed by GitHub
parent 70253a5767
commit c4d453bdc2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 4 deletions

View File

@ -54,7 +54,7 @@ namespace mamba
path = env::expand_user(path);
if (lexists(path))
{
fs::last_write_time(path, fs::file_time_type::clock::now());
fs::last_write_time(path, fs::now());
return true;
}
else

View File

@ -7,6 +7,18 @@
#include "mamba/core/util_string.hpp"
#if !defined(_WIN32)
#include <sys/stat.h>
#include <fcntl.h>
// We can use the presence of UTIME_OMIT to detect platforms that provide
// utimensat.
#if defined(UTIME_OMIT)
#define USE_UTIMENSAT
#endif
#endif
//---- RATIONAL: Why do we wrap standard filesystem here? ----
// 1. This codebase relies on `std::string` and `const char*` to denote UTF-8 encoded text.
// However `std::filesystem::path` constructors cannot assume that `std::string` is in
@ -63,6 +75,10 @@
namespace fs
{
// sentinel argument for indicating the current time to last_write_time
class now
{
};
#if defined(_WIN32)
@ -1148,6 +1164,31 @@ namespace fs
return std::filesystem::last_write_time(path, std::forward<OtherArgs>(args)...);
}
// void last_write_time(const path& p, now _, error_code& ec) noexcept;
inline void last_write_time(const u8path& path, now _, std::error_code& ec) noexcept
{
#if defined(USE_UTIMENSAT)
if (utimensat(AT_FDCWD, path.string().c_str(), NULL, 0) == -1)
{
ec = std::error_code(errno, std::generic_category());
}
#else
auto new_time = fs::file_time_type::clock::now();
std::filesystem::last_write_time(path, new_time, ec);
#endif
}
// void last_write_time(const path& p, now _);
inline void last_write_time(const u8path& path, now sentinel)
{
std::error_code ec;
last_write_time(path, sentinel, ec);
if (ec)
{
throw filesystem_error("last_write_time", path, ec);
}
}
// void last_write_time(const path& p, file_time_type new_time);
// void last_write_time(const path& p, file_time_type new_time, error_code& ec) noexcept;
template <typename... OtherArgs>

View File

@ -503,13 +503,13 @@ namespace mamba
{
LOG_TRACE << "Refreshing '" << json_file.string() << "'";
auto lock = LockFile(json_file);
fs::last_write_time(json_file, now);
fs::last_write_time(json_file, fs::now());
}
if (fs::exists(solv_file) && solv_age.count() <= json_age.count())
{
LOG_TRACE << "Refreshing '" << solv_file.string() << "'";
auto lock = LockFile(solv_file);
fs::last_write_time(solv_file, now);
fs::last_write_time(solv_file, fs::now());
m_solv_cache_valid = true;
}
@ -606,7 +606,7 @@ namespace mamba
m_temp_file.reset(nullptr);
final_file.close();
fs::last_write_time(json_file, fs::file_time_type::clock::now());
fs::last_write_time(json_file, fs::now());
return true;
}