[llvm] [Support] Report EISDIR when opening a directory (PR #79880)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 29 10:29:29 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-binary-utilities

Author: None (azhan92)

<details>
<summary>Changes</summary>

The test `llvm/unittests/Support/CommandLineTest.cpp` that handles errors in expansion of response files was previously disabled for AIX. Originally the code was dependent on read returning EISDIR which occurs on platforms such as Linux. However, other platforms such as AIX follow POSIX in reporting EISDIR only if write access is requested when opening a directory as a file. This change introduces an implementation that checks the validity of the path in `llvm/lib/Support/CommandLine.cpp` instead of relying on read.



---
Full diff: https://github.com/llvm/llvm-project/pull/79880.diff


4 Files Affected:

- (modified) llvm/lib/Support/Unix/Path.inc (+7) 
- (modified) llvm/test/tools/llvm-symbolizer/input-file-err.test (-2) 
- (modified) llvm/unittests/Support/CommandLineTest.cpp (-2) 
- (modified) llvm/unittests/Support/Path.cpp (+16) 


``````````diff
diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc
index 9f89d63bb0fda84..fe8af76bd4d6ada 100644
--- a/llvm/lib/Support/Unix/Path.inc
+++ b/llvm/lib/Support/Unix/Path.inc
@@ -1024,6 +1024,13 @@ std::error_code openFile(const Twine &Name, int &ResultFD,
   auto Open = [&]() { return ::open(P.begin(), OpenFlags, Mode); };
   if ((ResultFD = sys::RetryAfterSignal(-1, Open)) < 0)
     return std::error_code(errno, std::generic_category());
+  if (Access == FA_Read) {
+    struct stat Status;    
+    if (fstat(ResultFD, &Status) == -1)
+      return std::error_code(errno, std::generic_category());
+    if (S_ISDIR(Status.st_mode))
+      return make_error_code(errc::is_a_directory);
+  } 
 #ifndef O_CLOEXEC
   if (!(Flags & OF_ChildInherit)) {
     int r = fcntl(ResultFD, F_SETFD, FD_CLOEXEC);
diff --git a/llvm/test/tools/llvm-symbolizer/input-file-err.test b/llvm/test/tools/llvm-symbolizer/input-file-err.test
index df14da2f433c012..76115b513470b9c 100644
--- a/llvm/test/tools/llvm-symbolizer/input-file-err.test
+++ b/llvm/test/tools/llvm-symbolizer/input-file-err.test
@@ -1,5 +1,3 @@
-Failing on AIX due to D153595. The test expects a different error message from the one given on AIX.
-XFAIL: target={{.*}}-aix{{.*}}
 RUN: not llvm-addr2line -e %p/Inputs/nonexistent 0x12 2>&1 | FileCheck %s --check-prefix=CHECK-NONEXISTENT-A2L -DMSG=%errc_ENOENT
 RUN: not llvm-addr2line -e %p/Inputs/nonexistent 2>&1 | FileCheck %s --check-prefix=CHECK-NONEXISTENT-A2L -DMSG=%errc_ENOENT
 CHECK-NONEXISTENT-A2L: llvm-addr2line{{.*}}: error: '{{.*}}Inputs/nonexistent': [[MSG]]
diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp
index bbeb9d5dc19bda1..23f6081cd32a455 100644
--- a/llvm/unittests/Support/CommandLineTest.cpp
+++ b/llvm/unittests/Support/CommandLineTest.cpp
@@ -1117,7 +1117,6 @@ TEST(CommandLineTest, BadResponseFile) {
   ASSERT_STREQ(Argv[0], "clang");
   ASSERT_STREQ(Argv[1], AFileExp.c_str());
 
-#if !defined(_AIX) && !defined(__MVS__)
   std::string ADirExp = std::string("@") + std::string(ADir.path());
   Argv = {"clang", ADirExp.c_str()};
   Res = cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Argv);
@@ -1125,7 +1124,6 @@ TEST(CommandLineTest, BadResponseFile) {
   ASSERT_EQ(2U, Argv.size());
   ASSERT_STREQ(Argv[0], "clang");
   ASSERT_STREQ(Argv[1], ADirExp.c_str());
-#endif
 }
 
 TEST(CommandLineTest, SetDefaultValue) {
diff --git a/llvm/unittests/Support/Path.cpp b/llvm/unittests/Support/Path.cpp
index 837ca03216f87ab..604a8803f60e691 100644
--- a/llvm/unittests/Support/Path.cpp
+++ b/llvm/unittests/Support/Path.cpp
@@ -1296,6 +1296,22 @@ TEST_F(FileSystemTest, UTF8ToUTF16DirectoryIteration) {
 }
 #endif
 
+TEST_F(FileSystemTest, OpenDirectoryAsFile) {
+  ASSERT_NO_ERROR(fs::create_directory(Twine(TestDirectory)));
+  ASSERT_EQ(fs::create_directory(Twine(TestDirectory), false),
+            errc::file_exists);
+
+  int FD;
+  std::error_code EC;
+  EC = fs::openFileForRead(Twine(TestDirectory), FD);
+  ASSERT_EQ(EC, errc::is_a_directory);
+  EC = fs::openFileForWrite(Twine(TestDirectory), FD);
+  ASSERT_EQ(EC, errc::is_a_directory);
+
+  ASSERT_NO_ERROR(fs::remove_directories(Twine(TestDirectory)));
+  ::close(FD);
+}
+
 TEST_F(FileSystemTest, Remove) {
   SmallString<64> BaseDir;
   SmallString<64> Paths[4];

``````````

</details>


https://github.com/llvm/llvm-project/pull/79880


More information about the llvm-commits mailing list