aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--butl/filesystem11
-rw-r--r--butl/filesystem.cxx44
-rw-r--r--butl/timestamp13
-rw-r--r--butl/timestamp.cxx44
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)
{