diff --git a/llvm/lib/Support/Unix/Path.inc b/llvm/lib/Support/Unix/Path.inc index 968e2c459f3fb..6e679f74869f0 100644 --- a/llvm/lib/Support/Unix/Path.inc +++ b/llvm/lib/Support/Unix/Path.inc @@ -1191,6 +1191,15 @@ Expected readNativeFile(file_t FD, MutableArrayRef Buf) { ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Size); if (ssize_t(NumRead) == -1) return errorCodeToError(errnoAsErrorCode()); +// The underlying operation on these platforms allow opening directories +// for reading in more cases than other platforms. +#if defined(__MVS__) || defined(_AIX) + struct stat Status; + if (fstat(FD, &Status) == -1) + return errorCodeToError(errnoAsErrorCode()); + if (S_ISDIR(Status.st_mode)) + return errorCodeToError(make_error_code(errc::is_a_directory)); +#endif return NumRead; } diff --git a/llvm/test/tools/llvm-symbolizer/input-file-err.test b/llvm/test/tools/llvm-symbolizer/input-file-err.test index df14da2f433c0..76115b513470b 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 bbeb9d5dc19bd..23f6081cd32a4 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 837ca03216f87..bdae7a8ee4b55 100644 --- a/llvm/unittests/Support/Path.cpp +++ b/llvm/unittests/Support/Path.cpp @@ -1757,6 +1757,28 @@ TEST_F(FileSystemTest, OpenFileForRead) { #endif } +TEST_F(FileSystemTest, OpenDirectoryAsFileForRead) { + std::string Buf(5, '?'); + Expected FD = fs::openNativeFileForRead(TestDirectory); +#ifdef _WIN32 + EXPECT_EQ(errorToErrorCode(FD.takeError()), errc::is_a_directory); +#else + ASSERT_THAT_EXPECTED(FD, Succeeded()); + auto Close = make_scope_exit([&] { fs::closeFile(*FD); }); + Expected BytesRead = + fs::readNativeFile(*FD, MutableArrayRef(&*Buf.begin(), Buf.size())); + EXPECT_EQ(errorToErrorCode(BytesRead.takeError()), errc::is_a_directory); +#endif +} + +TEST_F(FileSystemTest, OpenDirectoryAsFileForWrite) { + int FD; + std::error_code EC = fs::openFileForWrite(Twine(TestDirectory), FD); + if (!EC) + ::close(FD); + EXPECT_EQ(EC, errc::is_a_directory); +} + static void createFileWithData(const Twine &Path, bool ShouldExistBefore, fs::CreationDisposition Disp, StringRef Data) { int FD;