summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-25 15:32:52 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2016-10-25 15:32:52 +0000
commit2fa9dfd45fee22b0662ddea5b5eeea377d48fe7e (patch)
treee20fea44c107df23239db86f2a8a4f203b078b96
parentd9fbb1e87f42a054f4223c9e551e0d1a6cb76d9d (diff)
downloadgcc-2fa9dfd45fee22b0662ddea5b5eeea377d48fe7e.tar.gz
Handle negative times in filesystem::last_write_time
* src/filesystem/ops.cc (last_write_time(const path&, file_time_type, error_code&)): Handle negative times correctly. * testsuite/experimental/filesystem/operations/last_write_time.cc: Test writing file times. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241522 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc5
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc40
3 files changed, 51 insertions, 0 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 5086417d463..11ac1062d09 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
2016-10-25 Jonathan Wakely <jwakely@redhat.com>
+ * src/filesystem/ops.cc
+ (last_write_time(const path&, file_time_type, error_code&)): Handle
+ negative times correctly.
+ * testsuite/experimental/filesystem/operations/last_write_time.cc:
+ Test writing file times.
+
* src/filesystem/ops.cc (do_copy_file): Report an error if source or
destination is not a regular file (LWG 2712).
(equivalent): Fix error handling and result when only one file exists.
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index fcf747e6a01..32c9c5e850d 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -1100,6 +1100,11 @@ fs::last_write_time(const path& p __attribute__((__unused__)),
auto s = chrono::duration_cast<chrono::seconds>(d);
#if _GLIBCXX_USE_UTIMENSAT
auto ns = chrono::duration_cast<chrono::nanoseconds>(d - s);
+ if (ns < ns.zero()) // tv_nsec must be non-negative and less than 10e9.
+ {
+ --s;
+ ns += chrono::seconds(1);
+ }
struct ::timespec ts[2];
ts[0].tv_sec = 0;
ts[0].tv_nsec = UTIME_OMIT;
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
index dee55a53cdb..74be4f94dda 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
@@ -35,6 +35,8 @@
void
test01()
{
+ // read times
+
using time_type = std::experimental::filesystem::file_time_type;
auto p = __gnu_test::nonexistent_path();
@@ -103,8 +105,46 @@ test01()
#endif
}
+void
+test02()
+{
+ // write times
+
+ using time_type = std::experimental::filesystem::file_time_type;
+
+ __gnu_test::scoped_file f;
+ std::error_code ec;
+ time_type time;
+
+ time = last_write_time(f.path);
+ last_write_time(f.path, time, ec);
+ VERIFY( !ec );
+ VERIFY( last_write_time(f.path) == time );
+
+ time -= std::chrono::milliseconds(1000 * 60 * 10 + 15);
+ last_write_time(f.path, time, ec);
+ VERIFY( !ec );
+ VERIFY( last_write_time(f.path) == time );
+
+ time += std::chrono::milliseconds(1000 * 60 * 20 + 15);
+ last_write_time(f.path, time, ec);
+ VERIFY( !ec );
+ VERIFY( last_write_time(f.path) == time );
+
+ time = time_type();
+ last_write_time(f.path, time, ec);
+ VERIFY( !ec );
+ VERIFY( last_write_time(f.path) == time );
+
+ time -= std::chrono::milliseconds(1000 * 60 * 10 + 15);
+ last_write_time(f.path, time, ec);
+ VERIFY( !ec );
+ VERIFY( last_write_time(f.path) == time );
+}
+
int
main()
{
test01();
+ test02();
}