[PATCH] D153051: [Support][Unix] create_directory should fail if the path is not directory

Steven Wu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 15 10:05:51 PDT 2023


steven_wu created this revision.
steven_wu added a reviewer: Bigcheese.
Herald added subscribers: ributzka, hiraditya.
Herald added a project: All.
steven_wu requested review of this revision.
Herald added a project: LLVM.

When `create_directory` is called with `IngoreExisting` is true, the function
will return success if the path provided exists, no matter if that is a
directory or not.

At the same time, the caller of the function would expect that if the
function returns success, the path provided should be a directory. Update
the function so it matches the expectation and caller doesn't need to
check if the path is a directory before using it.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D153051

Files:
  llvm/lib/Support/Unix/Path.inc
  llvm/unittests/Support/Path.cpp


Index: llvm/unittests/Support/Path.cpp
===================================================================
--- llvm/unittests/Support/Path.cpp
+++ llvm/unittests/Support/Path.cpp
@@ -1012,6 +1012,14 @@
 
   // Restore umask to be safe.
   ::umask(OldUmask);
+
+  // Test create directory on top of a file.
+  int FD;
+  SmallString<64> TempPath;
+  ASSERT_NO_ERROR(fs::createTemporaryFile("prefix", "temp", FD, TempPath));
+  ::close(FD);
+  ASSERT_EQ(fs::create_directory(Twine(TempPath)), errc::file_exists);
+
 #endif
 
 #ifdef _WIN32
Index: llvm/lib/Support/Unix/Path.inc
===================================================================
--- llvm/lib/Support/Unix/Path.inc
+++ llvm/lib/Support/Unix/Path.inc
@@ -409,8 +409,15 @@
   StringRef p = path.toNullTerminatedStringRef(path_storage);
 
   if (::mkdir(p.begin(), Perms) == -1) {
-    if (errno != EEXIST || !IgnoreExisting)
-      return std::error_code(errno, std::generic_category());
+    if (errno == EEXIST && IgnoreExisting) {
+      // Only ignore existing directory.
+      bool is_dir;
+      if (std::error_code ec = is_directory(p, is_dir))
+        return ec;
+      if (is_dir)
+        return std::error_code();
+    }
+    return std::error_code(errno, std::generic_category());
   }
 
   return std::error_code();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D153051.531812.patch
Type: text/x-patch
Size: 1293 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230615/abeb4e51/attachment.bin>


More information about the llvm-commits mailing list