mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-15 02:36:16 +02:00
Merge pull request #11751 from artemist/nix-utimensat
Add support for `utimensat` as an alternative to `lutimes`
This commit is contained in:
commit
63f9159953
3 changed files with 43 additions and 38 deletions
|
@ -89,9 +89,10 @@ AC_LANG_POP(C++)
|
||||||
AC_CHECK_FUNCS([statvfs pipe2 close_range])
|
AC_CHECK_FUNCS([statvfs pipe2 close_range])
|
||||||
|
|
||||||
|
|
||||||
# Check for lutimes, optionally used for changing the mtime of
|
# Check for lutimes and utimensat, optionally used for changing the
|
||||||
# symlinks.
|
# mtime of symlinks.
|
||||||
AC_CHECK_FUNCS([lutimes])
|
AC_CHECK_DECLS([AT_SYMLINK_NOFOLLOW], [], [], [[#include <fcntl.h>]])
|
||||||
|
AC_CHECK_FUNCS([lutimes utimensat])
|
||||||
|
|
||||||
|
|
||||||
# Check whether the store optimiser can optimise symlinks.
|
# Check whether the store optimiser can optimise symlinks.
|
||||||
|
|
|
@ -630,7 +630,28 @@ void setWriteTime(
|
||||||
time_t modificationTime,
|
time_t modificationTime,
|
||||||
std::optional<bool> optIsSymlink)
|
std::optional<bool> optIsSymlink)
|
||||||
{
|
{
|
||||||
#ifndef _WIN32
|
#ifdef _WIN32
|
||||||
|
// FIXME use `fs::last_write_time`.
|
||||||
|
//
|
||||||
|
// Would be nice to use std::filesystem unconditionally, but
|
||||||
|
// doesn't support access time just modification time.
|
||||||
|
//
|
||||||
|
// System clock vs File clock issues also make that annoying.
|
||||||
|
warn("Changing file times is not yet implemented on Windows, path is '%s'", path);
|
||||||
|
#elif HAVE_UTIMENSAT && HAVE_DECL_AT_SYMLINK_NOFOLLOW
|
||||||
|
struct timespec times[2] = {
|
||||||
|
{
|
||||||
|
.tv_sec = accessedTime,
|
||||||
|
.tv_nsec = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.tv_sec = modificationTime,
|
||||||
|
.tv_nsec = 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (utimensat(AT_FDCWD, path.c_str(), times, AT_SYMLINK_NOFOLLOW) == -1)
|
||||||
|
throw SysError("changing modification time of '%s' (using `utimensat`)", path);
|
||||||
|
#else
|
||||||
struct timeval times[2] = {
|
struct timeval times[2] = {
|
||||||
{
|
{
|
||||||
.tv_sec = accessedTime,
|
.tv_sec = accessedTime,
|
||||||
|
@ -641,42 +662,21 @@ void setWriteTime(
|
||||||
.tv_usec = 0,
|
.tv_usec = 0,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
auto nonSymlink = [&]{
|
|
||||||
bool isSymlink = optIsSymlink
|
|
||||||
? *optIsSymlink
|
|
||||||
: fs::is_symlink(path);
|
|
||||||
|
|
||||||
if (!isSymlink) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
// FIXME use `fs::last_write_time`.
|
|
||||||
//
|
|
||||||
// Would be nice to use std::filesystem unconditionally, but
|
|
||||||
// doesn't support access time just modification time.
|
|
||||||
//
|
|
||||||
// System clock vs File clock issues also make that annoying.
|
|
||||||
warn("Changing file times is not yet implemented on Windows, path is '%s'", path);
|
|
||||||
#else
|
|
||||||
if (utimes(path.c_str(), times) == -1) {
|
|
||||||
|
|
||||||
throw SysError("changing modification time of '%s' (not a symlink)", path);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
throw Error("Cannot modification time of symlink '%s'", path);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#if HAVE_LUTIMES
|
#if HAVE_LUTIMES
|
||||||
if (lutimes(path.c_str(), times) == -1) {
|
if (lutimes(path.c_str(), times) == -1)
|
||||||
if (errno == ENOSYS)
|
throw SysError("changing modification time of '%s'", path);
|
||||||
nonSymlink();
|
|
||||||
else
|
|
||||||
throw SysError("changing modification time of '%s'", path);
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
nonSymlink();
|
bool isSymlink = optIsSymlink
|
||||||
|
? *optIsSymlink
|
||||||
|
: fs::is_symlink(path);
|
||||||
|
|
||||||
|
if (!isSymlink) {
|
||||||
|
if (utimes(path.c_str(), times) == -1)
|
||||||
|
throw SysError("changing modification time of '%s' (not a symlink)", path);
|
||||||
|
} else {
|
||||||
|
throw Error("Cannot modification time of symlink '%s'", path);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,8 @@ check_funcs = [
|
||||||
# Optionally used to try to close more file descriptors (e.g. before
|
# Optionally used to try to close more file descriptors (e.g. before
|
||||||
# forking) on Unix.
|
# forking) on Unix.
|
||||||
'sysconf',
|
'sysconf',
|
||||||
|
# Optionally used for changing the mtime of files and symlinks.
|
||||||
|
'utimensat',
|
||||||
]
|
]
|
||||||
foreach funcspec : check_funcs
|
foreach funcspec : check_funcs
|
||||||
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
||||||
|
@ -49,6 +51,8 @@ foreach funcspec : check_funcs
|
||||||
configdata.set(define_name, define_value)
|
configdata.set(define_name, define_value)
|
||||||
endforeach
|
endforeach
|
||||||
|
|
||||||
|
configdata.set('HAVE_DECL_AT_SYMLINK_NOFOLLOW', cxx.has_header_symbol('fcntl.h', 'AT_SYMLINK_NOFOLLOW').to_int())
|
||||||
|
|
||||||
subdir('build-utils-meson/threads')
|
subdir('build-utils-meson/threads')
|
||||||
|
|
||||||
# Check if -latomic is needed
|
# Check if -latomic is needed
|
||||||
|
|
Loading…
Reference in a new issue