]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/testsuite/experimental/filesystem/operations/last_write_time.cc
Check for overflow in filesystem::last_write_time
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / filesystem / operations / last_write_time.cc
CommitLineData
fd5effb1
JW
1// Copyright (C) 2016 Free Software Foundation, Inc.
2//
3// This file is part of the GNU ISO C++ Library. This library is free
4// software; you can redistribute it and/or modify it under the
5// terms of the GNU General Public License as published by the
6// Free Software Foundation; either version 3, or (at your option)
7// any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License along
15// with this library; see the file COPYING3. If not see
16// <http://www.gnu.org/licenses/>.
17
18// { dg-options "-lstdc++fs" }
19// { dg-do run { target c++11 } }
20// { dg-require-filesystem-ts "" }
21
22// 15.25 Permissions [fs.op.last_write_time]
23
24#include <experimental/filesystem>
25#include <testsuite_fs.h>
26#include <testsuite_hooks.h>
27
28#ifdef _GLIBCXX_HAVE_FCNTL_H
29# include <fcntl.h>
30#endif
31#if _GLIBCXX_HAVE_UTIME_H
32# include <utime.h>
33#endif
34
35void
36test01()
37{
38 bool test __attribute__((unused)) = true;
39 using time_type = std::experimental::filesystem::file_time_type;
40
41 auto p = __gnu_test::nonexistent_path();
42 std::error_code ec;
43 time_type mtime = last_write_time(p, ec);
44 VERIFY( ec );
45 VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
46#if __cpp_exceptions
47 bool caught = false;
48 try {
49 mtime = last_write_time(p);
50 } catch (std::system_error const& e) {
51 caught = true;
52 ec = e.code();
53 }
54 VERIFY( caught );
55 VERIFY( ec );
56 VERIFY( ec == std::make_error_code(std::errc::no_such_file_or_directory) );
57#endif
58
59 __gnu_test::scoped_file file(p);
60 VERIFY( exists(p) );
61 mtime = last_write_time(p, ec);
62 VERIFY( !ec );
63 VERIFY( mtime <= time_type::clock::now() );
64 VERIFY( mtime == last_write_time(p) );
65
66 auto end_of_time = time_type::duration::max();
67 auto last_second
68 = std::chrono::duration_cast<std::chrono::seconds>(end_of_time).count();
69 if (last_second > std::numeric_limits<std::time_t>::max())
70 return; // can't test overflow
71
72#if _GLIBCXX_USE_UTIMENSAT
73 struct ::timespec ts[2];
74 ts[0].tv_sec = 0;
75 ts[0].tv_nsec = UTIME_NOW;
76 ts[1].tv_sec = std::numeric_limits<std::time_t>::max() - 1;
77 ts[1].tv_nsec = 0;
78 VERIFY( !::utimensat(AT_FDCWD, p.c_str(), ts, 0) );
79#elif _GLIBCXX_HAVE_UTIME_H
80 ::utimbuf times;
81 times.modtime = std::numeric_limits<std::time_t>::max() - 1;
82 times.actime = std::numeric_limits<std::time_t>::max() - 1;
83 VERIFY( !::utime(p.c_str(), &times) );
84#else
85 return;
86#endif
87
88 mtime = last_write_time(p, ec);
89 VERIFY( ec );
90 VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
91 VERIFY( mtime == time_type::min() );
92
93#if __cpp_exceptions
94 caught = false;
95 try {
96 mtime = last_write_time(p);
97 } catch (std::system_error const& e) {
98 caught = true;
99 ec = e.code();
100 }
101 VERIFY( caught );
102 VERIFY( ec );
103 VERIFY( ec == std::make_error_code(std::errc::value_too_large) );
104#endif
105}
106
107int
108main()
109{
110 test01();
111}