1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // UNSUPPORTED: c++03, c++11, c++14
10 // UNSUPPORTED: availability-filesystem-missing
11 // UNSUPPORTED: no-filesystem
12 // ADDITIONAL_COMPILE_FLAGS: -I %S/../../../../../../src
13 
14 // This test relies on calling functions from the libcxx internal headers
15 // of <filesystem>; the Windows implementation uses different
16 // internals and doesn't provide the same set_file_times function as for
17 // other platforms.
18 // UNSUPPORTED: windows
19 
20 // This test assumes that time is stored as a 64 bit value when on MVS it is stored as 32 bit
21 // XFAIL: target={{.+}}-zos{{.*}}
22 
23 // <filesystem>
24 
25 // class directory_entry
26 
27 #include <filesystem>
28 #include <type_traits>
29 #include <cassert>
30 
31 #include "assert_macros.h"
32 #include "test_macros.h"
33 #include "filesystem_test_helper.h"
34 
35 #include "filesystem/time_utils.h"
36 
37 namespace fs = std::filesystem;
38 using namespace fs::detail;
39 
last_write_time_not_representable_error()40 static void last_write_time_not_representable_error() {
41   using namespace fs;
42   using namespace std::chrono;
43   scoped_test_env env;
44   const path dir = env.create_dir("dir");
45   const path file = env.create_file("dir/file", 42);
46 
47   TimeSpec ToTime;
48   ToTime.tv_sec = std::numeric_limits<decltype(ToTime.tv_sec)>::max();
49   ToTime.tv_nsec = duration_cast<nanoseconds>(seconds(1)).count() - 1;
50 
51   std::array<TimeSpec, 2> TS = {ToTime, ToTime};
52 
53   file_time_type old_time = last_write_time(file);
54   directory_entry ent(file);
55 
56   file_time_type start_time = file_time_type::clock::now() - hours(1);
57   last_write_time(file, start_time);
58 
59   assert(ent.last_write_time() == old_time);
60 
61   bool IsRepresentable = true;
62   file_time_type rep_value;
63   {
64     std::error_code ec;
65     assert(!set_file_times(file, TS, ec));
66     ec.clear();
67     rep_value = last_write_time(file, ec);
68     IsRepresentable = !bool(ec);
69   }
70 
71   if (!IsRepresentable) {
72     std::error_code rec = GetTestEC();
73     ent.refresh(rec);
74     assert(!rec);
75 
76     const std::errc expected_err = std::errc::value_too_large;
77 
78     std::error_code ec = GetTestEC();
79     assert(ent.last_write_time(ec) == file_time_type::min());
80     assert(ErrorIs(ec, expected_err));
81 
82     ec = GetTestEC();
83     assert(last_write_time(file, ec) == file_time_type::min());
84     assert(ErrorIs(ec, expected_err));
85 
86     ExceptionChecker CheckExcept(file, expected_err,
87                                  "directory_entry::last_write_time");
88     TEST_VALIDATE_EXCEPTION(filesystem_error, CheckExcept,
89                             ent.last_write_time());
90 
91   } else {
92     ent.refresh();
93 
94     std::error_code ec = GetTestEC();
95     assert(ent.last_write_time(ec) == rep_value);
96     assert(!ec);
97   }
98 }
99 
main(int,char **)100 int main(int, char**) {
101   last_write_time_not_representable_error();
102 
103   return 0;
104 }
105