Path.cpp 63 KB

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