]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / filesystem / operations / temp_directory_path.cc
1 // Copyright (C) 2015-2024 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 "-DUSE_FILESYSTEM_TS -lstdc++fs" }
19 // { dg-do run { target c++11 } }
20 // { dg-require-filesystem-ts "" }
21
22 #include <experimental/filesystem>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <testsuite_hooks.h>
26 #include <testsuite_fs.h>
27
28 void
29 clean_env()
30 {
31 #if defined(__MINGW32__) || defined(__MINGW64__)
32 ::_putenv("TMP=");
33 ::_putenv("TEMP=");
34 #else
35 ::unsetenv("TMPDIR");
36 ::unsetenv("TMP");
37 ::unsetenv("TEMPDIR");
38 ::unsetenv("TEMP");
39 #endif
40 }
41
42 bool
43 set_env(const char* name, std::string value)
44 {
45 #if defined(__MINGW32__) || defined(__MINGW64__)
46 std::string s = name;
47 s += '=';
48 s += value;
49 return !::_putenv(s.c_str());
50 #else
51 return !::setenv(name, value.c_str(), 1);
52 #endif
53 }
54
55 namespace fs = std::experimental::filesystem;
56
57 void
58 test01()
59 {
60 clean_env();
61
62 if (!fs::exists("/tmp"))
63 {
64 puts("/tmp doesn't exist, not testing it for temp_directory_path");
65 return; // just give up
66 }
67
68 std::error_code ec = make_error_code(std::errc::invalid_argument);
69 fs::path p1 = fs::temp_directory_path(ec);
70 VERIFY( !ec );
71 VERIFY( exists(p1) );
72
73 fs::path p2 = fs::temp_directory_path();
74 VERIFY( p1 == p2 );
75 }
76
77 void
78 test02()
79 {
80 clean_env();
81
82 if (!set_env("TMP", __gnu_test::nonexistent_path().string()))
83 {
84 puts("Cannot set environment variables, not testing temp_directory_path");
85 return; // just give up
86 }
87
88 std::error_code ec;
89 fs::path p = fs::temp_directory_path(ec);
90 VERIFY( ec );
91 VERIFY( p == fs::path() );
92
93 std::error_code ec2;
94 try {
95 p = fs::temp_directory_path();
96 } catch (const fs::filesystem_error& e) {
97 ec2 = e.code();
98 }
99 VERIFY( ec2 == ec );
100 }
101
102 void
103 test03()
104 {
105 if (!__gnu_test::permissions_are_testable())
106 return;
107
108 clean_env();
109
110 auto p = __gnu_test::nonexistent_path();
111 create_directories(p/"tmp");
112 permissions(p, fs::perms::none);
113 set_env("TMPDIR", (p/"tmp").string());
114 std::error_code ec;
115 auto r = fs::temp_directory_path(ec); // libstdc++/PR71337
116 VERIFY( ec == std::make_error_code(std::errc::permission_denied) );
117 VERIFY( r == fs::path() );
118
119 std::error_code ec2;
120 try {
121 (void) fs::temp_directory_path();
122 } catch (const fs::filesystem_error& e) {
123 ec2 = e.code();
124 }
125 VERIFY( ec2 == ec );
126
127 permissions(p, fs::perms::owner_all, ec);
128 remove_all(p, ec);
129 }
130
131 void
132 test04()
133 {
134 clean_env();
135
136 __gnu_test::scoped_file f;
137 set_env("TMP", f.path.string());
138 std::error_code ec;
139 auto r = fs::temp_directory_path(ec);
140 VERIFY( ec == std::make_error_code(std::errc::not_a_directory) );
141 VERIFY( r == fs::path() );
142
143 std::error_code ec2;
144 std::string failed_path;
145 try {
146 (void) fs::temp_directory_path();
147 } catch (const fs::filesystem_error& e) {
148 ec2 = e.code();
149 // On Windows the returned path will be in preferred form, i.e. using L'\\'
150 // and will have a trailing slash, so compare generic forms.
151 failed_path = e.path1().generic_string();
152 }
153 VERIFY( ec2 == ec );
154 VERIFY( failed_path.find(f.path.generic_string()) != std::string::npos );
155 }
156
157 int
158 main()
159 {
160 test01();
161 test02();
162 test03();
163 test04();
164 }