1 //===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===//
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 #include "llvm/Support/Path.h"
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/Triple.h"
13 #include "llvm/BinaryFormat/Magic.h"
14 #include "llvm/Config/llvm-config.h"
15 #include "llvm/Support/ConvertUTF.h"
16 #include "llvm/Support/Errc.h"
17 #include "llvm/Support/ErrorHandling.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/FileUtilities.h"
20 #include "llvm/Support/Host.h"
21 #include "llvm/Support/MemoryBuffer.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "gtest/gtest.h"
24 #include "gmock/gmock.h"
25 
26 #ifdef _WIN32
27 #include "llvm/ADT/ArrayRef.h"
28 #include "llvm/Support/Chrono.h"
29 #include <windows.h>
30 #include <winerror.h>
31 #endif
32 
33 #ifdef LLVM_ON_UNIX
34 #include <pwd.h>
35 #include <sys/stat.h>
36 #endif
37 
38 using namespace llvm;
39 using namespace llvm::sys;
40 
41 #define ASSERT_NO_ERROR(x)                                                     \
42   if (std::error_code ASSERT_NO_ERROR_ec = x) {                                \
43     SmallString<128> MessageStorage;                                           \
44     raw_svector_ostream Message(MessageStorage);                               \
45     Message << #x ": did not return errc::success.\n"                          \
46             << "error number: " << ASSERT_NO_ERROR_ec.value() << "\n"          \
47             << "error message: " << ASSERT_NO_ERROR_ec.message() << "\n";      \
48     GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
49   } else {                                                                     \
50   }
51 
52 #define ASSERT_ERROR(x)                                                        \
53   if (!x) {                                                                    \
54     SmallString<128> MessageStorage;                                           \
55     raw_svector_ostream Message(MessageStorage);                               \
56     Message << #x ": did not return a failure error code.\n";                  \
57     GTEST_FATAL_FAILURE_(MessageStorage.c_str());                              \
58   }
59 
60 namespace {
61 
62 struct FileDescriptorCloser {
63   explicit FileDescriptorCloser(int FD) : FD(FD) {}
64   ~FileDescriptorCloser() { ::close(FD); }
65   int FD;
66 };
67 
68 TEST(is_separator, Works) {
69   EXPECT_TRUE(path::is_separator('/'));
70   EXPECT_FALSE(path::is_separator('\0'));
71   EXPECT_FALSE(path::is_separator('-'));
72   EXPECT_FALSE(path::is_separator(' '));
73 
74   EXPECT_TRUE(path::is_separator('\\', path::Style::windows));
75   EXPECT_FALSE(path::is_separator('\\', path::Style::posix));
76 
77 #ifdef _WIN32
78   EXPECT_TRUE(path::is_separator('\\'));
79 #else
80   EXPECT_FALSE(path::is_separator('\\'));
81 #endif
82 }
83 
84 TEST(Support, Path) {
85   SmallVector<StringRef, 40> paths;
86   paths.push_back("");
87   paths.push_back(".");
88   paths.push_back("..");
89   paths.push_back("foo");
90   paths.push_back("/");
91   paths.push_back("/foo");
92   paths.push_back("foo/");
93   paths.push_back("/foo/");
94   paths.push_back("foo/bar");
95   paths.push_back("/foo/bar");
96   paths.push_back("//net");
97   paths.push_back("//net/");
98   paths.push_back("//net/foo");
99   paths.push_back("///foo///");
100   paths.push_back("///foo///bar");
101   paths.push_back("/.");
102   paths.push_back("./");
103   paths.push_back("/..");
104   paths.push_back("../");
105   paths.push_back("foo/.");
106   paths.push_back("foo/..");
107   paths.push_back("foo/./");
108   paths.push_back("foo/./bar");
109   paths.push_back("foo/..");
110   paths.push_back("foo/../");
111   paths.push_back("foo/../bar");
112   paths.push_back("c:");
113   paths.push_back("c:/");
114   paths.push_back("c:foo");
115   paths.push_back("c:/foo");
116   paths.push_back("c:foo/");
117   paths.push_back("c:/foo/");
118   paths.push_back("c:/foo/bar");
119   paths.push_back("prn:");
120   paths.push_back("c:\\");
121   paths.push_back("c:foo");
122   paths.push_back("c:\\foo");
123   paths.push_back("c:foo\\");
124   paths.push_back("c:\\foo\\");
125   paths.push_back("c:\\foo/");
126   paths.push_back("c:/foo\\bar");
127 
128   for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(),
129                                                   e = paths.end();
130                                                   i != e;
131                                                   ++i) {
132     SCOPED_TRACE(*i);
133     SmallVector<StringRef, 5> ComponentStack;
134     for (sys::path::const_iterator ci = sys::path::begin(*i),
135                                    ce = sys::path::end(*i);
136                                    ci != ce;
137                                    ++ci) {
138       EXPECT_FALSE(ci->empty());
139       ComponentStack.push_back(*ci);
140     }
141 
142     SmallVector<StringRef, 5> ReverseComponentStack;
143     for (sys::path::reverse_iterator ci = sys::path::rbegin(*i),
144                                      ce = sys::path::rend(*i);
145                                      ci != ce;
146                                      ++ci) {
147       EXPECT_FALSE(ci->empty());
148       ReverseComponentStack.push_back(*ci);
149     }
150     std::reverse(ReverseComponentStack.begin(), ReverseComponentStack.end());
151     EXPECT_THAT(ComponentStack, testing::ContainerEq(ReverseComponentStack));
152 
153     // Crash test most of the API - since we're iterating over all of our paths
154     // here there isn't really anything reasonable to assert on in the results.
155     (void)path::has_root_path(*i);
156     (void)path::root_path(*i);
157     (void)path::has_root_name(*i);
158     (void)path::root_name(*i);
159     (void)path::has_root_directory(*i);
160     (void)path::root_directory(*i);
161     (void)path::has_parent_path(*i);
162     (void)path::parent_path(*i);
163     (void)path::has_filename(*i);
164     (void)path::filename(*i);
165     (void)path::has_stem(*i);
166     (void)path::stem(*i);
167     (void)path::has_extension(*i);
168     (void)path::extension(*i);
169     (void)path::is_absolute(*i);
170     (void)path::is_relative(*i);
171 
172     SmallString<128> temp_store;
173     temp_store = *i;
174     ASSERT_NO_ERROR(fs::make_absolute(temp_store));
175     temp_store = *i;
176     path::remove_filename(temp_store);
177 
178     temp_store = *i;
179     path::replace_extension(temp_store, "ext");
180     StringRef filename(temp_store.begin(), temp_store.size()), stem, ext;
181     stem = path::stem(filename);
182     ext  = path::extension(filename);
183     EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str());
184 
185     path::native(*i, temp_store);
186   }
187 
188   {
189     SmallString<32> Relative("foo.cpp");
190     sys::fs::make_absolute("/root", Relative);
191     Relative[5] = '/'; // Fix up windows paths.
192     ASSERT_EQ("/root/foo.cpp", Relative);
193   }
194 
195   {
196     SmallString<32> Relative("foo.cpp");
197     sys::fs::make_absolute("//root", Relative);
198     Relative[6] = '/'; // Fix up windows paths.
199     ASSERT_EQ("//root/foo.cpp", Relative);
200   }
201 }
202 
203 TEST(Support, FilenameParent) {
204   EXPECT_EQ("/", path::filename("/"));
205   EXPECT_EQ("", path::parent_path("/"));
206 
207   EXPECT_EQ("\\", path::filename("c:\\", path::Style::windows));
208   EXPECT_EQ("c:", path::parent_path("c:\\", path::Style::windows));
209 
210   EXPECT_EQ("/", path::filename("///"));
211   EXPECT_EQ("", path::parent_path("///"));
212 
213   EXPECT_EQ("\\", path::filename("c:\\\\", path::Style::windows));
214   EXPECT_EQ("c:", path::parent_path("c:\\\\", path::Style::windows));
215 
216   EXPECT_EQ("bar", path::filename("/foo/bar"));
217   EXPECT_EQ("/foo", path::parent_path("/foo/bar"));
218 
219   EXPECT_EQ("foo", path::filename("/foo"));
220   EXPECT_EQ("/", path::parent_path("/foo"));
221 
222   EXPECT_EQ("foo", path::filename("foo"));
223   EXPECT_EQ("", path::parent_path("foo"));
224 
225   EXPECT_EQ(".", path::filename("foo/"));
226   EXPECT_EQ("foo", path::parent_path("foo/"));
227 
228   EXPECT_EQ("//net", path::filename("//net"));
229   EXPECT_EQ("", path::parent_path("//net"));
230 
231   EXPECT_EQ("/", path::filename("//net/"));
232   EXPECT_EQ("//net", path::parent_path("//net/"));
233 
234   EXPECT_EQ("foo", path::filename("//net/foo"));
235   EXPECT_EQ("//net/", path::parent_path("//net/foo"));
236 
237   // These checks are just to make sure we do something reasonable with the
238   // paths below. They are not meant to prescribe the one true interpretation of
239   // these paths. Other decompositions (e.g. "//" -> "" + "//") are also
240   // possible.
241   EXPECT_EQ("/", path::filename("//"));
242   EXPECT_EQ("", path::parent_path("//"));
243 
244   EXPECT_EQ("\\", path::filename("\\\\", path::Style::windows));
245   EXPECT_EQ("", path::parent_path("\\\\", path::Style::windows));
246 
247   EXPECT_EQ("\\", path::filename("\\\\\\", path::Style::windows));
248   EXPECT_EQ("", path::parent_path("\\\\\\", path::Style::windows));
249 }
250 
251 static std::vector<StringRef>
252 GetComponents(StringRef Path, path::Style S = path::Style::native) {
253   return {path::begin(Path, S), path::end(Path)};
254 }
255 
256 TEST(Support, PathIterator) {
257   EXPECT_THAT(GetComponents("/foo"), testing::ElementsAre("/", "foo"));
258   EXPECT_THAT(GetComponents("/"), testing::ElementsAre("/"));
259   EXPECT_THAT(GetComponents("//"), testing::ElementsAre("/"));
260   EXPECT_THAT(GetComponents("///"), testing::ElementsAre("/"));
261   EXPECT_THAT(GetComponents("c/d/e/foo.txt"),
262               testing::ElementsAre("c", "d", "e", "foo.txt"));
263   EXPECT_THAT(GetComponents(".c/.d/../."),
264               testing::ElementsAre(".c", ".d", "..", "."));
265   EXPECT_THAT(GetComponents("/c/d/e/foo.txt"),
266               testing::ElementsAre("/", "c", "d", "e", "foo.txt"));
267   EXPECT_THAT(GetComponents("/.c/.d/../."),
268               testing::ElementsAre("/", ".c", ".d", "..", "."));
269   EXPECT_THAT(GetComponents("c:\\c\\e\\foo.txt", path::Style::windows),
270               testing::ElementsAre("c:", "\\", "c", "e", "foo.txt"));
271   EXPECT_THAT(GetComponents("//net/"), testing::ElementsAre("//net", "/"));
272   EXPECT_THAT(GetComponents("//net/c/foo.txt"),
273               testing::ElementsAre("//net", "/", "c", "foo.txt"));
274 }
275 
276 TEST(Support, AbsolutePathIteratorEnd) {
277   // Trailing slashes are converted to '.' unless they are part of the root path.
278   SmallVector<std::pair<StringRef, path::Style>, 4> Paths;
279   Paths.emplace_back("/foo/", path::Style::native);
280   Paths.emplace_back("/foo//", path::Style::native);
281   Paths.emplace_back("//net/foo/", path::Style::native);
282   Paths.emplace_back("c:\\foo\\", path::Style::windows);
283 
284   for (auto &Path : Paths) {
285     SCOPED_TRACE(Path.first);
286     StringRef LastComponent = *path::rbegin(Path.first, Path.second);
287     EXPECT_EQ(".", LastComponent);
288   }
289 
290   SmallVector<std::pair<StringRef, path::Style>, 3> RootPaths;
291   RootPaths.emplace_back("/", path::Style::native);
292   RootPaths.emplace_back("//net/", path::Style::native);
293   RootPaths.emplace_back("c:\\", path::Style::windows);
294   RootPaths.emplace_back("//net//", path::Style::native);
295   RootPaths.emplace_back("c:\\\\", path::Style::windows);
296 
297   for (auto &Path : RootPaths) {
298     SCOPED_TRACE(Path.first);
299     StringRef LastComponent = *path::rbegin(Path.first, Path.second);
300     EXPECT_EQ(1u, LastComponent.size());
301     EXPECT_TRUE(path::is_separator(LastComponent[0], Path.second));
302   }
303 }
304 
305 TEST(Support, HomeDirectory) {
306   std::string expected;
307 #ifdef _WIN32
308   if (wchar_t const *path = ::_wgetenv(L"USERPROFILE")) {
309     auto pathLen = ::wcslen(path);
310     ArrayRef<char> ref{reinterpret_cast<char const *>(path),
311                        pathLen * sizeof(wchar_t)};
312     convertUTF16ToUTF8String(ref, expected);
313   }
314 #else
315   if (char const *path = ::getenv("HOME"))
316     expected = path;
317 #endif
318   // Do not try to test it if we don't know what to expect.
319   // On Windows we use something better than env vars.
320   if (!expected.empty()) {
321     SmallString<128> HomeDir;
322     auto status = path::home_directory(HomeDir);
323     EXPECT_TRUE(status);
324     EXPECT_EQ(expected, HomeDir);
325   }
326 }
327 
328 #ifdef LLVM_ON_UNIX
329 TEST(Support, HomeDirectoryWithNoEnv) {
330   std::string OriginalStorage;
331   char const *OriginalEnv = ::getenv("HOME");
332   if (OriginalEnv) {
333     // We're going to unset it, so make a copy and save a pointer to the copy
334     // so that we can reset it at the end of the test.
335     OriginalStorage = OriginalEnv;
336     OriginalEnv = OriginalStorage.c_str();
337   }
338 
339   // Don't run the test if we have nothing to compare against.
340   struct passwd *pw = getpwuid(getuid());
341   if (!pw || !pw->pw_dir) return;
342 
343   ::unsetenv("HOME");
344   EXPECT_EQ(nullptr, ::getenv("HOME"));
345   std::string PwDir = pw->pw_dir;
346 
347   SmallString<128> HomeDir;
348   auto status = path::home_directory(HomeDir);
349   EXPECT_TRUE(status);
350   EXPECT_EQ(PwDir, HomeDir);
351 
352   // Now put the environment back to its original state (meaning that if it was
353   // unset before, we don't reset it).
354   if (OriginalEnv) ::setenv("HOME", OriginalEnv, 1);
355 }
356 #endif
357 
358 TEST(Support, TempDirectory) {
359   SmallString<32> TempDir;
360   path::system_temp_directory(false, TempDir);
361   EXPECT_TRUE(!TempDir.empty());
362   TempDir.clear();
363   path::system_temp_directory(true, TempDir);
364   EXPECT_TRUE(!TempDir.empty());
365 }
366 
367 #ifdef _WIN32
368 static std::string path2regex(std::string Path) {
369   size_t Pos = 0;
370   while ((Pos = Path.find('\\', Pos)) != std::string::npos) {
371     Path.replace(Pos, 1, "\\\\");
372     Pos += 2;
373   }
374   return Path;
375 }
376 
377 /// Helper for running temp dir test in separated process. See below.
378 #define EXPECT_TEMP_DIR(prepare, expected)                                     \
379   EXPECT_EXIT(                                                                 \
380       {                                                                        \
381         prepare;                                                               \
382         SmallString<300> TempDir;                                              \
383         path::system_temp_directory(true, TempDir);                            \
384         raw_os_ostream(std::cerr) << TempDir;                                  \
385         std::exit(0);                                                          \
386       },                                                                       \
387       ::testing::ExitedWithCode(0), path2regex(expected))
388 
389 TEST(SupportDeathTest, TempDirectoryOnWindows) {
390   // In this test we want to check how system_temp_directory responds to
391   // different values of specific env vars. To prevent corrupting env vars of
392   // the current process all checks are done in separated processes.
393   EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:\\OtherFolder"), "C:\\OtherFolder");
394   EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:/Unix/Path/Seperators"),
395                   "C:\\Unix\\Path\\Seperators");
396   EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"Local Path"), ".+\\Local Path$");
397   EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"F:\\TrailingSep\\"), "F:\\TrailingSep");
398   EXPECT_TEMP_DIR(
399       _wputenv_s(L"TMP", L"C:\\2\x03C0r-\x00B5\x00B3\\\x2135\x2080"),
400       "C:\\2\xCF\x80r-\xC2\xB5\xC2\xB3\\\xE2\x84\xB5\xE2\x82\x80");
401 
402   // Test $TMP empty, $TEMP set.
403   EXPECT_TEMP_DIR(
404       {
405         _wputenv_s(L"TMP", L"");
406         _wputenv_s(L"TEMP", L"C:\\Valid\\Path");
407       },
408       "C:\\Valid\\Path");
409 
410   // All related env vars empty
411   EXPECT_TEMP_DIR(
412   {
413     _wputenv_s(L"TMP", L"");
414     _wputenv_s(L"TEMP", L"");
415     _wputenv_s(L"USERPROFILE", L"");
416   },
417     "C:\\Temp");
418 
419   // Test evn var / path with 260 chars.
420   SmallString<270> Expected{"C:\\Temp\\AB\\123456789"};
421   while (Expected.size() < 260)
422     Expected.append("\\DirNameWith19Charss");
423   ASSERT_EQ(260U, Expected.size());
424   EXPECT_TEMP_DIR(_putenv_s("TMP", Expected.c_str()), Expected.c_str());
425 }
426 #endif
427 
428 class FileSystemTest : public testing::Test {
429 protected:
430   /// Unique temporary directory in which all created filesystem entities must
431   /// be placed. It is removed at the end of each test (must be empty).
432   SmallString<128> TestDirectory;
433   SmallString<128> NonExistantFile;
434 
435   void SetUp() override {
436     ASSERT_NO_ERROR(
437         fs::createUniqueDirectory("file-system-test", TestDirectory));
438     // We don't care about this specific file.
439     errs() << "Test Directory: " << TestDirectory << '\n';
440     errs().flush();
441     NonExistantFile = TestDirectory;
442 
443     // Even though this value is hardcoded, is a 128-bit GUID, so we should be
444     // guaranteed that this file will never exist.
445     sys::path::append(NonExistantFile, "1B28B495C16344CB9822E588CD4C3EF0");
446   }
447 
448   void TearDown() override { ASSERT_NO_ERROR(fs::remove(TestDirectory.str())); }
449 };
450 
451 TEST_F(FileSystemTest, Unique) {
452   // Create a temp file.
453   int FileDescriptor;
454   SmallString<64> TempPath;
455   ASSERT_NO_ERROR(
456       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
457 
458   // The same file should return an identical unique id.
459   fs::UniqueID F1, F2;
460   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F1));
461   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), F2));
462   ASSERT_EQ(F1, F2);
463 
464   // Different files should return different unique ids.
465   int FileDescriptor2;
466   SmallString<64> TempPath2;
467   ASSERT_NO_ERROR(
468       fs::createTemporaryFile("prefix", "temp", FileDescriptor2, TempPath2));
469 
470   fs::UniqueID D;
471   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D));
472   ASSERT_NE(D, F1);
473   ::close(FileDescriptor2);
474 
475   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
476 
477   // Two paths representing the same file on disk should still provide the
478   // same unique id.  We can test this by making a hard link.
479   ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
480   fs::UniqueID D2;
481   ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath2), D2));
482   ASSERT_EQ(D2, F1);
483 
484   ::close(FileDescriptor);
485 
486   SmallString<128> Dir1;
487   ASSERT_NO_ERROR(
488      fs::createUniqueDirectory("dir1", Dir1));
489   ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F1));
490   ASSERT_NO_ERROR(fs::getUniqueID(Dir1.c_str(), F2));
491   ASSERT_EQ(F1, F2);
492 
493   SmallString<128> Dir2;
494   ASSERT_NO_ERROR(
495      fs::createUniqueDirectory("dir2", Dir2));
496   ASSERT_NO_ERROR(fs::getUniqueID(Dir2.c_str(), F2));
497   ASSERT_NE(F1, F2);
498   ASSERT_NO_ERROR(fs::remove(Dir1));
499   ASSERT_NO_ERROR(fs::remove(Dir2));
500   ASSERT_NO_ERROR(fs::remove(TempPath2));
501   ASSERT_NO_ERROR(fs::remove(TempPath));
502 }
503 
504 TEST_F(FileSystemTest, RealPath) {
505   ASSERT_NO_ERROR(
506       fs::create_directories(Twine(TestDirectory) + "/test1/test2/test3"));
507   ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/test1/test2/test3"));
508 
509   SmallString<64> RealBase;
510   SmallString<64> Expected;
511   SmallString<64> Actual;
512 
513   // TestDirectory itself might be under a symlink or have been specified with
514   // a different case than the existing temp directory.  In such cases real_path
515   // on the concatenated path will differ in the TestDirectory portion from
516   // how we specified it.  Make sure to compare against the real_path of the
517   // TestDirectory, and not just the value of TestDirectory.
518   ASSERT_NO_ERROR(fs::real_path(TestDirectory, RealBase));
519   path::native(Twine(RealBase) + "/test1/test2", Expected);
520 
521   ASSERT_NO_ERROR(fs::real_path(
522       Twine(TestDirectory) + "/././test1/../test1/test2/./test3/..", Actual));
523 
524   EXPECT_EQ(Expected, Actual);
525 
526   SmallString<64> HomeDir;
527 
528   // This can fail if $HOME is not set and getpwuid fails.
529   bool Result = llvm::sys::path::home_directory(HomeDir);
530   if (Result) {
531     ASSERT_NO_ERROR(fs::real_path(HomeDir, Expected));
532     ASSERT_NO_ERROR(fs::real_path("~", Actual, true));
533     EXPECT_EQ(Expected, Actual);
534     ASSERT_NO_ERROR(fs::real_path("~/", Actual, true));
535     EXPECT_EQ(Expected, Actual);
536   }
537 
538   ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1"));
539 }
540 
541 TEST_F(FileSystemTest, ExpandTilde) {
542   SmallString<64> Expected;
543   SmallString<64> Actual;
544   SmallString<64> HomeDir;
545 
546   // This can fail if $HOME is not set and getpwuid fails.
547   bool Result = llvm::sys::path::home_directory(HomeDir);
548   if (Result) {
549     fs::expand_tilde(HomeDir, Expected);
550 
551     fs::expand_tilde("~", Actual);
552     EXPECT_EQ(Expected, Actual);
553 
554 #ifdef _WIN32
555     Expected += "\\foo";
556     fs::expand_tilde("~\\foo", Actual);
557 #else
558     Expected += "/foo";
559     fs::expand_tilde("~/foo", Actual);
560 #endif
561 
562     EXPECT_EQ(Expected, Actual);
563   }
564 }
565 
566 #ifdef LLVM_ON_UNIX
567 TEST_F(FileSystemTest, RealPathNoReadPerm) {
568   SmallString<64> Expanded;
569 
570   ASSERT_NO_ERROR(
571     fs::create_directories(Twine(TestDirectory) + "/noreadperm"));
572   ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/noreadperm"));
573 
574   fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::no_perms);
575   fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::all_exe);
576 
577   ASSERT_NO_ERROR(fs::real_path(Twine(TestDirectory) + "/noreadperm", Expanded,
578                                 false));
579 
580   ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noreadperm"));
581 }
582 #endif
583 
584 
585 TEST_F(FileSystemTest, TempFileKeepDiscard) {
586   // We can keep then discard.
587   auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
588   ASSERT_TRUE((bool)TempFileOrError);
589   fs::TempFile File = std::move(*TempFileOrError);
590   ASSERT_EQ(-1, TempFileOrError->FD);
591   ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep"));
592   ASSERT_FALSE((bool)File.discard());
593   ASSERT_TRUE(fs::exists(TestDirectory + "/keep"));
594   ASSERT_NO_ERROR(fs::remove(TestDirectory + "/keep"));
595 }
596 
597 TEST_F(FileSystemTest, TempFileDiscardDiscard) {
598   // We can discard twice.
599   auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%");
600   ASSERT_TRUE((bool)TempFileOrError);
601   fs::TempFile File = std::move(*TempFileOrError);
602   ASSERT_EQ(-1, TempFileOrError->FD);
603   ASSERT_FALSE((bool)File.discard());
604   ASSERT_FALSE((bool)File.discard());
605   ASSERT_FALSE(fs::exists(TestDirectory + "/keep"));
606 }
607 
608 TEST_F(FileSystemTest, TempFiles) {
609   // Create a temp file.
610   int FileDescriptor;
611   SmallString<64> TempPath;
612   ASSERT_NO_ERROR(
613       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
614 
615   // Make sure it exists.
616   ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
617 
618   // Create another temp tile.
619   int FD2;
620   SmallString<64> TempPath2;
621   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2));
622   ASSERT_TRUE(TempPath2.endswith(".temp"));
623   ASSERT_NE(TempPath.str(), TempPath2.str());
624 
625   fs::file_status A, B;
626   ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
627   ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
628   EXPECT_FALSE(fs::equivalent(A, B));
629 
630   ::close(FD2);
631 
632   // Remove Temp2.
633   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
634   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
635   ASSERT_EQ(fs::remove(Twine(TempPath2), false),
636             errc::no_such_file_or_directory);
637 
638   std::error_code EC = fs::status(TempPath2.c_str(), B);
639   EXPECT_EQ(EC, errc::no_such_file_or_directory);
640   EXPECT_EQ(B.type(), fs::file_type::file_not_found);
641 
642   // Make sure Temp2 doesn't exist.
643   ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist),
644             errc::no_such_file_or_directory);
645 
646   SmallString<64> TempPath3;
647   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3));
648   ASSERT_FALSE(TempPath3.endswith("."));
649   FileRemover Cleanup3(TempPath3);
650 
651   // Create a hard link to Temp1.
652   ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2)));
653   bool equal;
654   ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal));
655   EXPECT_TRUE(equal);
656   ASSERT_NO_ERROR(fs::status(Twine(TempPath), A));
657   ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B));
658   EXPECT_TRUE(fs::equivalent(A, B));
659 
660   // Remove Temp1.
661   ::close(FileDescriptor);
662   ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
663 
664   // Remove the hard link.
665   ASSERT_NO_ERROR(fs::remove(Twine(TempPath2)));
666 
667   // Make sure Temp1 doesn't exist.
668   ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist),
669             errc::no_such_file_or_directory);
670 
671 #ifdef _WIN32
672   // Path name > 260 chars should get an error.
673   const char *Path270 =
674     "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8"
675     "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
676     "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
677     "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
678     "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
679   EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath),
680             errc::invalid_argument);
681   // Relative path < 247 chars, no problem.
682   const char *Path216 =
683     "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6"
684     "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4"
685     "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2"
686     "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0";
687   ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath));
688   ASSERT_NO_ERROR(fs::remove(Twine(TempPath)));
689 #endif
690 }
691 
692 TEST_F(FileSystemTest, TempFileCollisions) {
693   SmallString<128> TestDirectory;
694   ASSERT_NO_ERROR(
695       fs::createUniqueDirectory("CreateUniqueFileTest", TestDirectory));
696   FileRemover Cleanup(TestDirectory);
697   SmallString<128> Model = TestDirectory;
698   path::append(Model, "%.tmp");
699   SmallString<128> Path;
700   std::vector<fs::TempFile> TempFiles;
701 
702   auto TryCreateTempFile = [&]() {
703     Expected<fs::TempFile> T = fs::TempFile::create(Model);
704     if (T) {
705       TempFiles.push_back(std::move(*T));
706       return true;
707     } else {
708       logAllUnhandledErrors(T.takeError(), errs(),
709                             "Failed to create temporary file: ");
710       return false;
711     }
712   };
713 
714   // Our single-character template allows for 16 unique names. Check that
715   // calling TryCreateTempFile repeatedly results in 16 successes.
716   // Because the test depends on random numbers, it could theoretically fail.
717   // However, the probability of this happening is tiny: with 32 calls, each
718   // of which will retry up to 128 times, to not get a given digit we would
719   // have to fail at least 15 + 17 * 128 = 2191 attempts. The probability of
720   // 2191 attempts not producing a given hexadecimal digit is
721   // (1 - 1/16) ** 2191 or 3.88e-62.
722   int Successes = 0;
723   for (int i = 0; i < 32; ++i)
724     if (TryCreateTempFile()) ++Successes;
725   EXPECT_EQ(Successes, 16);
726 
727   for (fs::TempFile &T : TempFiles)
728     cantFail(T.discard());
729 }
730 
731 TEST_F(FileSystemTest, CreateDir) {
732   ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
733   ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo"));
734   ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false),
735             errc::file_exists);
736   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo"));
737 
738 #ifdef LLVM_ON_UNIX
739   // Set a 0000 umask so that we can test our directory permissions.
740   mode_t OldUmask = ::umask(0000);
741 
742   fs::file_status Status;
743   ASSERT_NO_ERROR(
744       fs::create_directory(Twine(TestDirectory) + "baz500", false,
745                            fs::perms::owner_read | fs::perms::owner_exe));
746   ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz500", Status));
747   ASSERT_EQ(Status.permissions() & fs::perms::all_all,
748             fs::perms::owner_read | fs::perms::owner_exe);
749   ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "baz777", false,
750                                        fs::perms::all_all));
751   ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz777", Status));
752   ASSERT_EQ(Status.permissions() & fs::perms::all_all, fs::perms::all_all);
753 
754   // Restore umask to be safe.
755   ::umask(OldUmask);
756 #endif
757 
758 #ifdef _WIN32
759   // Prove that create_directories() can handle a pathname > 248 characters,
760   // which is the documented limit for CreateDirectory().
761   // (248 is MAX_PATH subtracting room for an 8.3 filename.)
762   // Generate a directory path guaranteed to fall into that range.
763   size_t TmpLen = TestDirectory.size();
764   const char *OneDir = "\\123456789";
765   size_t OneDirLen = strlen(OneDir);
766   ASSERT_LT(OneDirLen, 12U);
767   size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1;
768   SmallString<260> LongDir(TestDirectory);
769   for (size_t I = 0; I < NLevels; ++I)
770     LongDir.append(OneDir);
771   ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
772   ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir)));
773   ASSERT_EQ(fs::create_directories(Twine(LongDir), false),
774             errc::file_exists);
775   // Tidy up, "recursively" removing the directories.
776   StringRef ThisDir(LongDir);
777   for (size_t J = 0; J < NLevels; ++J) {
778     ASSERT_NO_ERROR(fs::remove(ThisDir));
779     ThisDir = path::parent_path(ThisDir);
780   }
781 
782   // Also verify that paths with Unix separators are handled correctly.
783   std::string LongPathWithUnixSeparators(TestDirectory.str());
784   // Add at least one subdirectory to TestDirectory, and replace slashes with
785   // backslashes
786   do {
787     LongPathWithUnixSeparators.append("/DirNameWith19Charss");
788   } while (LongPathWithUnixSeparators.size() < 260);
789   std::replace(LongPathWithUnixSeparators.begin(),
790                LongPathWithUnixSeparators.end(),
791                '\\', '/');
792   ASSERT_NO_ERROR(fs::create_directories(Twine(LongPathWithUnixSeparators)));
793   // cleanup
794   ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) +
795                                          "/DirNameWith19Charss"));
796 
797   // Similarly for a relative pathname.  Need to set the current directory to
798   // TestDirectory so that the one we create ends up in the right place.
799   char PreviousDir[260];
800   size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir);
801   ASSERT_GT(PreviousDirLen, 0U);
802   ASSERT_LT(PreviousDirLen, 260U);
803   ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0);
804   LongDir.clear();
805   // Generate a relative directory name with absolute length > 248.
806   size_t LongDirLen = 249 - TestDirectory.size();
807   LongDir.assign(LongDirLen, 'a');
808   ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir)));
809   // While we're here, prove that .. and . handling works in these long paths.
810   const char *DotDotDirs = "\\..\\.\\b";
811   LongDir.append(DotDotDirs);
812   ASSERT_NO_ERROR(fs::create_directory("b"));
813   ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists);
814   // And clean up.
815   ASSERT_NO_ERROR(fs::remove("b"));
816   ASSERT_NO_ERROR(fs::remove(
817     Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs)))));
818   ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0);
819 #endif
820 }
821 
822 TEST_F(FileSystemTest, DirectoryIteration) {
823   std::error_code ec;
824   for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec))
825     ASSERT_NO_ERROR(ec);
826 
827   // Create a known hierarchy to recurse over.
828   ASSERT_NO_ERROR(
829       fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1"));
830   ASSERT_NO_ERROR(
831       fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1"));
832   ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) +
833                                          "/recursive/dontlookhere/da1"));
834   ASSERT_NO_ERROR(
835       fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1"));
836   ASSERT_NO_ERROR(
837       fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1"));
838   typedef std::vector<std::string> v_t;
839   v_t visited;
840   for (fs::recursive_directory_iterator i(Twine(TestDirectory)
841          + "/recursive", ec), e; i != e; i.increment(ec)){
842     ASSERT_NO_ERROR(ec);
843     if (path::filename(i->path()) == "p1") {
844       i.pop();
845       // FIXME: recursive_directory_iterator should be more robust.
846       if (i == e) break;
847     }
848     if (path::filename(i->path()) == "dontlookhere")
849       i.no_push();
850     visited.push_back(path::filename(i->path()));
851   }
852   v_t::const_iterator a0 = find(visited, "a0");
853   v_t::const_iterator aa1 = find(visited, "aa1");
854   v_t::const_iterator ab1 = find(visited, "ab1");
855   v_t::const_iterator dontlookhere = find(visited, "dontlookhere");
856   v_t::const_iterator da1 = find(visited, "da1");
857   v_t::const_iterator z0 = find(visited, "z0");
858   v_t::const_iterator za1 = find(visited, "za1");
859   v_t::const_iterator pop = find(visited, "pop");
860   v_t::const_iterator p1 = find(visited, "p1");
861 
862   // Make sure that each path was visited correctly.
863   ASSERT_NE(a0, visited.end());
864   ASSERT_NE(aa1, visited.end());
865   ASSERT_NE(ab1, visited.end());
866   ASSERT_NE(dontlookhere, visited.end());
867   ASSERT_EQ(da1, visited.end()); // Not visited.
868   ASSERT_NE(z0, visited.end());
869   ASSERT_NE(za1, visited.end());
870   ASSERT_NE(pop, visited.end());
871   ASSERT_EQ(p1, visited.end()); // Not visited.
872 
873   // Make sure that parents were visited before children. No other ordering
874   // guarantees can be made across siblings.
875   ASSERT_LT(a0, aa1);
876   ASSERT_LT(a0, ab1);
877   ASSERT_LT(z0, za1);
878 
879   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1"));
880   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1"));
881   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0"));
882   ASSERT_NO_ERROR(
883       fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1"));
884   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere"));
885   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1"));
886   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop"));
887   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1"));
888   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0"));
889   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive"));
890 
891   // Test recursive_directory_iterator level()
892   ASSERT_NO_ERROR(
893       fs::create_directories(Twine(TestDirectory) + "/reclevel/a/b/c"));
894   fs::recursive_directory_iterator I(Twine(TestDirectory) + "/reclevel", ec), E;
895   for (int l = 0; I != E; I.increment(ec), ++l) {
896     ASSERT_NO_ERROR(ec);
897     EXPECT_EQ(I.level(), l);
898   }
899   EXPECT_EQ(I, E);
900   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b/c"));
901   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b"));
902   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a"));
903   ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel"));
904 }
905 
906 #ifdef LLVM_ON_UNIX
907 TEST_F(FileSystemTest, BrokenSymlinkDirectoryIteration) {
908   // Create a known hierarchy to recurse over.
909   ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + "/symlink"));
910   ASSERT_NO_ERROR(
911       fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/a"));
912   ASSERT_NO_ERROR(
913       fs::create_directories(Twine(TestDirectory) + "/symlink/b/bb"));
914   ASSERT_NO_ERROR(
915       fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/ba"));
916   ASSERT_NO_ERROR(
917       fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/bc"));
918   ASSERT_NO_ERROR(
919       fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/c"));
920   ASSERT_NO_ERROR(
921       fs::create_directories(Twine(TestDirectory) + "/symlink/d/dd/ddd"));
922   ASSERT_NO_ERROR(fs::create_link(Twine(TestDirectory) + "/symlink/d/dd",
923                                   Twine(TestDirectory) + "/symlink/d/da"));
924   ASSERT_NO_ERROR(
925       fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/e"));
926 
927   typedef std::vector<std::string> v_t;
928   v_t VisitedNonBrokenSymlinks;
929   v_t VisitedBrokenSymlinks;
930   std::error_code ec;
931   using testing::UnorderedElementsAre;
932   using testing::UnorderedElementsAreArray;
933 
934   // Broken symbol links are expected to throw an error.
935   for (fs::directory_iterator i(Twine(TestDirectory) + "/symlink", ec), e;
936        i != e; i.increment(ec)) {
937     ASSERT_NO_ERROR(ec);
938     if (i->status().getError() ==
939         std::make_error_code(std::errc::no_such_file_or_directory)) {
940       VisitedBrokenSymlinks.push_back(path::filename(i->path()));
941       continue;
942     }
943     VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
944   }
945   EXPECT_THAT(VisitedNonBrokenSymlinks, UnorderedElementsAre("b", "d"));
946   VisitedNonBrokenSymlinks.clear();
947 
948   EXPECT_THAT(VisitedBrokenSymlinks, UnorderedElementsAre("a", "c", "e"));
949   VisitedBrokenSymlinks.clear();
950 
951   // Broken symbol links are expected to throw an error.
952   for (fs::recursive_directory_iterator i(
953       Twine(TestDirectory) + "/symlink", ec), e; i != e; i.increment(ec)) {
954     ASSERT_NO_ERROR(ec);
955     if (i->status().getError() ==
956         std::make_error_code(std::errc::no_such_file_or_directory)) {
957       VisitedBrokenSymlinks.push_back(path::filename(i->path()));
958       continue;
959     }
960     VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
961   }
962   EXPECT_THAT(VisitedNonBrokenSymlinks,
963               UnorderedElementsAre("b", "bb", "d", "da", "dd", "ddd", "ddd"));
964   VisitedNonBrokenSymlinks.clear();
965 
966   EXPECT_THAT(VisitedBrokenSymlinks,
967               UnorderedElementsAre("a", "ba", "bc", "c", "e"));
968   VisitedBrokenSymlinks.clear();
969 
970   for (fs::recursive_directory_iterator i(
971       Twine(TestDirectory) + "/symlink", ec, /*follow_symlinks=*/false), e;
972        i != e; i.increment(ec)) {
973     ASSERT_NO_ERROR(ec);
974     if (i->status().getError() ==
975         std::make_error_code(std::errc::no_such_file_or_directory)) {
976       VisitedBrokenSymlinks.push_back(path::filename(i->path()));
977       continue;
978     }
979     VisitedNonBrokenSymlinks.push_back(path::filename(i->path()));
980   }
981   EXPECT_THAT(VisitedNonBrokenSymlinks,
982               UnorderedElementsAreArray({"a", "b", "ba", "bb", "bc", "c", "d",
983                                          "da", "dd", "ddd", "e"}));
984   VisitedNonBrokenSymlinks.clear();
985 
986   EXPECT_THAT(VisitedBrokenSymlinks, UnorderedElementsAre());
987   VisitedBrokenSymlinks.clear();
988 
989   ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/symlink"));
990 }
991 #endif
992 
993 TEST_F(FileSystemTest, Remove) {
994   SmallString<64> BaseDir;
995   SmallString<64> Paths[4];
996   int fds[4];
997   ASSERT_NO_ERROR(fs::createUniqueDirectory("fs_remove", BaseDir));
998 
999   ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/baz"));
1000   ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/buzz"));
1001   ASSERT_NO_ERROR(fs::createUniqueFile(
1002       Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[0], Paths[0]));
1003   ASSERT_NO_ERROR(fs::createUniqueFile(
1004       Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[1], Paths[1]));
1005   ASSERT_NO_ERROR(fs::createUniqueFile(
1006       Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[2], Paths[2]));
1007   ASSERT_NO_ERROR(fs::createUniqueFile(
1008       Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[3], Paths[3]));
1009 
1010   for (int fd : fds)
1011     ::close(fd);
1012 
1013   EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/baz"));
1014   EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/buzz"));
1015   EXPECT_TRUE(fs::exists(Paths[0]));
1016   EXPECT_TRUE(fs::exists(Paths[1]));
1017   EXPECT_TRUE(fs::exists(Paths[2]));
1018   EXPECT_TRUE(fs::exists(Paths[3]));
1019 
1020   ASSERT_NO_ERROR(fs::remove_directories("D:/footest"));
1021 
1022   ASSERT_NO_ERROR(fs::remove_directories(BaseDir));
1023   ASSERT_FALSE(fs::exists(BaseDir));
1024 }
1025 
1026 #ifdef _WIN32
1027 TEST_F(FileSystemTest, CarriageReturn) {
1028   SmallString<128> FilePathname(TestDirectory);
1029   std::error_code EC;
1030   path::append(FilePathname, "test");
1031 
1032   {
1033     raw_fd_ostream File(FilePathname, EC, sys::fs::OF_Text);
1034     ASSERT_NO_ERROR(EC);
1035     File << '\n';
1036   }
1037   {
1038     auto Buf = MemoryBuffer::getFile(FilePathname.str());
1039     EXPECT_TRUE((bool)Buf);
1040     EXPECT_EQ(Buf.get()->getBuffer(), "\r\n");
1041   }
1042 
1043   {
1044     raw_fd_ostream File(FilePathname, EC, sys::fs::OF_None);
1045     ASSERT_NO_ERROR(EC);
1046     File << '\n';
1047   }
1048   {
1049     auto Buf = MemoryBuffer::getFile(FilePathname.str());
1050     EXPECT_TRUE((bool)Buf);
1051     EXPECT_EQ(Buf.get()->getBuffer(), "\n");
1052   }
1053   ASSERT_NO_ERROR(fs::remove(Twine(FilePathname)));
1054 }
1055 #endif
1056 
1057 TEST_F(FileSystemTest, Resize) {
1058   int FD;
1059   SmallString<64> TempPath;
1060   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
1061   ASSERT_NO_ERROR(fs::resize_file(FD, 123));
1062   fs::file_status Status;
1063   ASSERT_NO_ERROR(fs::status(FD, Status));
1064   ASSERT_EQ(Status.getSize(), 123U);
1065   ::close(FD);
1066   ASSERT_NO_ERROR(fs::remove(TempPath));
1067 }
1068 
1069 TEST_F(FileSystemTest, MD5) {
1070   int FD;
1071   SmallString<64> TempPath;
1072   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
1073   StringRef Data("abcdefghijklmnopqrstuvwxyz");
1074   ASSERT_EQ(write(FD, Data.data(), Data.size()), static_cast<ssize_t>(Data.size()));
1075   lseek(FD, 0, SEEK_SET);
1076   auto Hash = fs::md5_contents(FD);
1077   ::close(FD);
1078   ASSERT_NO_ERROR(Hash.getError());
1079 
1080   EXPECT_STREQ("c3fcd3d76192e4007dfb496cca67e13b", Hash->digest().c_str());
1081 }
1082 
1083 TEST_F(FileSystemTest, FileMapping) {
1084   // Create a temp file.
1085   int FileDescriptor;
1086   SmallString<64> TempPath;
1087   ASSERT_NO_ERROR(
1088       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
1089   unsigned Size = 4096;
1090   ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size));
1091 
1092   // Map in temp file and add some content
1093   std::error_code EC;
1094   StringRef Val("hello there");
1095   {
1096     fs::mapped_file_region mfr(fs::convertFDToNativeFile(FileDescriptor),
1097                                fs::mapped_file_region::readwrite, Size, 0, EC);
1098     ASSERT_NO_ERROR(EC);
1099     std::copy(Val.begin(), Val.end(), mfr.data());
1100     // Explicitly add a 0.
1101     mfr.data()[Val.size()] = 0;
1102     // Unmap temp file
1103   }
1104   ASSERT_EQ(close(FileDescriptor), 0);
1105 
1106   // Map it back in read-only
1107   {
1108     int FD;
1109     EC = fs::openFileForRead(Twine(TempPath), FD);
1110     ASSERT_NO_ERROR(EC);
1111     fs::mapped_file_region mfr(fs::convertFDToNativeFile(FD),
1112                                fs::mapped_file_region::readonly, Size, 0, EC);
1113     ASSERT_NO_ERROR(EC);
1114 
1115     // Verify content
1116     EXPECT_EQ(StringRef(mfr.const_data()), Val);
1117 
1118     // Unmap temp file
1119     fs::mapped_file_region m(fs::convertFDToNativeFile(FD),
1120                              fs::mapped_file_region::readonly, Size, 0, EC);
1121     ASSERT_NO_ERROR(EC);
1122     ASSERT_EQ(close(FD), 0);
1123   }
1124   ASSERT_NO_ERROR(fs::remove(TempPath));
1125 }
1126 
1127 TEST(Support, NormalizePath) {
1128   using TestTuple = std::tuple<const char *, const char *, const char *>;
1129   std::vector<TestTuple> Tests;
1130   Tests.emplace_back("a", "a", "a");
1131   Tests.emplace_back("a/b", "a\\b", "a/b");
1132   Tests.emplace_back("a\\b", "a\\b", "a/b");
1133   Tests.emplace_back("a\\\\b", "a\\\\b", "a\\\\b");
1134   Tests.emplace_back("\\a", "\\a", "/a");
1135   Tests.emplace_back("a\\", "a\\", "a/");
1136 
1137   for (auto &T : Tests) {
1138     SmallString<64> Win(std::get<0>(T));
1139     SmallString<64> Posix(Win);
1140     path::native(Win, path::Style::windows);
1141     path::native(Posix, path::Style::posix);
1142     EXPECT_EQ(std::get<1>(T), Win);
1143     EXPECT_EQ(std::get<2>(T), Posix);
1144   }
1145 
1146 #if defined(_WIN32)
1147   SmallString<64> PathHome;
1148   path::home_directory(PathHome);
1149 
1150   const char *Path7a = "~/aaa";
1151   SmallString<64> Path7(Path7a);
1152   path::native(Path7);
1153   EXPECT_TRUE(Path7.endswith("\\aaa"));
1154   EXPECT_TRUE(Path7.startswith(PathHome));
1155   EXPECT_EQ(Path7.size(), PathHome.size() + strlen(Path7a + 1));
1156 
1157   const char *Path8a = "~";
1158   SmallString<64> Path8(Path8a);
1159   path::native(Path8);
1160   EXPECT_EQ(Path8, PathHome);
1161 
1162   const char *Path9a = "~aaa";
1163   SmallString<64> Path9(Path9a);
1164   path::native(Path9);
1165   EXPECT_EQ(Path9, "~aaa");
1166 
1167   const char *Path10a = "aaa/~/b";
1168   SmallString<64> Path10(Path10a);
1169   path::native(Path10);
1170   EXPECT_EQ(Path10, "aaa\\~\\b");
1171 #endif
1172 }
1173 
1174 TEST(Support, RemoveLeadingDotSlash) {
1175   StringRef Path1("././/foolz/wat");
1176   StringRef Path2("./////");
1177 
1178   Path1 = path::remove_leading_dotslash(Path1);
1179   EXPECT_EQ(Path1, "foolz/wat");
1180   Path2 = path::remove_leading_dotslash(Path2);
1181   EXPECT_EQ(Path2, "");
1182 }
1183 
1184 static std::string remove_dots(StringRef path, bool remove_dot_dot,
1185                                path::Style style) {
1186   SmallString<256> buffer(path);
1187   path::remove_dots(buffer, remove_dot_dot, style);
1188   return buffer.str();
1189 }
1190 
1191 TEST(Support, RemoveDots) {
1192   EXPECT_EQ("foolz\\wat",
1193             remove_dots(".\\.\\\\foolz\\wat", false, path::Style::windows));
1194   EXPECT_EQ("", remove_dots(".\\\\\\\\\\", false, path::Style::windows));
1195 
1196   EXPECT_EQ("a\\..\\b\\c",
1197             remove_dots(".\\a\\..\\b\\c", false, path::Style::windows));
1198   EXPECT_EQ("b\\c", remove_dots(".\\a\\..\\b\\c", true, path::Style::windows));
1199   EXPECT_EQ("c", remove_dots(".\\.\\c", true, path::Style::windows));
1200   EXPECT_EQ("..\\a\\c",
1201             remove_dots("..\\a\\b\\..\\c", true, path::Style::windows));
1202   EXPECT_EQ("..\\..\\a\\c",
1203             remove_dots("..\\..\\a\\b\\..\\c", true, path::Style::windows));
1204 
1205   SmallString<64> Path1(".\\.\\c");
1206   EXPECT_TRUE(path::remove_dots(Path1, true, path::Style::windows));
1207   EXPECT_EQ("c", Path1);
1208 
1209   EXPECT_EQ("foolz/wat",
1210             remove_dots("././/foolz/wat", false, path::Style::posix));
1211   EXPECT_EQ("", remove_dots("./////", false, path::Style::posix));
1212 
1213   EXPECT_EQ("a/../b/c", remove_dots("./a/../b/c", false, path::Style::posix));
1214   EXPECT_EQ("b/c", remove_dots("./a/../b/c", true, path::Style::posix));
1215   EXPECT_EQ("c", remove_dots("././c", true, path::Style::posix));
1216   EXPECT_EQ("../a/c", remove_dots("../a/b/../c", true, path::Style::posix));
1217   EXPECT_EQ("../../a/c",
1218             remove_dots("../../a/b/../c", true, path::Style::posix));
1219   EXPECT_EQ("/a/c", remove_dots("/../../a/c", true, path::Style::posix));
1220   EXPECT_EQ("/a/c",
1221             remove_dots("/../a/b//../././/c", true, path::Style::posix));
1222 
1223   SmallString<64> Path2("././c");
1224   EXPECT_TRUE(path::remove_dots(Path2, true, path::Style::posix));
1225   EXPECT_EQ("c", Path2);
1226 }
1227 
1228 TEST(Support, ReplacePathPrefix) {
1229   SmallString<64> Path1("/foo");
1230   SmallString<64> Path2("/old/foo");
1231   SmallString<64> OldPrefix("/old");
1232   SmallString<64> NewPrefix("/new");
1233   SmallString<64> NewPrefix2("/longernew");
1234   SmallString<64> EmptyPrefix("");
1235 
1236   SmallString<64> Path = Path1;
1237   path::replace_path_prefix(Path, OldPrefix, NewPrefix);
1238   EXPECT_EQ(Path, "/foo");
1239   Path = Path2;
1240   path::replace_path_prefix(Path, OldPrefix, NewPrefix);
1241   EXPECT_EQ(Path, "/new/foo");
1242   Path = Path2;
1243   path::replace_path_prefix(Path, OldPrefix, NewPrefix2);
1244   EXPECT_EQ(Path, "/longernew/foo");
1245   Path = Path1;
1246   path::replace_path_prefix(Path, EmptyPrefix, NewPrefix);
1247   EXPECT_EQ(Path, "/new/foo");
1248   Path = Path2;
1249   path::replace_path_prefix(Path, OldPrefix, EmptyPrefix);
1250   EXPECT_EQ(Path, "/foo");
1251 }
1252 
1253 TEST_F(FileSystemTest, OpenFileForRead) {
1254   // Create a temp file.
1255   int FileDescriptor;
1256   SmallString<64> TempPath;
1257   ASSERT_NO_ERROR(
1258       fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath));
1259   FileRemover Cleanup(TempPath);
1260 
1261   // Make sure it exists.
1262   ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1263 
1264   // Open the file for read
1265   int FileDescriptor2;
1266   SmallString<64> ResultPath;
1267   ASSERT_NO_ERROR(fs::openFileForRead(Twine(TempPath), FileDescriptor2,
1268                                       fs::OF_None, &ResultPath))
1269 
1270   // If we succeeded, check that the paths are the same (modulo case):
1271   if (!ResultPath.empty()) {
1272     // The paths returned by createTemporaryFile and getPathFromOpenFD
1273     // should reference the same file on disk.
1274     fs::UniqueID D1, D2;
1275     ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1));
1276     ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2));
1277     ASSERT_EQ(D1, D2);
1278   }
1279   ::close(FileDescriptor);
1280   ::close(FileDescriptor2);
1281 
1282 #ifdef _WIN32
1283   // Since Windows Vista, file access time is not updated by default.
1284   // This is instead updated manually by openFileForRead.
1285   // https://blogs.technet.microsoft.com/filecab/2006/11/07/disabling-last-access-time-in-windows-vista-to-improve-ntfs-performance/
1286   // This part of the unit test is Windows specific as the updating of
1287   // access times can be disabled on Linux using /etc/fstab.
1288 
1289   // Set access time to UNIX epoch.
1290   ASSERT_NO_ERROR(sys::fs::openFileForWrite(Twine(TempPath), FileDescriptor,
1291                                             fs::CD_OpenExisting));
1292   TimePoint<> Epoch(std::chrono::milliseconds(0));
1293   ASSERT_NO_ERROR(fs::setLastAccessAndModificationTime(FileDescriptor, Epoch));
1294   ::close(FileDescriptor);
1295 
1296   // Open the file and ensure access time is updated, when forced.
1297   ASSERT_NO_ERROR(fs::openFileForRead(Twine(TempPath), FileDescriptor,
1298                                       fs::OF_UpdateAtime, &ResultPath));
1299 
1300   sys::fs::file_status Status;
1301   ASSERT_NO_ERROR(sys::fs::status(FileDescriptor, Status));
1302   auto FileAccessTime = Status.getLastAccessedTime();
1303 
1304   ASSERT_NE(Epoch, FileAccessTime);
1305   ::close(FileDescriptor);
1306 
1307   // Ideally this test would include a case when ATime is not forced to update,
1308   // however the expected behaviour will differ depending on the configuration
1309   // of the Windows file system.
1310 #endif
1311 }
1312 
1313 static void createFileWithData(const Twine &Path, bool ShouldExistBefore,
1314                                fs::CreationDisposition Disp, StringRef Data) {
1315   int FD;
1316   ASSERT_EQ(ShouldExistBefore, fs::exists(Path));
1317   ASSERT_NO_ERROR(fs::openFileForWrite(Path, FD, Disp));
1318   FileDescriptorCloser Closer(FD);
1319   ASSERT_TRUE(fs::exists(Path));
1320 
1321   ASSERT_EQ(Data.size(), (size_t)write(FD, Data.data(), Data.size()));
1322 }
1323 
1324 static void verifyFileContents(const Twine &Path, StringRef Contents) {
1325   auto Buffer = MemoryBuffer::getFile(Path);
1326   ASSERT_TRUE((bool)Buffer);
1327   StringRef Data = Buffer.get()->getBuffer();
1328   ASSERT_EQ(Data, Contents);
1329 }
1330 
1331 TEST_F(FileSystemTest, CreateNew) {
1332   int FD;
1333   Optional<FileDescriptorCloser> Closer;
1334 
1335   // Succeeds if the file does not exist.
1336   ASSERT_FALSE(fs::exists(NonExistantFile));
1337   ASSERT_NO_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateNew));
1338   ASSERT_TRUE(fs::exists(NonExistantFile));
1339 
1340   FileRemover Cleanup(NonExistantFile);
1341   Closer.emplace(FD);
1342 
1343   // And creates a file of size 0.
1344   sys::fs::file_status Status;
1345   ASSERT_NO_ERROR(sys::fs::status(FD, Status));
1346   EXPECT_EQ(0ULL, Status.getSize());
1347 
1348   // Close this first, before trying to re-open the file.
1349   Closer.reset();
1350 
1351   // But fails if the file does exist.
1352   ASSERT_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateNew));
1353 }
1354 
1355 TEST_F(FileSystemTest, CreateAlways) {
1356   int FD;
1357   Optional<FileDescriptorCloser> Closer;
1358 
1359   // Succeeds if the file does not exist.
1360   ASSERT_FALSE(fs::exists(NonExistantFile));
1361   ASSERT_NO_ERROR(
1362       fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateAlways));
1363 
1364   Closer.emplace(FD);
1365 
1366   ASSERT_TRUE(fs::exists(NonExistantFile));
1367 
1368   FileRemover Cleanup(NonExistantFile);
1369 
1370   // And creates a file of size 0.
1371   uint64_t FileSize;
1372   ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1373   ASSERT_EQ(0ULL, FileSize);
1374 
1375   // If we write some data to it re-create it with CreateAlways, it succeeds and
1376   // truncates to 0 bytes.
1377   ASSERT_EQ(4, write(FD, "Test", 4));
1378 
1379   Closer.reset();
1380 
1381   ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1382   ASSERT_EQ(4ULL, FileSize);
1383 
1384   ASSERT_NO_ERROR(
1385       fs::openFileForWrite(NonExistantFile, FD, fs::CD_CreateAlways));
1386   Closer.emplace(FD);
1387   ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1388   ASSERT_EQ(0ULL, FileSize);
1389 }
1390 
1391 TEST_F(FileSystemTest, OpenExisting) {
1392   int FD;
1393 
1394   // Fails if the file does not exist.
1395   ASSERT_FALSE(fs::exists(NonExistantFile));
1396   ASSERT_ERROR(fs::openFileForWrite(NonExistantFile, FD, fs::CD_OpenExisting));
1397   ASSERT_FALSE(fs::exists(NonExistantFile));
1398 
1399   // Make a dummy file now so that we can try again when the file does exist.
1400   createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
1401   FileRemover Cleanup(NonExistantFile);
1402   uint64_t FileSize;
1403   ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1404   ASSERT_EQ(4ULL, FileSize);
1405 
1406   // If we re-create it with different data, it overwrites rather than
1407   // appending.
1408   createFileWithData(NonExistantFile, true, fs::CD_OpenExisting, "Buzz");
1409   verifyFileContents(NonExistantFile, "Buzz");
1410 }
1411 
1412 TEST_F(FileSystemTest, OpenAlways) {
1413   // Succeeds if the file does not exist.
1414   createFileWithData(NonExistantFile, false, fs::CD_OpenAlways, "Fizz");
1415   FileRemover Cleanup(NonExistantFile);
1416   uint64_t FileSize;
1417   ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1418   ASSERT_EQ(4ULL, FileSize);
1419 
1420   // Now re-open it and write again, verifying the contents get over-written.
1421   createFileWithData(NonExistantFile, true, fs::CD_OpenAlways, "Bu");
1422   verifyFileContents(NonExistantFile, "Buzz");
1423 }
1424 
1425 TEST_F(FileSystemTest, AppendSetsCorrectFileOffset) {
1426   fs::CreationDisposition Disps[] = {fs::CD_CreateAlways, fs::CD_OpenAlways,
1427                                      fs::CD_OpenExisting};
1428 
1429   // Write some data and re-open it with every possible disposition (this is a
1430   // hack that shouldn't work, but is left for compatibility.  OF_Append
1431   // overrides
1432   // the specified disposition.
1433   for (fs::CreationDisposition Disp : Disps) {
1434     int FD;
1435     Optional<FileDescriptorCloser> Closer;
1436 
1437     createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
1438 
1439     FileRemover Cleanup(NonExistantFile);
1440 
1441     uint64_t FileSize;
1442     ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1443     ASSERT_EQ(4ULL, FileSize);
1444     ASSERT_NO_ERROR(
1445         fs::openFileForWrite(NonExistantFile, FD, Disp, fs::OF_Append));
1446     Closer.emplace(FD);
1447     ASSERT_NO_ERROR(sys::fs::file_size(NonExistantFile, FileSize));
1448     ASSERT_EQ(4ULL, FileSize);
1449 
1450     ASSERT_EQ(4, write(FD, "Buzz", 4));
1451     Closer.reset();
1452 
1453     verifyFileContents(NonExistantFile, "FizzBuzz");
1454   }
1455 }
1456 
1457 static void verifyRead(int FD, StringRef Data, bool ShouldSucceed) {
1458   std::vector<char> Buffer;
1459   Buffer.resize(Data.size());
1460   int Result = ::read(FD, Buffer.data(), Buffer.size());
1461   if (ShouldSucceed) {
1462     ASSERT_EQ((size_t)Result, Data.size());
1463     ASSERT_EQ(Data, StringRef(Buffer.data(), Buffer.size()));
1464   } else {
1465     ASSERT_EQ(-1, Result);
1466     ASSERT_EQ(EBADF, errno);
1467   }
1468 }
1469 
1470 static void verifyWrite(int FD, StringRef Data, bool ShouldSucceed) {
1471   int Result = ::write(FD, Data.data(), Data.size());
1472   if (ShouldSucceed)
1473     ASSERT_EQ((size_t)Result, Data.size());
1474   else {
1475     ASSERT_EQ(-1, Result);
1476     ASSERT_EQ(EBADF, errno);
1477   }
1478 }
1479 
1480 TEST_F(FileSystemTest, ReadOnlyFileCantWrite) {
1481   createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
1482   FileRemover Cleanup(NonExistantFile);
1483 
1484   int FD;
1485   ASSERT_NO_ERROR(fs::openFileForRead(NonExistantFile, FD));
1486   FileDescriptorCloser Closer(FD);
1487 
1488   verifyWrite(FD, "Buzz", false);
1489   verifyRead(FD, "Fizz", true);
1490 }
1491 
1492 TEST_F(FileSystemTest, WriteOnlyFileCantRead) {
1493   createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
1494   FileRemover Cleanup(NonExistantFile);
1495 
1496   int FD;
1497   ASSERT_NO_ERROR(
1498       fs::openFileForWrite(NonExistantFile, FD, fs::CD_OpenExisting));
1499   FileDescriptorCloser Closer(FD);
1500   verifyRead(FD, "Fizz", false);
1501   verifyWrite(FD, "Buzz", true);
1502 }
1503 
1504 TEST_F(FileSystemTest, ReadWriteFileCanReadOrWrite) {
1505   createFileWithData(NonExistantFile, false, fs::CD_CreateNew, "Fizz");
1506   FileRemover Cleanup(NonExistantFile);
1507 
1508   int FD;
1509   ASSERT_NO_ERROR(fs::openFileForReadWrite(NonExistantFile, FD,
1510                                            fs::CD_OpenExisting, fs::OF_None));
1511   FileDescriptorCloser Closer(FD);
1512   verifyRead(FD, "Fizz", true);
1513   verifyWrite(FD, "Buzz", true);
1514 }
1515 
1516 TEST_F(FileSystemTest, is_local) {
1517   bool TestDirectoryIsLocal;
1518   ASSERT_NO_ERROR(fs::is_local(TestDirectory, TestDirectoryIsLocal));
1519   EXPECT_EQ(TestDirectoryIsLocal, fs::is_local(TestDirectory));
1520 
1521   int FD;
1522   SmallString<128> TempPath;
1523   ASSERT_NO_ERROR(
1524       fs::createUniqueFile(Twine(TestDirectory) + "/temp", FD, TempPath));
1525   FileRemover Cleanup(TempPath);
1526 
1527   // Make sure it exists.
1528   ASSERT_TRUE(sys::fs::exists(Twine(TempPath)));
1529 
1530   bool TempFileIsLocal;
1531   ASSERT_NO_ERROR(fs::is_local(FD, TempFileIsLocal));
1532   EXPECT_EQ(TempFileIsLocal, fs::is_local(FD));
1533   ::close(FD);
1534 
1535   // Expect that the file and its parent directory are equally local or equally
1536   // remote.
1537   EXPECT_EQ(TestDirectoryIsLocal, TempFileIsLocal);
1538 }
1539 
1540 TEST_F(FileSystemTest, getUmask) {
1541 #ifdef _WIN32
1542   EXPECT_EQ(fs::getUmask(), 0U) << "Should always be 0 on Windows.";
1543 #else
1544   unsigned OldMask = ::umask(0022);
1545   unsigned CurrentMask = fs::getUmask();
1546   EXPECT_EQ(CurrentMask, 0022U)
1547       << "getUmask() didn't return previously set umask()";
1548   EXPECT_EQ(::umask(OldMask), 0022U) << "getUmask() may have changed umask()";
1549 #endif
1550 }
1551 
1552 TEST_F(FileSystemTest, RespectUmask) {
1553 #ifndef _WIN32
1554   unsigned OldMask = ::umask(0022);
1555 
1556   int FD;
1557   SmallString<128> TempPath;
1558   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
1559 
1560   fs::perms AllRWE = static_cast<fs::perms>(0777);
1561 
1562   ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
1563 
1564   ErrorOr<fs::perms> Perms = fs::getPermissions(TempPath);
1565   ASSERT_TRUE(!!Perms);
1566   EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask by default";
1567 
1568   ASSERT_NO_ERROR(fs::setPermissions(TempPath, AllRWE));
1569 
1570   Perms = fs::getPermissions(TempPath);
1571   ASSERT_TRUE(!!Perms);
1572   EXPECT_EQ(Perms.get(), AllRWE) << "Should have ignored umask";
1573 
1574   ASSERT_NO_ERROR(
1575       fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
1576   Perms = fs::getPermissions(TempPath);
1577   ASSERT_TRUE(!!Perms);
1578   EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0755))
1579       << "Did not respect umask";
1580 
1581   (void)::umask(0057);
1582 
1583   ASSERT_NO_ERROR(
1584       fs::setPermissions(FD, static_cast<fs::perms>(AllRWE & ~fs::getUmask())));
1585   Perms = fs::getPermissions(TempPath);
1586   ASSERT_TRUE(!!Perms);
1587   EXPECT_EQ(Perms.get(), static_cast<fs::perms>(0720))
1588       << "Did not respect umask";
1589 
1590   (void)::umask(OldMask);
1591   (void)::close(FD);
1592 #endif
1593 }
1594 
1595 TEST_F(FileSystemTest, set_current_path) {
1596   SmallString<128> path;
1597 
1598   ASSERT_NO_ERROR(fs::current_path(path));
1599   ASSERT_NE(TestDirectory, path);
1600 
1601   struct RestorePath {
1602     SmallString<128> path;
1603     RestorePath(const SmallString<128> &path) : path(path) {}
1604     ~RestorePath() { fs::set_current_path(path); }
1605   } restore_path(path);
1606 
1607   ASSERT_NO_ERROR(fs::set_current_path(TestDirectory));
1608 
1609   ASSERT_NO_ERROR(fs::current_path(path));
1610 
1611   fs::UniqueID D1, D2;
1612   ASSERT_NO_ERROR(fs::getUniqueID(TestDirectory, D1));
1613   ASSERT_NO_ERROR(fs::getUniqueID(path, D2));
1614   ASSERT_EQ(D1, D2) << "D1: " << TestDirectory << "\nD2: " << path;
1615 }
1616 
1617 TEST_F(FileSystemTest, permissions) {
1618   int FD;
1619   SmallString<64> TempPath;
1620   ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
1621   FileRemover Cleanup(TempPath);
1622 
1623   // Make sure it exists.
1624   ASSERT_TRUE(fs::exists(Twine(TempPath)));
1625 
1626   auto CheckPermissions = [&](fs::perms Expected) {
1627     ErrorOr<fs::perms> Actual = fs::getPermissions(TempPath);
1628     return Actual && *Actual == Expected;
1629   };
1630 
1631   std::error_code NoError;
1632   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_all), NoError);
1633   EXPECT_TRUE(CheckPermissions(fs::all_all));
1634 
1635   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::all_exe), NoError);
1636   EXPECT_TRUE(CheckPermissions(fs::all_read | fs::all_exe));
1637 
1638 #if defined(_WIN32)
1639   fs::perms ReadOnly = fs::all_read | fs::all_exe;
1640   EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError);
1641   EXPECT_TRUE(CheckPermissions(ReadOnly));
1642 
1643   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError);
1644   EXPECT_TRUE(CheckPermissions(ReadOnly));
1645 
1646   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError);
1647   EXPECT_TRUE(CheckPermissions(fs::all_all));
1648 
1649   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError);
1650   EXPECT_TRUE(CheckPermissions(ReadOnly));
1651 
1652   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError);
1653   EXPECT_TRUE(CheckPermissions(fs::all_all));
1654 
1655   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError);
1656   EXPECT_TRUE(CheckPermissions(ReadOnly));
1657 
1658   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError);
1659   EXPECT_TRUE(CheckPermissions(fs::all_all));
1660 
1661   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError);
1662   EXPECT_TRUE(CheckPermissions(ReadOnly));
1663 
1664   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError);
1665   EXPECT_TRUE(CheckPermissions(fs::all_all));
1666 
1667   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError);
1668   EXPECT_TRUE(CheckPermissions(ReadOnly));
1669 
1670   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError);
1671   EXPECT_TRUE(CheckPermissions(fs::all_all));
1672 
1673   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError);
1674   EXPECT_TRUE(CheckPermissions(ReadOnly));
1675 
1676   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError);
1677   EXPECT_TRUE(CheckPermissions(fs::all_all));
1678 
1679   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError);
1680   EXPECT_TRUE(CheckPermissions(ReadOnly));
1681 
1682   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError);
1683   EXPECT_TRUE(CheckPermissions(fs::all_all));
1684 
1685   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError);
1686   EXPECT_TRUE(CheckPermissions(ReadOnly));
1687 
1688   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError);
1689   EXPECT_TRUE(CheckPermissions(ReadOnly));
1690 
1691   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError);
1692   EXPECT_TRUE(CheckPermissions(ReadOnly));
1693 
1694   EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
1695   EXPECT_TRUE(CheckPermissions(ReadOnly));
1696 
1697   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe |
1698                                              fs::set_gid_on_exe |
1699                                              fs::sticky_bit),
1700             NoError);
1701   EXPECT_TRUE(CheckPermissions(ReadOnly));
1702 
1703   EXPECT_EQ(fs::setPermissions(TempPath, ReadOnly | fs::set_uid_on_exe |
1704                                              fs::set_gid_on_exe |
1705                                              fs::sticky_bit),
1706             NoError);
1707   EXPECT_TRUE(CheckPermissions(ReadOnly));
1708 
1709   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError);
1710   EXPECT_TRUE(CheckPermissions(fs::all_all));
1711 #else
1712   EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError);
1713   EXPECT_TRUE(CheckPermissions(fs::no_perms));
1714 
1715   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError);
1716   EXPECT_TRUE(CheckPermissions(fs::owner_read));
1717 
1718   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError);
1719   EXPECT_TRUE(CheckPermissions(fs::owner_write));
1720 
1721   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError);
1722   EXPECT_TRUE(CheckPermissions(fs::owner_exe));
1723 
1724   EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError);
1725   EXPECT_TRUE(CheckPermissions(fs::owner_all));
1726 
1727   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError);
1728   EXPECT_TRUE(CheckPermissions(fs::group_read));
1729 
1730   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError);
1731   EXPECT_TRUE(CheckPermissions(fs::group_write));
1732 
1733   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError);
1734   EXPECT_TRUE(CheckPermissions(fs::group_exe));
1735 
1736   EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError);
1737   EXPECT_TRUE(CheckPermissions(fs::group_all));
1738 
1739   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError);
1740   EXPECT_TRUE(CheckPermissions(fs::others_read));
1741 
1742   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError);
1743   EXPECT_TRUE(CheckPermissions(fs::others_write));
1744 
1745   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError);
1746   EXPECT_TRUE(CheckPermissions(fs::others_exe));
1747 
1748   EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError);
1749   EXPECT_TRUE(CheckPermissions(fs::others_all));
1750 
1751   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError);
1752   EXPECT_TRUE(CheckPermissions(fs::all_read));
1753 
1754   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError);
1755   EXPECT_TRUE(CheckPermissions(fs::all_write));
1756 
1757   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError);
1758   EXPECT_TRUE(CheckPermissions(fs::all_exe));
1759 
1760   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError);
1761   EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe));
1762 
1763   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError);
1764   EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe));
1765 
1766   // Modern BSDs require root to set the sticky bit on files.
1767   // AIX and Solaris without root will mask off (i.e., lose) the sticky bit
1768   // on files.
1769 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) &&  \
1770     !defined(_AIX) && !(defined(__sun__) && defined(__svr4__))
1771   EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError);
1772   EXPECT_TRUE(CheckPermissions(fs::sticky_bit));
1773 
1774   EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe |
1775                                              fs::set_gid_on_exe |
1776                                              fs::sticky_bit),
1777             NoError);
1778   EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe | fs::set_gid_on_exe |
1779                                fs::sticky_bit));
1780 
1781   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::set_uid_on_exe |
1782                                              fs::set_gid_on_exe |
1783                                              fs::sticky_bit),
1784             NoError);
1785   EXPECT_TRUE(CheckPermissions(fs::all_read | fs::set_uid_on_exe |
1786                                fs::set_gid_on_exe | fs::sticky_bit));
1787 
1788   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError);
1789   EXPECT_TRUE(CheckPermissions(fs::all_perms));
1790 #endif // !FreeBSD && !NetBSD && !OpenBSD && !AIX
1791 
1792   EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms & ~fs::sticky_bit),
1793                                NoError);
1794   EXPECT_TRUE(CheckPermissions(fs::all_perms & ~fs::sticky_bit));
1795 #endif
1796 }
1797 
1798 } // anonymous namespace
1799