1 //===- llvm/unittest/Support/Path.cpp - Path tests ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Support/Path.h" 11 #include "llvm/ADT/STLExtras.h" 12 #include "llvm/ADT/SmallVector.h" 13 #include "llvm/ADT/Triple.h" 14 #include "llvm/BinaryFormat/Magic.h" 15 #include "llvm/Config/llvm-config.h" 16 #include "llvm/Support/ConvertUTF.h" 17 #include "llvm/Support/Errc.h" 18 #include "llvm/Support/ErrorHandling.h" 19 #include "llvm/Support/FileSystem.h" 20 #include "llvm/Support/FileUtilities.h" 21 #include "llvm/Support/Host.h" 22 #include "llvm/Support/MemoryBuffer.h" 23 #include "llvm/Support/raw_ostream.h" 24 #include "gtest/gtest.h" 25 #include "gmock/gmock.h" 26 27 #ifdef _WIN32 28 #include "llvm/ADT/ArrayRef.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 namespace { 53 54 TEST(is_separator, Works) { 55 EXPECT_TRUE(path::is_separator('/')); 56 EXPECT_FALSE(path::is_separator('\0')); 57 EXPECT_FALSE(path::is_separator('-')); 58 EXPECT_FALSE(path::is_separator(' ')); 59 60 EXPECT_TRUE(path::is_separator('\\', path::Style::windows)); 61 EXPECT_FALSE(path::is_separator('\\', path::Style::posix)); 62 63 #ifdef _WIN32 64 EXPECT_TRUE(path::is_separator('\\')); 65 #else 66 EXPECT_FALSE(path::is_separator('\\')); 67 #endif 68 } 69 70 TEST(Support, Path) { 71 SmallVector<StringRef, 40> paths; 72 paths.push_back(""); 73 paths.push_back("."); 74 paths.push_back(".."); 75 paths.push_back("foo"); 76 paths.push_back("/"); 77 paths.push_back("/foo"); 78 paths.push_back("foo/"); 79 paths.push_back("/foo/"); 80 paths.push_back("foo/bar"); 81 paths.push_back("/foo/bar"); 82 paths.push_back("//net"); 83 paths.push_back("//net/"); 84 paths.push_back("//net/foo"); 85 paths.push_back("///foo///"); 86 paths.push_back("///foo///bar"); 87 paths.push_back("/."); 88 paths.push_back("./"); 89 paths.push_back("/.."); 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/.."); 96 paths.push_back("foo/../"); 97 paths.push_back("foo/../bar"); 98 paths.push_back("c:"); 99 paths.push_back("c:/"); 100 paths.push_back("c:foo"); 101 paths.push_back("c:/foo"); 102 paths.push_back("c:foo/"); 103 paths.push_back("c:/foo/"); 104 paths.push_back("c:/foo/bar"); 105 paths.push_back("prn:"); 106 paths.push_back("c:\\"); 107 paths.push_back("c:foo"); 108 paths.push_back("c:\\foo"); 109 paths.push_back("c:foo\\"); 110 paths.push_back("c:\\foo\\"); 111 paths.push_back("c:\\foo/"); 112 paths.push_back("c:/foo\\bar"); 113 114 for (SmallVector<StringRef, 40>::const_iterator i = paths.begin(), 115 e = paths.end(); 116 i != e; 117 ++i) { 118 SCOPED_TRACE(*i); 119 SmallVector<StringRef, 5> ComponentStack; 120 for (sys::path::const_iterator ci = sys::path::begin(*i), 121 ce = sys::path::end(*i); 122 ci != ce; 123 ++ci) { 124 EXPECT_FALSE(ci->empty()); 125 ComponentStack.push_back(*ci); 126 } 127 128 SmallVector<StringRef, 5> ReverseComponentStack; 129 for (sys::path::reverse_iterator ci = sys::path::rbegin(*i), 130 ce = sys::path::rend(*i); 131 ci != ce; 132 ++ci) { 133 EXPECT_FALSE(ci->empty()); 134 ReverseComponentStack.push_back(*ci); 135 } 136 std::reverse(ReverseComponentStack.begin(), ReverseComponentStack.end()); 137 EXPECT_THAT(ComponentStack, testing::ContainerEq(ReverseComponentStack)); 138 139 // Crash test most of the API - since we're iterating over all of our paths 140 // here there isn't really anything reasonable to assert on in the results. 141 (void)path::has_root_path(*i); 142 (void)path::root_path(*i); 143 (void)path::has_root_name(*i); 144 (void)path::root_name(*i); 145 (void)path::has_root_directory(*i); 146 (void)path::root_directory(*i); 147 (void)path::has_parent_path(*i); 148 (void)path::parent_path(*i); 149 (void)path::has_filename(*i); 150 (void)path::filename(*i); 151 (void)path::has_stem(*i); 152 (void)path::stem(*i); 153 (void)path::has_extension(*i); 154 (void)path::extension(*i); 155 (void)path::is_absolute(*i); 156 (void)path::is_relative(*i); 157 158 SmallString<128> temp_store; 159 temp_store = *i; 160 ASSERT_NO_ERROR(fs::make_absolute(temp_store)); 161 temp_store = *i; 162 path::remove_filename(temp_store); 163 164 temp_store = *i; 165 path::replace_extension(temp_store, "ext"); 166 StringRef filename(temp_store.begin(), temp_store.size()), stem, ext; 167 stem = path::stem(filename); 168 ext = path::extension(filename); 169 EXPECT_EQ(*sys::path::rbegin(filename), (stem + ext).str()); 170 171 path::native(*i, temp_store); 172 } 173 174 SmallString<32> Relative("foo.cpp"); 175 ASSERT_NO_ERROR(sys::fs::make_absolute("/root", Relative)); 176 Relative[5] = '/'; // Fix up windows paths. 177 ASSERT_EQ("/root/foo.cpp", Relative); 178 } 179 180 TEST(Support, FilenameParent) { 181 EXPECT_EQ("/", path::filename("/")); 182 EXPECT_EQ("", path::parent_path("/")); 183 184 EXPECT_EQ("\\", path::filename("c:\\", path::Style::windows)); 185 EXPECT_EQ("c:", path::parent_path("c:\\", path::Style::windows)); 186 187 EXPECT_EQ("/", path::filename("///")); 188 EXPECT_EQ("", path::parent_path("///")); 189 190 EXPECT_EQ("\\", path::filename("c:\\\\", path::Style::windows)); 191 EXPECT_EQ("c:", path::parent_path("c:\\\\", path::Style::windows)); 192 193 EXPECT_EQ("bar", path::filename("/foo/bar")); 194 EXPECT_EQ("/foo", path::parent_path("/foo/bar")); 195 196 EXPECT_EQ("foo", path::filename("/foo")); 197 EXPECT_EQ("/", path::parent_path("/foo")); 198 199 EXPECT_EQ("foo", path::filename("foo")); 200 EXPECT_EQ("", path::parent_path("foo")); 201 202 EXPECT_EQ(".", path::filename("foo/")); 203 EXPECT_EQ("foo", path::parent_path("foo/")); 204 205 EXPECT_EQ("//net", path::filename("//net")); 206 EXPECT_EQ("", path::parent_path("//net")); 207 208 EXPECT_EQ("/", path::filename("//net/")); 209 EXPECT_EQ("//net", path::parent_path("//net/")); 210 211 EXPECT_EQ("foo", path::filename("//net/foo")); 212 EXPECT_EQ("//net/", path::parent_path("//net/foo")); 213 214 // These checks are just to make sure we do something reasonable with the 215 // paths below. They are not meant to prescribe the one true interpretation of 216 // these paths. Other decompositions (e.g. "//" -> "" + "//") are also 217 // possible. 218 EXPECT_EQ("/", path::filename("//")); 219 EXPECT_EQ("", path::parent_path("//")); 220 221 EXPECT_EQ("\\", path::filename("\\\\", path::Style::windows)); 222 EXPECT_EQ("", path::parent_path("\\\\", path::Style::windows)); 223 224 EXPECT_EQ("\\", path::filename("\\\\\\", path::Style::windows)); 225 EXPECT_EQ("", path::parent_path("\\\\\\", path::Style::windows)); 226 } 227 228 static std::vector<StringRef> 229 GetComponents(StringRef Path, path::Style S = path::Style::native) { 230 return {path::begin(Path, S), path::end(Path)}; 231 } 232 233 TEST(Support, PathIterator) { 234 EXPECT_THAT(GetComponents("/foo"), testing::ElementsAre("/", "foo")); 235 EXPECT_THAT(GetComponents("/"), testing::ElementsAre("/")); 236 EXPECT_THAT(GetComponents("//"), testing::ElementsAre("/")); 237 EXPECT_THAT(GetComponents("///"), testing::ElementsAre("/")); 238 EXPECT_THAT(GetComponents("c/d/e/foo.txt"), 239 testing::ElementsAre("c", "d", "e", "foo.txt")); 240 EXPECT_THAT(GetComponents(".c/.d/../."), 241 testing::ElementsAre(".c", ".d", "..", ".")); 242 EXPECT_THAT(GetComponents("/c/d/e/foo.txt"), 243 testing::ElementsAre("/", "c", "d", "e", "foo.txt")); 244 EXPECT_THAT(GetComponents("/.c/.d/../."), 245 testing::ElementsAre("/", ".c", ".d", "..", ".")); 246 EXPECT_THAT(GetComponents("c:\\c\\e\\foo.txt", path::Style::windows), 247 testing::ElementsAre("c:", "\\", "c", "e", "foo.txt")); 248 EXPECT_THAT(GetComponents("//net/"), testing::ElementsAre("//net", "/")); 249 EXPECT_THAT(GetComponents("//net/c/foo.txt"), 250 testing::ElementsAre("//net", "/", "c", "foo.txt")); 251 } 252 253 TEST(Support, AbsolutePathIteratorEnd) { 254 // Trailing slashes are converted to '.' unless they are part of the root path. 255 SmallVector<std::pair<StringRef, path::Style>, 4> Paths; 256 Paths.emplace_back("/foo/", path::Style::native); 257 Paths.emplace_back("/foo//", path::Style::native); 258 Paths.emplace_back("//net/foo/", path::Style::native); 259 Paths.emplace_back("c:\\foo\\", path::Style::windows); 260 261 for (auto &Path : Paths) { 262 SCOPED_TRACE(Path.first); 263 StringRef LastComponent = *path::rbegin(Path.first, Path.second); 264 EXPECT_EQ(".", LastComponent); 265 } 266 267 SmallVector<std::pair<StringRef, path::Style>, 3> RootPaths; 268 RootPaths.emplace_back("/", path::Style::native); 269 RootPaths.emplace_back("//net/", path::Style::native); 270 RootPaths.emplace_back("c:\\", path::Style::windows); 271 RootPaths.emplace_back("//net//", path::Style::native); 272 RootPaths.emplace_back("c:\\\\", path::Style::windows); 273 274 for (auto &Path : RootPaths) { 275 SCOPED_TRACE(Path.first); 276 StringRef LastComponent = *path::rbegin(Path.first, Path.second); 277 EXPECT_EQ(1u, LastComponent.size()); 278 EXPECT_TRUE(path::is_separator(LastComponent[0], Path.second)); 279 } 280 } 281 282 TEST(Support, HomeDirectory) { 283 std::string expected; 284 #ifdef _WIN32 285 if (wchar_t const *path = ::_wgetenv(L"USERPROFILE")) { 286 auto pathLen = ::wcslen(path); 287 ArrayRef<char> ref{reinterpret_cast<char const *>(path), 288 pathLen * sizeof(wchar_t)}; 289 convertUTF16ToUTF8String(ref, expected); 290 } 291 #else 292 if (char const *path = ::getenv("HOME")) 293 expected = path; 294 #endif 295 // Do not try to test it if we don't know what to expect. 296 // On Windows we use something better than env vars. 297 if (!expected.empty()) { 298 SmallString<128> HomeDir; 299 auto status = path::home_directory(HomeDir); 300 EXPECT_TRUE(status); 301 EXPECT_EQ(expected, HomeDir); 302 } 303 } 304 305 #ifdef LLVM_ON_UNIX 306 TEST(Support, HomeDirectoryWithNoEnv) { 307 std::string OriginalStorage; 308 char const *OriginalEnv = ::getenv("HOME"); 309 if (OriginalEnv) { 310 // We're going to unset it, so make a copy and save a pointer to the copy 311 // so that we can reset it at the end of the test. 312 OriginalStorage = OriginalEnv; 313 OriginalEnv = OriginalStorage.c_str(); 314 } 315 316 // Don't run the test if we have nothing to compare against. 317 struct passwd *pw = getpwuid(getuid()); 318 if (!pw || !pw->pw_dir) return; 319 320 ::unsetenv("HOME"); 321 EXPECT_EQ(nullptr, ::getenv("HOME")); 322 std::string PwDir = pw->pw_dir; 323 324 SmallString<128> HomeDir; 325 auto status = path::home_directory(HomeDir); 326 EXPECT_TRUE(status); 327 EXPECT_EQ(PwDir, HomeDir); 328 329 // Now put the environment back to its original state (meaning that if it was 330 // unset before, we don't reset it). 331 if (OriginalEnv) ::setenv("HOME", OriginalEnv, 1); 332 } 333 #endif 334 335 TEST(Support, UserCacheDirectory) { 336 SmallString<13> CacheDir; 337 SmallString<20> CacheDir2; 338 auto Status = path::user_cache_directory(CacheDir, ""); 339 EXPECT_TRUE(Status ^ CacheDir.empty()); 340 341 if (Status) { 342 EXPECT_TRUE(path::user_cache_directory(CacheDir2, "")); // should succeed 343 EXPECT_EQ(CacheDir, CacheDir2); // and return same paths 344 345 EXPECT_TRUE(path::user_cache_directory(CacheDir, "A", "B", "file.c")); 346 auto It = path::rbegin(CacheDir); 347 EXPECT_EQ("file.c", *It); 348 EXPECT_EQ("B", *++It); 349 EXPECT_EQ("A", *++It); 350 auto ParentDir = *++It; 351 352 // Test Unicode: "<user_cache_dir>/(pi)r^2/aleth.0" 353 EXPECT_TRUE(path::user_cache_directory(CacheDir2, "\xCF\x80r\xC2\xB2", 354 "\xE2\x84\xB5.0")); 355 auto It2 = path::rbegin(CacheDir2); 356 EXPECT_EQ("\xE2\x84\xB5.0", *It2); 357 EXPECT_EQ("\xCF\x80r\xC2\xB2", *++It2); 358 auto ParentDir2 = *++It2; 359 360 EXPECT_EQ(ParentDir, ParentDir2); 361 } 362 } 363 364 TEST(Support, TempDirectory) { 365 SmallString<32> TempDir; 366 path::system_temp_directory(false, TempDir); 367 EXPECT_TRUE(!TempDir.empty()); 368 TempDir.clear(); 369 path::system_temp_directory(true, TempDir); 370 EXPECT_TRUE(!TempDir.empty()); 371 } 372 373 #ifdef _WIN32 374 static std::string path2regex(std::string Path) { 375 size_t Pos = 0; 376 while ((Pos = Path.find('\\', Pos)) != std::string::npos) { 377 Path.replace(Pos, 1, "\\\\"); 378 Pos += 2; 379 } 380 return Path; 381 } 382 383 /// Helper for running temp dir test in separated process. See below. 384 #define EXPECT_TEMP_DIR(prepare, expected) \ 385 EXPECT_EXIT( \ 386 { \ 387 prepare; \ 388 SmallString<300> TempDir; \ 389 path::system_temp_directory(true, TempDir); \ 390 raw_os_ostream(std::cerr) << TempDir; \ 391 std::exit(0); \ 392 }, \ 393 ::testing::ExitedWithCode(0), path2regex(expected)) 394 395 TEST(SupportDeathTest, TempDirectoryOnWindows) { 396 // In this test we want to check how system_temp_directory responds to 397 // different values of specific env vars. To prevent corrupting env vars of 398 // the current process all checks are done in separated processes. 399 EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:\\OtherFolder"), "C:\\OtherFolder"); 400 EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"C:/Unix/Path/Seperators"), 401 "C:\\Unix\\Path\\Seperators"); 402 EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"Local Path"), ".+\\Local Path$"); 403 EXPECT_TEMP_DIR(_wputenv_s(L"TMP", L"F:\\TrailingSep\\"), "F:\\TrailingSep"); 404 EXPECT_TEMP_DIR( 405 _wputenv_s(L"TMP", L"C:\\2\x03C0r-\x00B5\x00B3\\\x2135\x2080"), 406 "C:\\2\xCF\x80r-\xC2\xB5\xC2\xB3\\\xE2\x84\xB5\xE2\x82\x80"); 407 408 // Test $TMP empty, $TEMP set. 409 EXPECT_TEMP_DIR( 410 { 411 _wputenv_s(L"TMP", L""); 412 _wputenv_s(L"TEMP", L"C:\\Valid\\Path"); 413 }, 414 "C:\\Valid\\Path"); 415 416 // All related env vars empty 417 EXPECT_TEMP_DIR( 418 { 419 _wputenv_s(L"TMP", L""); 420 _wputenv_s(L"TEMP", L""); 421 _wputenv_s(L"USERPROFILE", L""); 422 }, 423 "C:\\Temp"); 424 425 // Test evn var / path with 260 chars. 426 SmallString<270> Expected{"C:\\Temp\\AB\\123456789"}; 427 while (Expected.size() < 260) 428 Expected.append("\\DirNameWith19Charss"); 429 ASSERT_EQ(260U, Expected.size()); 430 EXPECT_TEMP_DIR(_putenv_s("TMP", Expected.c_str()), Expected.c_str()); 431 } 432 #endif 433 434 class FileSystemTest : public testing::Test { 435 protected: 436 /// Unique temporary directory in which all created filesystem entities must 437 /// be placed. It is removed at the end of each test (must be empty). 438 SmallString<128> TestDirectory; 439 440 void SetUp() override { 441 ASSERT_NO_ERROR( 442 fs::createUniqueDirectory("file-system-test", TestDirectory)); 443 // We don't care about this specific file. 444 errs() << "Test Directory: " << TestDirectory << '\n'; 445 errs().flush(); 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 bool Result = llvm::sys::path::home_directory(HomeDir); 528 if (Result) { 529 ASSERT_NO_ERROR(fs::real_path(HomeDir, Expected)); 530 ASSERT_NO_ERROR(fs::real_path("~", Actual, true)); 531 EXPECT_EQ(Expected, Actual); 532 ASSERT_NO_ERROR(fs::real_path("~/", Actual, true)); 533 EXPECT_EQ(Expected, Actual); 534 } 535 536 ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/test1")); 537 } 538 539 #ifdef LLVM_ON_UNIX 540 TEST_F(FileSystemTest, RealPathNoReadPerm) { 541 SmallString<64> Expanded; 542 543 ASSERT_NO_ERROR( 544 fs::create_directories(Twine(TestDirectory) + "/noreadperm")); 545 ASSERT_TRUE(fs::exists(Twine(TestDirectory) + "/noreadperm")); 546 547 fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::no_perms); 548 fs::setPermissions(Twine(TestDirectory) + "/noreadperm", fs::all_exe); 549 550 ASSERT_NO_ERROR(fs::real_path(Twine(TestDirectory) + "/noreadperm", Expanded, 551 false)); 552 553 ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/noreadperm")); 554 } 555 #endif 556 557 558 TEST_F(FileSystemTest, TempFileKeepDiscard) { 559 // We can keep then discard. 560 auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%"); 561 ASSERT_TRUE((bool)TempFileOrError); 562 fs::TempFile File = std::move(*TempFileOrError); 563 ASSERT_FALSE((bool)File.keep(TestDirectory + "/keep")); 564 ASSERT_FALSE((bool)File.discard()); 565 ASSERT_TRUE(fs::exists(TestDirectory + "/keep")); 566 ASSERT_NO_ERROR(fs::remove(TestDirectory + "/keep")); 567 } 568 569 TEST_F(FileSystemTest, TempFileDiscardDiscard) { 570 // We can discard twice. 571 auto TempFileOrError = fs::TempFile::create(TestDirectory + "/test-%%%%"); 572 ASSERT_TRUE((bool)TempFileOrError); 573 fs::TempFile File = std::move(*TempFileOrError); 574 ASSERT_FALSE((bool)File.discard()); 575 ASSERT_FALSE((bool)File.discard()); 576 ASSERT_FALSE(fs::exists(TestDirectory + "/keep")); 577 } 578 579 TEST_F(FileSystemTest, TempFiles) { 580 // Create a temp file. 581 int FileDescriptor; 582 SmallString<64> TempPath; 583 ASSERT_NO_ERROR( 584 fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath)); 585 586 // Make sure it exists. 587 ASSERT_TRUE(sys::fs::exists(Twine(TempPath))); 588 589 // Create another temp tile. 590 int FD2; 591 SmallString<64> TempPath2; 592 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD2, TempPath2)); 593 ASSERT_TRUE(TempPath2.endswith(".temp")); 594 ASSERT_NE(TempPath.str(), TempPath2.str()); 595 596 fs::file_status A, B; 597 ASSERT_NO_ERROR(fs::status(Twine(TempPath), A)); 598 ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B)); 599 EXPECT_FALSE(fs::equivalent(A, B)); 600 601 ::close(FD2); 602 603 // Remove Temp2. 604 ASSERT_NO_ERROR(fs::remove(Twine(TempPath2))); 605 ASSERT_NO_ERROR(fs::remove(Twine(TempPath2))); 606 ASSERT_EQ(fs::remove(Twine(TempPath2), false), 607 errc::no_such_file_or_directory); 608 609 std::error_code EC = fs::status(TempPath2.c_str(), B); 610 EXPECT_EQ(EC, errc::no_such_file_or_directory); 611 EXPECT_EQ(B.type(), fs::file_type::file_not_found); 612 613 // Make sure Temp2 doesn't exist. 614 ASSERT_EQ(fs::access(Twine(TempPath2), sys::fs::AccessMode::Exist), 615 errc::no_such_file_or_directory); 616 617 SmallString<64> TempPath3; 618 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "", TempPath3)); 619 ASSERT_FALSE(TempPath3.endswith(".")); 620 FileRemover Cleanup3(TempPath3); 621 622 // Create a hard link to Temp1. 623 ASSERT_NO_ERROR(fs::create_link(Twine(TempPath), Twine(TempPath2))); 624 bool equal; 625 ASSERT_NO_ERROR(fs::equivalent(Twine(TempPath), Twine(TempPath2), equal)); 626 EXPECT_TRUE(equal); 627 ASSERT_NO_ERROR(fs::status(Twine(TempPath), A)); 628 ASSERT_NO_ERROR(fs::status(Twine(TempPath2), B)); 629 EXPECT_TRUE(fs::equivalent(A, B)); 630 631 // Remove Temp1. 632 ::close(FileDescriptor); 633 ASSERT_NO_ERROR(fs::remove(Twine(TempPath))); 634 635 // Remove the hard link. 636 ASSERT_NO_ERROR(fs::remove(Twine(TempPath2))); 637 638 // Make sure Temp1 doesn't exist. 639 ASSERT_EQ(fs::access(Twine(TempPath), sys::fs::AccessMode::Exist), 640 errc::no_such_file_or_directory); 641 642 #ifdef _WIN32 643 // Path name > 260 chars should get an error. 644 const char *Path270 = 645 "abcdefghijklmnopqrstuvwxyz9abcdefghijklmnopqrstuvwxyz8" 646 "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6" 647 "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4" 648 "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2" 649 "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0"; 650 EXPECT_EQ(fs::createUniqueFile(Path270, FileDescriptor, TempPath), 651 errc::invalid_argument); 652 // Relative path < 247 chars, no problem. 653 const char *Path216 = 654 "abcdefghijklmnopqrstuvwxyz7abcdefghijklmnopqrstuvwxyz6" 655 "abcdefghijklmnopqrstuvwxyz5abcdefghijklmnopqrstuvwxyz4" 656 "abcdefghijklmnopqrstuvwxyz3abcdefghijklmnopqrstuvwxyz2" 657 "abcdefghijklmnopqrstuvwxyz1abcdefghijklmnopqrstuvwxyz0"; 658 ASSERT_NO_ERROR(fs::createTemporaryFile(Path216, "", TempPath)); 659 ASSERT_NO_ERROR(fs::remove(Twine(TempPath))); 660 #endif 661 } 662 663 TEST_F(FileSystemTest, CreateDir) { 664 ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo")); 665 ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "foo")); 666 ASSERT_EQ(fs::create_directory(Twine(TestDirectory) + "foo", false), 667 errc::file_exists); 668 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "foo")); 669 670 #ifdef LLVM_ON_UNIX 671 // Set a 0000 umask so that we can test our directory permissions. 672 mode_t OldUmask = ::umask(0000); 673 674 fs::file_status Status; 675 ASSERT_NO_ERROR( 676 fs::create_directory(Twine(TestDirectory) + "baz500", false, 677 fs::perms::owner_read | fs::perms::owner_exe)); 678 ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz500", Status)); 679 ASSERT_EQ(Status.permissions() & fs::perms::all_all, 680 fs::perms::owner_read | fs::perms::owner_exe); 681 ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory) + "baz777", false, 682 fs::perms::all_all)); 683 ASSERT_NO_ERROR(fs::status(Twine(TestDirectory) + "baz777", Status)); 684 ASSERT_EQ(Status.permissions() & fs::perms::all_all, fs::perms::all_all); 685 686 // Restore umask to be safe. 687 ::umask(OldUmask); 688 #endif 689 690 #ifdef _WIN32 691 // Prove that create_directories() can handle a pathname > 248 characters, 692 // which is the documented limit for CreateDirectory(). 693 // (248 is MAX_PATH subtracting room for an 8.3 filename.) 694 // Generate a directory path guaranteed to fall into that range. 695 size_t TmpLen = TestDirectory.size(); 696 const char *OneDir = "\\123456789"; 697 size_t OneDirLen = strlen(OneDir); 698 ASSERT_LT(OneDirLen, 12U); 699 size_t NLevels = ((248 - TmpLen) / OneDirLen) + 1; 700 SmallString<260> LongDir(TestDirectory); 701 for (size_t I = 0; I < NLevels; ++I) 702 LongDir.append(OneDir); 703 ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir))); 704 ASSERT_NO_ERROR(fs::create_directories(Twine(LongDir))); 705 ASSERT_EQ(fs::create_directories(Twine(LongDir), false), 706 errc::file_exists); 707 // Tidy up, "recursively" removing the directories. 708 StringRef ThisDir(LongDir); 709 for (size_t J = 0; J < NLevels; ++J) { 710 ASSERT_NO_ERROR(fs::remove(ThisDir)); 711 ThisDir = path::parent_path(ThisDir); 712 } 713 714 // Also verify that paths with Unix separators are handled correctly. 715 std::string LongPathWithUnixSeparators(TestDirectory.str()); 716 // Add at least one subdirectory to TestDirectory, and replace slashes with 717 // backslashes 718 do { 719 LongPathWithUnixSeparators.append("/DirNameWith19Charss"); 720 } while (LongPathWithUnixSeparators.size() < 260); 721 std::replace(LongPathWithUnixSeparators.begin(), 722 LongPathWithUnixSeparators.end(), 723 '\\', '/'); 724 ASSERT_NO_ERROR(fs::create_directories(Twine(LongPathWithUnixSeparators))); 725 // cleanup 726 ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + 727 "/DirNameWith19Charss")); 728 729 // Similarly for a relative pathname. Need to set the current directory to 730 // TestDirectory so that the one we create ends up in the right place. 731 char PreviousDir[260]; 732 size_t PreviousDirLen = ::GetCurrentDirectoryA(260, PreviousDir); 733 ASSERT_GT(PreviousDirLen, 0U); 734 ASSERT_LT(PreviousDirLen, 260U); 735 ASSERT_NE(::SetCurrentDirectoryA(TestDirectory.c_str()), 0); 736 LongDir.clear(); 737 // Generate a relative directory name with absolute length > 248. 738 size_t LongDirLen = 249 - TestDirectory.size(); 739 LongDir.assign(LongDirLen, 'a'); 740 ASSERT_NO_ERROR(fs::create_directory(Twine(LongDir))); 741 // While we're here, prove that .. and . handling works in these long paths. 742 const char *DotDotDirs = "\\..\\.\\b"; 743 LongDir.append(DotDotDirs); 744 ASSERT_NO_ERROR(fs::create_directory("b")); 745 ASSERT_EQ(fs::create_directory(Twine(LongDir), false), errc::file_exists); 746 // And clean up. 747 ASSERT_NO_ERROR(fs::remove("b")); 748 ASSERT_NO_ERROR(fs::remove( 749 Twine(LongDir.substr(0, LongDir.size() - strlen(DotDotDirs))))); 750 ASSERT_NE(::SetCurrentDirectoryA(PreviousDir), 0); 751 #endif 752 } 753 754 TEST_F(FileSystemTest, DirectoryIteration) { 755 std::error_code ec; 756 for (fs::directory_iterator i(".", ec), e; i != e; i.increment(ec)) 757 ASSERT_NO_ERROR(ec); 758 759 // Create a known hierarchy to recurse over. 760 ASSERT_NO_ERROR( 761 fs::create_directories(Twine(TestDirectory) + "/recursive/a0/aa1")); 762 ASSERT_NO_ERROR( 763 fs::create_directories(Twine(TestDirectory) + "/recursive/a0/ab1")); 764 ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + 765 "/recursive/dontlookhere/da1")); 766 ASSERT_NO_ERROR( 767 fs::create_directories(Twine(TestDirectory) + "/recursive/z0/za1")); 768 ASSERT_NO_ERROR( 769 fs::create_directories(Twine(TestDirectory) + "/recursive/pop/p1")); 770 typedef std::vector<std::string> v_t; 771 v_t visited; 772 for (fs::recursive_directory_iterator i(Twine(TestDirectory) 773 + "/recursive", ec), e; i != e; i.increment(ec)){ 774 ASSERT_NO_ERROR(ec); 775 if (path::filename(i->path()) == "p1") { 776 i.pop(); 777 // FIXME: recursive_directory_iterator should be more robust. 778 if (i == e) break; 779 } 780 if (path::filename(i->path()) == "dontlookhere") 781 i.no_push(); 782 visited.push_back(path::filename(i->path())); 783 } 784 v_t::const_iterator a0 = find(visited, "a0"); 785 v_t::const_iterator aa1 = find(visited, "aa1"); 786 v_t::const_iterator ab1 = find(visited, "ab1"); 787 v_t::const_iterator dontlookhere = find(visited, "dontlookhere"); 788 v_t::const_iterator da1 = find(visited, "da1"); 789 v_t::const_iterator z0 = find(visited, "z0"); 790 v_t::const_iterator za1 = find(visited, "za1"); 791 v_t::const_iterator pop = find(visited, "pop"); 792 v_t::const_iterator p1 = find(visited, "p1"); 793 794 // Make sure that each path was visited correctly. 795 ASSERT_NE(a0, visited.end()); 796 ASSERT_NE(aa1, visited.end()); 797 ASSERT_NE(ab1, visited.end()); 798 ASSERT_NE(dontlookhere, visited.end()); 799 ASSERT_EQ(da1, visited.end()); // Not visited. 800 ASSERT_NE(z0, visited.end()); 801 ASSERT_NE(za1, visited.end()); 802 ASSERT_NE(pop, visited.end()); 803 ASSERT_EQ(p1, visited.end()); // Not visited. 804 805 // Make sure that parents were visited before children. No other ordering 806 // guarantees can be made across siblings. 807 ASSERT_LT(a0, aa1); 808 ASSERT_LT(a0, ab1); 809 ASSERT_LT(z0, za1); 810 811 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/aa1")); 812 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0/ab1")); 813 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/a0")); 814 ASSERT_NO_ERROR( 815 fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere/da1")); 816 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/dontlookhere")); 817 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop/p1")); 818 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/pop")); 819 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0/za1")); 820 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive/z0")); 821 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/recursive")); 822 823 // Test recursive_directory_iterator level() 824 ASSERT_NO_ERROR( 825 fs::create_directories(Twine(TestDirectory) + "/reclevel/a/b/c")); 826 fs::recursive_directory_iterator I(Twine(TestDirectory) + "/reclevel", ec), E; 827 for (int l = 0; I != E; I.increment(ec), ++l) { 828 ASSERT_NO_ERROR(ec); 829 EXPECT_EQ(I.level(), l); 830 } 831 EXPECT_EQ(I, E); 832 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b/c")); 833 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a/b")); 834 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel/a")); 835 ASSERT_NO_ERROR(fs::remove(Twine(TestDirectory) + "/reclevel")); 836 } 837 838 #ifdef LLVM_ON_UNIX 839 TEST_F(FileSystemTest, BrokenSymlinkDirectoryIteration) { 840 // Create a known hierarchy to recurse over. 841 ASSERT_NO_ERROR(fs::create_directories(Twine(TestDirectory) + "/symlink")); 842 ASSERT_NO_ERROR( 843 fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/a")); 844 ASSERT_NO_ERROR( 845 fs::create_directories(Twine(TestDirectory) + "/symlink/b/bb")); 846 ASSERT_NO_ERROR( 847 fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/ba")); 848 ASSERT_NO_ERROR( 849 fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/b/bc")); 850 ASSERT_NO_ERROR( 851 fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/c")); 852 ASSERT_NO_ERROR( 853 fs::create_directories(Twine(TestDirectory) + "/symlink/d/dd/ddd")); 854 ASSERT_NO_ERROR(fs::create_link(Twine(TestDirectory) + "/symlink/d/dd", 855 Twine(TestDirectory) + "/symlink/d/da")); 856 ASSERT_NO_ERROR( 857 fs::create_link("no_such_file", Twine(TestDirectory) + "/symlink/e")); 858 859 typedef std::vector<std::string> v_t; 860 v_t VisitedNonBrokenSymlinks; 861 v_t VisitedBrokenSymlinks; 862 std::error_code ec; 863 864 // Broken symbol links are expected to throw an error. 865 for (fs::directory_iterator i(Twine(TestDirectory) + "/symlink", ec), e; 866 i != e; i.increment(ec)) { 867 if (ec == std::make_error_code(std::errc::no_such_file_or_directory)) { 868 VisitedBrokenSymlinks.push_back(path::filename(i->path())); 869 continue; 870 } 871 872 ASSERT_NO_ERROR(ec); 873 VisitedNonBrokenSymlinks.push_back(path::filename(i->path())); 874 } 875 llvm::sort(VisitedNonBrokenSymlinks.begin(), VisitedNonBrokenSymlinks.end()); 876 llvm::sort(VisitedBrokenSymlinks.begin(), VisitedBrokenSymlinks.end()); 877 v_t ExpectedNonBrokenSymlinks = {"b", "d"}; 878 ASSERT_EQ(ExpectedNonBrokenSymlinks.size(), VisitedNonBrokenSymlinks.size()); 879 ASSERT_TRUE(std::equal(VisitedNonBrokenSymlinks.begin(), 880 VisitedNonBrokenSymlinks.end(), 881 ExpectedNonBrokenSymlinks.begin())); 882 VisitedNonBrokenSymlinks.clear(); 883 884 v_t ExpectedBrokenSymlinks = {"a", "c", "e"}; 885 ASSERT_EQ(ExpectedBrokenSymlinks.size(), VisitedBrokenSymlinks.size()); 886 ASSERT_TRUE(std::equal(VisitedBrokenSymlinks.begin(), 887 VisitedBrokenSymlinks.end(), 888 ExpectedBrokenSymlinks.begin())); 889 VisitedBrokenSymlinks.clear(); 890 891 // Broken symbol links are expected to throw an error. 892 for (fs::recursive_directory_iterator i( 893 Twine(TestDirectory) + "/symlink", ec), e; i != e; i.increment(ec)) { 894 if (ec == std::make_error_code(std::errc::no_such_file_or_directory)) { 895 VisitedBrokenSymlinks.push_back(path::filename(i->path())); 896 continue; 897 } 898 899 ASSERT_NO_ERROR(ec); 900 VisitedNonBrokenSymlinks.push_back(path::filename(i->path())); 901 } 902 llvm::sort(VisitedNonBrokenSymlinks.begin(), VisitedNonBrokenSymlinks.end()); 903 llvm::sort(VisitedBrokenSymlinks.begin(), VisitedBrokenSymlinks.end()); 904 ExpectedNonBrokenSymlinks = {"b", "bb", "d", "da", "dd", "ddd", "ddd"}; 905 ASSERT_EQ(ExpectedNonBrokenSymlinks.size(), VisitedNonBrokenSymlinks.size()); 906 ASSERT_TRUE(std::equal(VisitedNonBrokenSymlinks.begin(), 907 VisitedNonBrokenSymlinks.end(), 908 ExpectedNonBrokenSymlinks.begin())); 909 VisitedNonBrokenSymlinks.clear(); 910 911 ExpectedBrokenSymlinks = {"a", "ba", "bc", "c", "e"}; 912 ASSERT_EQ(ExpectedBrokenSymlinks.size(), VisitedBrokenSymlinks.size()); 913 ASSERT_TRUE(std::equal(VisitedBrokenSymlinks.begin(), 914 VisitedBrokenSymlinks.end(), 915 ExpectedBrokenSymlinks.begin())); 916 VisitedBrokenSymlinks.clear(); 917 918 for (fs::recursive_directory_iterator i( 919 Twine(TestDirectory) + "/symlink", ec, /*follow_symlinks=*/false), e; 920 i != e; i.increment(ec)) { 921 if (ec == std::make_error_code(std::errc::no_such_file_or_directory)) { 922 VisitedBrokenSymlinks.push_back(path::filename(i->path())); 923 continue; 924 } 925 926 ASSERT_NO_ERROR(ec); 927 VisitedNonBrokenSymlinks.push_back(path::filename(i->path())); 928 } 929 llvm::sort(VisitedNonBrokenSymlinks.begin(), VisitedNonBrokenSymlinks.end()); 930 llvm::sort(VisitedBrokenSymlinks.begin(), VisitedBrokenSymlinks.end()); 931 ExpectedNonBrokenSymlinks = {"a", "b", "ba", "bb", "bc", "c", "d", "da", "dd", 932 "ddd", "e"}; 933 ASSERT_EQ(ExpectedNonBrokenSymlinks.size(), VisitedNonBrokenSymlinks.size()); 934 ASSERT_TRUE(std::equal(VisitedNonBrokenSymlinks.begin(), 935 VisitedNonBrokenSymlinks.end(), 936 ExpectedNonBrokenSymlinks.begin())); 937 VisitedNonBrokenSymlinks.clear(); 938 939 ExpectedBrokenSymlinks = {}; 940 ASSERT_EQ(ExpectedBrokenSymlinks.size(), VisitedBrokenSymlinks.size()); 941 ASSERT_TRUE(std::equal(VisitedBrokenSymlinks.begin(), 942 VisitedBrokenSymlinks.end(), 943 ExpectedBrokenSymlinks.begin())); 944 VisitedBrokenSymlinks.clear(); 945 946 ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory) + "/symlink")); 947 } 948 #endif 949 950 TEST_F(FileSystemTest, Remove) { 951 SmallString<64> BaseDir; 952 SmallString<64> Paths[4]; 953 int fds[4]; 954 ASSERT_NO_ERROR(fs::createUniqueDirectory("fs_remove", BaseDir)); 955 956 ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/baz")); 957 ASSERT_NO_ERROR(fs::create_directories(Twine(BaseDir) + "/foo/bar/buzz")); 958 ASSERT_NO_ERROR(fs::createUniqueFile( 959 Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[0], Paths[0])); 960 ASSERT_NO_ERROR(fs::createUniqueFile( 961 Twine(BaseDir) + "/foo/bar/baz/%%%%%%.tmp", fds[1], Paths[1])); 962 ASSERT_NO_ERROR(fs::createUniqueFile( 963 Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[2], Paths[2])); 964 ASSERT_NO_ERROR(fs::createUniqueFile( 965 Twine(BaseDir) + "/foo/bar/buzz/%%%%%%.tmp", fds[3], Paths[3])); 966 967 for (int fd : fds) 968 ::close(fd); 969 970 EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/baz")); 971 EXPECT_TRUE(fs::exists(Twine(BaseDir) + "/foo/bar/buzz")); 972 EXPECT_TRUE(fs::exists(Paths[0])); 973 EXPECT_TRUE(fs::exists(Paths[1])); 974 EXPECT_TRUE(fs::exists(Paths[2])); 975 EXPECT_TRUE(fs::exists(Paths[3])); 976 977 ASSERT_NO_ERROR(fs::remove_directories("D:/footest")); 978 979 ASSERT_NO_ERROR(fs::remove_directories(BaseDir)); 980 ASSERT_FALSE(fs::exists(BaseDir)); 981 } 982 983 #ifdef _WIN32 984 TEST_F(FileSystemTest, CarriageReturn) { 985 SmallString<128> FilePathname(TestDirectory); 986 std::error_code EC; 987 path::append(FilePathname, "test"); 988 989 { 990 raw_fd_ostream File(FilePathname, EC, sys::fs::F_Text); 991 ASSERT_NO_ERROR(EC); 992 File << '\n'; 993 } 994 { 995 auto Buf = MemoryBuffer::getFile(FilePathname.str()); 996 EXPECT_TRUE((bool)Buf); 997 EXPECT_EQ(Buf.get()->getBuffer(), "\r\n"); 998 } 999 1000 { 1001 raw_fd_ostream File(FilePathname, EC, sys::fs::F_None); 1002 ASSERT_NO_ERROR(EC); 1003 File << '\n'; 1004 } 1005 { 1006 auto Buf = MemoryBuffer::getFile(FilePathname.str()); 1007 EXPECT_TRUE((bool)Buf); 1008 EXPECT_EQ(Buf.get()->getBuffer(), "\n"); 1009 } 1010 ASSERT_NO_ERROR(fs::remove(Twine(FilePathname))); 1011 } 1012 #endif 1013 1014 TEST_F(FileSystemTest, Resize) { 1015 int FD; 1016 SmallString<64> TempPath; 1017 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); 1018 ASSERT_NO_ERROR(fs::resize_file(FD, 123)); 1019 fs::file_status Status; 1020 ASSERT_NO_ERROR(fs::status(FD, Status)); 1021 ASSERT_EQ(Status.getSize(), 123U); 1022 ::close(FD); 1023 ASSERT_NO_ERROR(fs::remove(TempPath)); 1024 } 1025 1026 TEST_F(FileSystemTest, MD5) { 1027 int FD; 1028 SmallString<64> TempPath; 1029 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); 1030 StringRef Data("abcdefghijklmnopqrstuvwxyz"); 1031 ASSERT_EQ(write(FD, Data.data(), Data.size()), static_cast<ssize_t>(Data.size())); 1032 lseek(FD, 0, SEEK_SET); 1033 auto Hash = fs::md5_contents(FD); 1034 ::close(FD); 1035 ASSERT_NO_ERROR(Hash.getError()); 1036 1037 EXPECT_STREQ("c3fcd3d76192e4007dfb496cca67e13b", Hash->digest().c_str()); 1038 } 1039 1040 TEST_F(FileSystemTest, FileMapping) { 1041 // Create a temp file. 1042 int FileDescriptor; 1043 SmallString<64> TempPath; 1044 ASSERT_NO_ERROR( 1045 fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath)); 1046 unsigned Size = 4096; 1047 ASSERT_NO_ERROR(fs::resize_file(FileDescriptor, Size)); 1048 1049 // Map in temp file and add some content 1050 std::error_code EC; 1051 StringRef Val("hello there"); 1052 { 1053 fs::mapped_file_region mfr(FileDescriptor, 1054 fs::mapped_file_region::readwrite, Size, 0, EC); 1055 ASSERT_NO_ERROR(EC); 1056 std::copy(Val.begin(), Val.end(), mfr.data()); 1057 // Explicitly add a 0. 1058 mfr.data()[Val.size()] = 0; 1059 // Unmap temp file 1060 } 1061 ASSERT_EQ(close(FileDescriptor), 0); 1062 1063 // Map it back in read-only 1064 { 1065 int FD; 1066 EC = fs::openFileForRead(Twine(TempPath), FD); 1067 ASSERT_NO_ERROR(EC); 1068 fs::mapped_file_region mfr(FD, fs::mapped_file_region::readonly, Size, 0, EC); 1069 ASSERT_NO_ERROR(EC); 1070 1071 // Verify content 1072 EXPECT_EQ(StringRef(mfr.const_data()), Val); 1073 1074 // Unmap temp file 1075 fs::mapped_file_region m(FD, fs::mapped_file_region::readonly, Size, 0, EC); 1076 ASSERT_NO_ERROR(EC); 1077 ASSERT_EQ(close(FD), 0); 1078 } 1079 ASSERT_NO_ERROR(fs::remove(TempPath)); 1080 } 1081 1082 TEST(Support, NormalizePath) { 1083 using TestTuple = std::tuple<const char *, const char *, const char *>; 1084 std::vector<TestTuple> Tests; 1085 Tests.emplace_back("a", "a", "a"); 1086 Tests.emplace_back("a/b", "a\\b", "a/b"); 1087 Tests.emplace_back("a\\b", "a\\b", "a/b"); 1088 Tests.emplace_back("a\\\\b", "a\\\\b", "a\\\\b"); 1089 Tests.emplace_back("\\a", "\\a", "/a"); 1090 Tests.emplace_back("a\\", "a\\", "a/"); 1091 1092 for (auto &T : Tests) { 1093 SmallString<64> Win(std::get<0>(T)); 1094 SmallString<64> Posix(Win); 1095 path::native(Win, path::Style::windows); 1096 path::native(Posix, path::Style::posix); 1097 EXPECT_EQ(std::get<1>(T), Win); 1098 EXPECT_EQ(std::get<2>(T), Posix); 1099 } 1100 1101 #if defined(_WIN32) 1102 SmallString<64> PathHome; 1103 path::home_directory(PathHome); 1104 1105 const char *Path7a = "~/aaa"; 1106 SmallString<64> Path7(Path7a); 1107 path::native(Path7); 1108 EXPECT_TRUE(Path7.endswith("\\aaa")); 1109 EXPECT_TRUE(Path7.startswith(PathHome)); 1110 EXPECT_EQ(Path7.size(), PathHome.size() + strlen(Path7a + 1)); 1111 1112 const char *Path8a = "~"; 1113 SmallString<64> Path8(Path8a); 1114 path::native(Path8); 1115 EXPECT_EQ(Path8, PathHome); 1116 1117 const char *Path9a = "~aaa"; 1118 SmallString<64> Path9(Path9a); 1119 path::native(Path9); 1120 EXPECT_EQ(Path9, "~aaa"); 1121 1122 const char *Path10a = "aaa/~/b"; 1123 SmallString<64> Path10(Path10a); 1124 path::native(Path10); 1125 EXPECT_EQ(Path10, "aaa\\~\\b"); 1126 #endif 1127 } 1128 1129 TEST(Support, RemoveLeadingDotSlash) { 1130 StringRef Path1("././/foolz/wat"); 1131 StringRef Path2("./////"); 1132 1133 Path1 = path::remove_leading_dotslash(Path1); 1134 EXPECT_EQ(Path1, "foolz/wat"); 1135 Path2 = path::remove_leading_dotslash(Path2); 1136 EXPECT_EQ(Path2, ""); 1137 } 1138 1139 static std::string remove_dots(StringRef path, bool remove_dot_dot, 1140 path::Style style) { 1141 SmallString<256> buffer(path); 1142 path::remove_dots(buffer, remove_dot_dot, style); 1143 return buffer.str(); 1144 } 1145 1146 TEST(Support, RemoveDots) { 1147 EXPECT_EQ("foolz\\wat", 1148 remove_dots(".\\.\\\\foolz\\wat", false, path::Style::windows)); 1149 EXPECT_EQ("", remove_dots(".\\\\\\\\\\", false, path::Style::windows)); 1150 1151 EXPECT_EQ("a\\..\\b\\c", 1152 remove_dots(".\\a\\..\\b\\c", false, path::Style::windows)); 1153 EXPECT_EQ("b\\c", remove_dots(".\\a\\..\\b\\c", true, path::Style::windows)); 1154 EXPECT_EQ("c", remove_dots(".\\.\\c", true, path::Style::windows)); 1155 EXPECT_EQ("..\\a\\c", 1156 remove_dots("..\\a\\b\\..\\c", true, path::Style::windows)); 1157 EXPECT_EQ("..\\..\\a\\c", 1158 remove_dots("..\\..\\a\\b\\..\\c", true, path::Style::windows)); 1159 1160 SmallString<64> Path1(".\\.\\c"); 1161 EXPECT_TRUE(path::remove_dots(Path1, true, path::Style::windows)); 1162 EXPECT_EQ("c", Path1); 1163 1164 EXPECT_EQ("foolz/wat", 1165 remove_dots("././/foolz/wat", false, path::Style::posix)); 1166 EXPECT_EQ("", remove_dots("./////", false, path::Style::posix)); 1167 1168 EXPECT_EQ("a/../b/c", remove_dots("./a/../b/c", false, path::Style::posix)); 1169 EXPECT_EQ("b/c", remove_dots("./a/../b/c", true, path::Style::posix)); 1170 EXPECT_EQ("c", remove_dots("././c", true, path::Style::posix)); 1171 EXPECT_EQ("../a/c", remove_dots("../a/b/../c", true, path::Style::posix)); 1172 EXPECT_EQ("../../a/c", 1173 remove_dots("../../a/b/../c", true, path::Style::posix)); 1174 EXPECT_EQ("/a/c", remove_dots("/../../a/c", true, path::Style::posix)); 1175 EXPECT_EQ("/a/c", 1176 remove_dots("/../a/b//../././/c", true, path::Style::posix)); 1177 1178 SmallString<64> Path2("././c"); 1179 EXPECT_TRUE(path::remove_dots(Path2, true, path::Style::posix)); 1180 EXPECT_EQ("c", Path2); 1181 } 1182 1183 TEST(Support, ReplacePathPrefix) { 1184 SmallString<64> Path1("/foo"); 1185 SmallString<64> Path2("/old/foo"); 1186 SmallString<64> OldPrefix("/old"); 1187 SmallString<64> NewPrefix("/new"); 1188 SmallString<64> NewPrefix2("/longernew"); 1189 SmallString<64> EmptyPrefix(""); 1190 1191 SmallString<64> Path = Path1; 1192 path::replace_path_prefix(Path, OldPrefix, NewPrefix); 1193 EXPECT_EQ(Path, "/foo"); 1194 Path = Path2; 1195 path::replace_path_prefix(Path, OldPrefix, NewPrefix); 1196 EXPECT_EQ(Path, "/new/foo"); 1197 Path = Path2; 1198 path::replace_path_prefix(Path, OldPrefix, NewPrefix2); 1199 EXPECT_EQ(Path, "/longernew/foo"); 1200 Path = Path1; 1201 path::replace_path_prefix(Path, EmptyPrefix, NewPrefix); 1202 EXPECT_EQ(Path, "/new/foo"); 1203 Path = Path2; 1204 path::replace_path_prefix(Path, OldPrefix, EmptyPrefix); 1205 EXPECT_EQ(Path, "/foo"); 1206 } 1207 1208 TEST_F(FileSystemTest, OpenFileForRead) { 1209 // Create a temp file. 1210 int FileDescriptor; 1211 SmallString<64> TempPath; 1212 ASSERT_NO_ERROR( 1213 fs::createTemporaryFile("prefix", "temp", FileDescriptor, TempPath)); 1214 FileRemover Cleanup(TempPath); 1215 1216 // Make sure it exists. 1217 ASSERT_TRUE(sys::fs::exists(Twine(TempPath))); 1218 1219 // Open the file for read 1220 int FileDescriptor2; 1221 SmallString<64> ResultPath; 1222 ASSERT_NO_ERROR( 1223 fs::openFileForRead(Twine(TempPath), FileDescriptor2, &ResultPath)) 1224 1225 // If we succeeded, check that the paths are the same (modulo case): 1226 if (!ResultPath.empty()) { 1227 // The paths returned by createTemporaryFile and getPathFromOpenFD 1228 // should reference the same file on disk. 1229 fs::UniqueID D1, D2; 1230 ASSERT_NO_ERROR(fs::getUniqueID(Twine(TempPath), D1)); 1231 ASSERT_NO_ERROR(fs::getUniqueID(Twine(ResultPath), D2)); 1232 ASSERT_EQ(D1, D2); 1233 } 1234 1235 ::close(FileDescriptor); 1236 } 1237 1238 TEST_F(FileSystemTest, set_current_path) { 1239 SmallString<128> path; 1240 1241 ASSERT_NO_ERROR(fs::current_path(path)); 1242 ASSERT_NE(TestDirectory, path); 1243 1244 struct RestorePath { 1245 SmallString<128> path; 1246 RestorePath(const SmallString<128> &path) : path(path) {} 1247 ~RestorePath() { fs::set_current_path(path); } 1248 } restore_path(path); 1249 1250 ASSERT_NO_ERROR(fs::set_current_path(TestDirectory)); 1251 1252 ASSERT_NO_ERROR(fs::current_path(path)); 1253 1254 fs::UniqueID D1, D2; 1255 ASSERT_NO_ERROR(fs::getUniqueID(TestDirectory, D1)); 1256 ASSERT_NO_ERROR(fs::getUniqueID(path, D2)); 1257 ASSERT_EQ(D1, D2) << "D1: " << TestDirectory << "\nD2: " << path; 1258 } 1259 1260 TEST_F(FileSystemTest, permissions) { 1261 int FD; 1262 SmallString<64> TempPath; 1263 ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath)); 1264 FileRemover Cleanup(TempPath); 1265 1266 // Make sure it exists. 1267 ASSERT_TRUE(fs::exists(Twine(TempPath))); 1268 1269 auto CheckPermissions = [&](fs::perms Expected) { 1270 ErrorOr<fs::perms> Actual = fs::getPermissions(TempPath); 1271 return Actual && *Actual == Expected; 1272 }; 1273 1274 std::error_code NoError; 1275 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_all), NoError); 1276 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1277 1278 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::all_exe), NoError); 1279 EXPECT_TRUE(CheckPermissions(fs::all_read | fs::all_exe)); 1280 1281 #if defined(_WIN32) 1282 fs::perms ReadOnly = fs::all_read | fs::all_exe; 1283 EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError); 1284 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1285 1286 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError); 1287 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1288 1289 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError); 1290 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1291 1292 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError); 1293 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1294 1295 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError); 1296 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1297 1298 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError); 1299 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1300 1301 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError); 1302 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1303 1304 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError); 1305 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1306 1307 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError); 1308 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1309 1310 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError); 1311 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1312 1313 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError); 1314 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1315 1316 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError); 1317 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1318 1319 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError); 1320 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1321 1322 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError); 1323 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1324 1325 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError); 1326 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1327 1328 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError); 1329 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1330 1331 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError); 1332 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1333 1334 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError); 1335 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1336 1337 EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError); 1338 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1339 1340 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe | 1341 fs::set_gid_on_exe | 1342 fs::sticky_bit), 1343 NoError); 1344 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1345 1346 EXPECT_EQ(fs::setPermissions(TempPath, ReadOnly | fs::set_uid_on_exe | 1347 fs::set_gid_on_exe | 1348 fs::sticky_bit), 1349 NoError); 1350 EXPECT_TRUE(CheckPermissions(ReadOnly)); 1351 1352 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError); 1353 EXPECT_TRUE(CheckPermissions(fs::all_all)); 1354 #else 1355 EXPECT_EQ(fs::setPermissions(TempPath, fs::no_perms), NoError); 1356 EXPECT_TRUE(CheckPermissions(fs::no_perms)); 1357 1358 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_read), NoError); 1359 EXPECT_TRUE(CheckPermissions(fs::owner_read)); 1360 1361 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_write), NoError); 1362 EXPECT_TRUE(CheckPermissions(fs::owner_write)); 1363 1364 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_exe), NoError); 1365 EXPECT_TRUE(CheckPermissions(fs::owner_exe)); 1366 1367 EXPECT_EQ(fs::setPermissions(TempPath, fs::owner_all), NoError); 1368 EXPECT_TRUE(CheckPermissions(fs::owner_all)); 1369 1370 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_read), NoError); 1371 EXPECT_TRUE(CheckPermissions(fs::group_read)); 1372 1373 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_write), NoError); 1374 EXPECT_TRUE(CheckPermissions(fs::group_write)); 1375 1376 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_exe), NoError); 1377 EXPECT_TRUE(CheckPermissions(fs::group_exe)); 1378 1379 EXPECT_EQ(fs::setPermissions(TempPath, fs::group_all), NoError); 1380 EXPECT_TRUE(CheckPermissions(fs::group_all)); 1381 1382 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_read), NoError); 1383 EXPECT_TRUE(CheckPermissions(fs::others_read)); 1384 1385 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_write), NoError); 1386 EXPECT_TRUE(CheckPermissions(fs::others_write)); 1387 1388 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_exe), NoError); 1389 EXPECT_TRUE(CheckPermissions(fs::others_exe)); 1390 1391 EXPECT_EQ(fs::setPermissions(TempPath, fs::others_all), NoError); 1392 EXPECT_TRUE(CheckPermissions(fs::others_all)); 1393 1394 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read), NoError); 1395 EXPECT_TRUE(CheckPermissions(fs::all_read)); 1396 1397 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_write), NoError); 1398 EXPECT_TRUE(CheckPermissions(fs::all_write)); 1399 1400 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_exe), NoError); 1401 EXPECT_TRUE(CheckPermissions(fs::all_exe)); 1402 1403 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe), NoError); 1404 EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe)); 1405 1406 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_gid_on_exe), NoError); 1407 EXPECT_TRUE(CheckPermissions(fs::set_gid_on_exe)); 1408 1409 // Modern BSDs require root to set the sticky bit on files. 1410 #if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) 1411 EXPECT_EQ(fs::setPermissions(TempPath, fs::sticky_bit), NoError); 1412 EXPECT_TRUE(CheckPermissions(fs::sticky_bit)); 1413 1414 EXPECT_EQ(fs::setPermissions(TempPath, fs::set_uid_on_exe | 1415 fs::set_gid_on_exe | 1416 fs::sticky_bit), 1417 NoError); 1418 EXPECT_TRUE(CheckPermissions(fs::set_uid_on_exe | fs::set_gid_on_exe | 1419 fs::sticky_bit)); 1420 1421 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_read | fs::set_uid_on_exe | 1422 fs::set_gid_on_exe | 1423 fs::sticky_bit), 1424 NoError); 1425 EXPECT_TRUE(CheckPermissions(fs::all_read | fs::set_uid_on_exe | 1426 fs::set_gid_on_exe | fs::sticky_bit)); 1427 1428 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms), NoError); 1429 EXPECT_TRUE(CheckPermissions(fs::all_perms)); 1430 #endif // !FreeBSD && !NetBSD && !OpenBSD 1431 1432 EXPECT_EQ(fs::setPermissions(TempPath, fs::all_perms & ~fs::sticky_bit), 1433 NoError); 1434 EXPECT_TRUE(CheckPermissions(fs::all_perms & ~fs::sticky_bit)); 1435 #endif 1436 } 1437 1438 } // anonymous namespace 1439