#include <unistd.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
+#include <sys/time.h> // for ::utimes as used in __last_write_time
#include <fcntl.h> /* values for fchmodat */
#include <experimental/filesystem>
#endif
#endif
-#if !defined(_LIBCPP_USE_UTIMENSAT)
-#include <sys/time.h> // for ::utimes as used in __last_write_time
-#endif
-
-#if !defined(UTIME_OMIT)
-#include <sys/time.h> // for ::utimes as used in __last_write_time
-#endif
-
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
TimeSpec extract_atime(StatT const& st) { return st.st_atim; }
#endif
-bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+// allow the utimes implementation to compile even it we're not going
+// to use it.
+
+bool posix_utimes(const path& p, std::array<TimeSpec, 2> const& TS,
error_code& ec) {
-#if !defined(_LIBCPP_USE_UTIMENSAT)
using namespace chrono;
auto Convert = [](long nsec) {
using int_type = decltype(std::declval<::timeval>().tv_usec);
};
struct ::timeval ConvertedTS[2] = {{TS[0].tv_sec, Convert(TS[0].tv_nsec)},
{TS[1].tv_sec, Convert(TS[1].tv_nsec)}};
- if (::utimes(p.c_str(), ConvertedTS) == -1)
-#else
+ if (::utimes(p.c_str(), ConvertedTS) == -1) {
+ ec = capture_errno();
+ return true;
+ }
+ return false;
+}
+
+#if defined(_LIBCPP_USE_UTIMENSAT)
+bool posix_utimensat(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
if (::utimensat(AT_FDCWD, p.c_str(), TS.data(), 0) == -1)
-#endif
{
ec = capture_errno();
return true;
}
return false;
}
+#endif
-bool set_time_spec_to(TimeSpec& TS, file_time_type NewTime) {
- return !fs_time::set_times_checked(
- &TS.tv_sec, &TS.tv_nsec, NewTime);
+bool set_file_times(const path& p, std::array<TimeSpec, 2> const& TS,
+ error_code& ec) {
+#if !defined(_LIBCPP_USE_UTIMENSAT)
+ return posix_utimes(p, TS, ec);
+#else
+ return posix_utimensat(p, TS, ec);
+#endif
}
+
} // namespace
} // end namespace detail
void __last_write_time(const path& p, file_time_type new_time,
error_code *ec)
{
+ using detail::fs_time;
ErrorHandler<void> err("last_write_time", ec, &p);
error_code m_ec;
tbuf[0].tv_sec = 0;
tbuf[0].tv_nsec = UTIME_OMIT;
#endif
- if (detail::set_time_spec_to(tbuf[1], new_time))
+ if (!fs_time::convert_to_timespec(tbuf[1], new_time))
return err.report(errc::value_too_large);
detail::set_file_times(p, tbuf, m_ec);