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.

From-SVN: r241522
This commit is contained in:
Jonathan Wakely 2016-10-25 16:32:52 +01:00 committed by Jonathan Wakely
parent ec04aad76d
commit 7195dfe9b6
3 changed files with 51 additions and 0 deletions

View File

@ -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.

View File

@ -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;

View File

@ -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();
}