[libcxx-commits] [PATCH] D106217: [libcxx] Fix create_directories returning false but actually creating the directories, if the path name is with trailing seperators

Cao Jingfan via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jul 22 11:11:46 PDT 2021


caojingfan updated this revision to Diff 360891.
caojingfan added a comment.

rewrite the fix in a more elegant way, also add more test cases


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D106217/new/

https://reviews.llvm.org/D106217

Files:
  libcxx/src/filesystem/operations.cpp
  libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp


Index: libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
===================================================================
--- libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
+++ libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.create_directories/create_directories.pass.cpp
@@ -150,6 +150,32 @@
                             fs::create_directories(path{}));
 }
 
+TEST_CASE(dest_is_with_trailing_sep) {
+  scoped_test_env env;
+
+  const struct {
+    const std::string dir_name;
+    const bool exists_before;
+    const bool create;
+    const bool exists_after;
+  } TEST_CASES[] = {{"dir1/", false, true, true},
+                    {"dir3//", false, true, true},
+                    {"dir1/dir2/dir3/", false, true, true},
+                    {"dir2//dir3///dir4////", false, true, true},
+                    {"/", true, false, true},
+                    {"./", true, false, true}};
+
+  for (const auto& TC : TEST_CASES) {
+    const path dir = env.make_env_path(TC.dir_name);
+    TEST_CHECK(!dir.has_filename());
+    TEST_CHECK(exists(dir) == TC.exists_before);
+    std::error_code ec = GetTestEC();
+    TEST_CHECK(fs::create_directories(dir, ec) == TC.create);
+    TEST_CHECK(!ec);
+    TEST_CHECK(exists(dir) == TC.exists_after);
+  }
+}
+
 #ifdef _WIN32
 TEST_CASE(nonexistent_root)
 {
Index: libcxx/src/filesystem/operations.cpp
===================================================================
--- libcxx/src/filesystem/operations.cpp
+++ libcxx/src/filesystem/operations.cpp
@@ -1007,13 +1007,18 @@
   else if (exists(st))
     return err.report(errc::file_exists);
 
-  const path parent = p.parent_path();
+  path m_p = p;
+  // removing trailing slashes
+  if (p.has_relative_path() && !p.has_filename())
+    m_p = p.parent_path();
+
+  const path parent = m_p.parent_path();
   if (!parent.empty()) {
     const file_status parent_st = status(parent, m_ec);
     if (not status_known(parent_st))
       return err.report(m_ec);
     if (not exists(parent_st)) {
-      if (parent == p)
+      if (parent == m_p)
         return err.report(errc::invalid_argument);
       __create_directories(parent, ec);
       if (ec && *ec) {
@@ -1022,7 +1027,7 @@
     } else if (not is_directory(parent_st))
       return err.report(errc::not_a_directory);
   }
-  bool ret = __create_directory(p, &m_ec);
+  bool ret = __create_directory(m_p, &m_ec);
   if (m_ec)
     return err.report(m_ec);
   return ret;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D106217.360891.patch
Type: text/x-patch
Size: 2553 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20210722/64d2cf35/attachment-0001.bin>


More information about the libcxx-commits mailing list