From 6852289c46cdfceb07b459cd1028722ffb124ca6 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 23 Jul 2012 16:52:25 -0400 Subject: [PATCH] Use lutimes() if available to canonicalise the timestamp of symlinks Also use utimes() instead of utime() if lutimes() is not available. --- configure.ac | 5 +++++ src/libstore/local-store.cc | 25 ++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 7b814dedc..a2512cfe9 100644 --- a/configure.ac +++ b/configure.ac @@ -115,6 +115,11 @@ AC_CHECK_HEADERS([sys/mount.h], [], [], ]) +# Check for lutimes, optionally used for changing the mtime of +# symlinks. +AC_CHECK_FUNCS([lutimes]) + + # Check for . AC_LANG_PUSH(C++) AC_CHECK_HEADERS([locale]) diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index 30398a244..e009191b6 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -444,7 +445,7 @@ void canonicalisePathMetaData(const Path & path, bool recurse) throw SysError(format("changing owner of `%1%' to %2%") % path % geteuid()); } - + if (!S_ISLNK(st.st_mode)) { /* Mask out all type related bits. */ @@ -458,14 +459,20 @@ void canonicalisePathMetaData(const Path & path, bool recurse) throw SysError(format("changing mode of `%1%' to %2$o") % path % mode); } - if (st.st_mtime != mtimeStore) { - struct utimbuf utimbuf; - utimbuf.actime = st.st_atime; - utimbuf.modtime = mtimeStore; - if (utime(path.c_str(), &utimbuf) == -1) - throw SysError(format("changing modification time of `%1%'") % path); - } - + } + + if (st.st_mtime != mtimeStore) { + struct timeval times[2]; + times[0].tv_sec = st.st_atime; + times[0].tv_usec = 0; + times[1].tv_sec = mtimeStore; + times[1].tv_usec = 0; +#if HAVE_LUTIMES + if (lutimes(path.c_str(), times) == -1) +#else + if (!S_ISLNK(st.st_mode) && utimes(path.c_str(), times) == -1) +#endif + throw SysError(format("changing modification time of `%1%'") % path); } if (recurse && S_ISDIR(st.st_mode)) {