diff options
Diffstat (limited to 'butl/filesystem.cxx')
-rw-r--r-- | butl/filesystem.cxx | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/butl/filesystem.cxx b/butl/filesystem.cxx index 230bc8e..7c8893e 100644 --- a/butl/filesystem.cxx +++ b/butl/filesystem.cxx @@ -4,7 +4,7 @@ #include <butl/filesystem> -#include <unistd.h> // rmdir(), unlink() +#include <unistd.h> // stat, rmdir(), unlink() #include <sys/types.h> // stat #include <sys/stat.h> // stat, lstat(), S_IS*, mkdir() @@ -14,6 +14,48 @@ using namespace std; namespace butl { + // Figuring out whether we have the nanoseconds in some form. + // + template <typename S> + constexpr auto nsec (const S* s) -> decltype(s->st_mtim.tv_nsec) + { + return s->st_mtim.tv_nsec; // POSIX (GNU/Linux, Solaris). + } + + template <typename S> + constexpr auto nsec (const S* s) -> decltype(s->st_mtimespec.tv_nsec) + { + return s->st_mtimespec.tv_nsec; // MacOS X. + } + + template <typename S> + constexpr auto nsec (const S* s) -> decltype(s->st_mtime_n) + { + return s->st_mtime_n; // AIX 5.2 and later. + } + + template <typename S> + constexpr int nsec (...) {return 0;} + + timestamp + file_mtime (const path& p) + { + struct stat s; + if (::lstat (p.string ().c_str (), &s) != 0) + { + if (errno == ENOENT || errno == ENOTDIR) + return timestamp_nonexistent; + else + throw system_error (errno, system_category ()); + } + + return S_ISREG (s.st_mode) + ? system_clock::from_time_t (s.st_mtime) + + chrono::duration_cast<duration> ( + chrono::nanoseconds (nsec<struct stat> (&s))) + : timestamp_nonexistent; + } + bool dir_exists (const path& p) { |