From 4430ca11e9bc9ea68d397424b5bd7e9f40909aed Mon Sep 17 00:00:00 2001 From: Sebastian Messmer Date: Thu, 13 Sep 2018 21:36:50 -0700 Subject: [PATCH] Handle struct ::stat correctly, whether it has st_atim or st_atime members --- src/fspp/impl/FilesystemImpl.cpp | 37 ++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/fspp/impl/FilesystemImpl.cpp b/src/fspp/impl/FilesystemImpl.cpp index 9ff74775..a16ab654 100644 --- a/src/fspp/impl/FilesystemImpl.cpp +++ b/src/fspp/impl/FilesystemImpl.cpp @@ -138,16 +138,41 @@ void FilesystemImpl::closeFile(int descriptor) { } namespace { -void convert_stat_info(const fspp::Node::stat_info& input, struct ::stat *output) { +// Implementation taken from http://en.cppreference.com/w/cpp/types/void_t +// (it takes CWG1558 into account and also works for older compilers) +template struct make_void { typedef void type;}; +template using void_t = typename make_void::type; + +template struct uses_timespec final : std::false_type {}; +template struct uses_timespec> final : std::true_type {}; + +// convert_stat_info_timestamps_ looks if struct ::stat has st_atim or st_atime members +// and sets the correct ones. +template struct convert_stat_info_timestamps_ final {}; +template struct convert_stat_info_timestamps_::value>> final { + static void call(const fspp::Node::stat_info& input, Stat* output) { + output->st_atim = input.atime; + output->st_mtim = input.mtime; + output->st_ctim = input.ctime; + } +}; +template struct convert_stat_info_timestamps_::value>> final { + static void call(const fspp::Node::stat_info& input, Stat* output) { + output->st_atime = input.atime.tv_sec; + output->st_mtime = input.mtime.tv_sec; + output->st_ctime = input.ctime.tv_sec; + } +}; + + +void convert_stat_info_(const fspp::Node::stat_info& input, struct ::stat *output) { output->st_nlink = input.nlink; output->st_mode = input.mode; output->st_uid = input.uid; output->st_gid = input.gid; output->st_size = input.size; output->st_blocks = input.blocks; - output->st_atim = input.atime; - output->st_mtim = input.mtime; - output->st_ctim = input.ctime; + convert_stat_info_timestamps_::call(input, output); } } @@ -158,14 +183,14 @@ void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) { throw fuse::FuseErrnoException(ENOENT); } else { auto stat_info = (*node)->stat(); - convert_stat_info(stat_info, stbuf); + convert_stat_info_(stat_info, stbuf); } } void FilesystemImpl::fstat(int descriptor, struct ::stat *stbuf) { PROFILE(_fstatNanosec); auto stat_info = _open_files.get(descriptor)->stat(); - convert_stat_info(stat_info, stbuf); + convert_stat_info_(stat_info, stbuf); } void FilesystemImpl::chmod(const boost::filesystem::path &path, mode_t mode) {