diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-25 15:32:52 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-10-25 15:32:52 +0000 |
commit | 2fa9dfd45fee22b0662ddea5b5eeea377d48fe7e (patch) | |
tree | e20fea44c107df23239db86f2a8a4f203b078b96 | |
parent | d9fbb1e87f42a054f4223c9e551e0d1a6cb76d9d (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/ops.cc | 5 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc | 40 |
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(); } |