diff options
-rw-r--r-- | butl/filesystem | 11 | ||||
-rw-r--r-- | butl/filesystem.cxx | 44 | ||||
-rw-r--r-- | butl/timestamp | 13 | ||||
-rw-r--r-- | butl/timestamp.cxx | 44 |
4 files changed, 58 insertions, 54 deletions
diff --git a/butl/filesystem b/butl/filesystem index 10f61f2..18ba48e 100644 --- a/butl/filesystem +++ b/butl/filesystem @@ -8,9 +8,18 @@ #include <sys/types.h> // mode_t #include <butl/path> +#include <butl/timestamp> namespace butl { + // Return timestamp_nonexistent if the entry at the specified path + // does not exist or is not a path. All other errors are reported + // by throwing std::system_error. Note that this function resolves + // symlinks. + // + timestamp + file_mtime (const path&); + // Return true if the path is to an existing directory. Note that // this function resolves symlinks. // @@ -48,7 +57,7 @@ namespace butl rmdir_status try_rmdir (const path&); - // Try to remove the file (or symbolic link) returning not_exist if + // Try to remove the file (or symlinks) returning not_exist if // it does not exist. All other errors are reported by throwing // std::system_error. // 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) { diff --git a/butl/timestamp b/butl/timestamp index 76df07b..f397dc6 100644 --- a/butl/timestamp +++ b/butl/timestamp @@ -6,7 +6,6 @@ #define BUTL_TIMESTAMP #include <chrono> -#include <string> #include <iosfwd> #include <butl/path> @@ -34,21 +33,19 @@ namespace butl using timestamp = system_clock::time_point; using duration = system_clock::duration; + // Generally-useful special values. + // const timestamp timestamp_unknown {duration {-1}}; const timestamp timestamp_nonexistent {duration {0}}; + // Human-readable representation. Note that these operators + // may throw std::system_error. + // std::ostream& operator<< (std::ostream&, const timestamp&); std::ostream& operator<< (std::ostream&, const duration&); - - // Returns timestamp_nonexistent if the entry at the specified path - // does not exist. All other errors are reported by throwing - // std::system_error. - // - timestamp - path_mtime (const path&); }; #endif // BUTL_TIMESTAMP diff --git a/butl/timestamp.cxx b/butl/timestamp.cxx index 2d02416..f9f5455 100644 --- a/butl/timestamp.cxx +++ b/butl/timestamp.cxx @@ -4,10 +4,6 @@ #include <butl/timestamp> -#include <unistd.h> // stat -#include <sys/types.h> // stat -#include <sys/stat.h> // stat - #include <time.h> // localtime, gmtime, strftime #include <ostream> @@ -17,46 +13,6 @@ 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 - path_mtime (const path& p) - { - struct stat s; - if (stat (p.string ().c_str (), &s) != 0) - { - if (errno == ENOENT || errno == ENOTDIR) - return timestamp_nonexistent; - else - throw system_error (errno, system_category ()); - } - - return system_clock::from_time_t (s.st_mtime) + - chrono::duration_cast<duration> ( - chrono::nanoseconds (nsec<struct stat> (&s))); - } - ostream& operator<< (ostream& os, const timestamp& ts) { |