Skip to content

Commit

Permalink
[Support] Report EISDIR when opening a directory (#79880)
Browse files Browse the repository at this point in the history
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
allow use of `read` on file descriptors for directories. This change
updates `readNativeFile` to produce `EISDIR` on AIX and z/OS when used
on a directory (instead of relying on the call to `read` to do so).

---------

Co-authored-by: Alison Zhang <alisonzhang@ibm.com>
Co-authored-by: James Henderson <46713263+jh7370@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 17, 2024
1 parent 0ab3f16 commit 678f19f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
9 changes: 9 additions & 0 deletions llvm/lib/Support/Unix/Path.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,15 @@ Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> 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;
}

Expand Down
2 changes: 0 additions & 2 deletions llvm/test/tools/llvm-symbolizer/input-file-err.test
Original file line number Diff line number Diff line change
@@ -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]]
Expand Down
2 changes: 0 additions & 2 deletions llvm/unittests/Support/CommandLineTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1117,15 +1117,13 @@ 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);
ASSERT_FALSE(Res);
ASSERT_EQ(2U, Argv.size());
ASSERT_STREQ(Argv[0], "clang");
ASSERT_STREQ(Argv[1], ADirExp.c_str());
#endif
}

TEST(CommandLineTest, SetDefaultValue) {
Expand Down
22 changes: 22 additions & 0 deletions llvm/unittests/Support/Path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,28 @@ TEST_F(FileSystemTest, OpenFileForRead) {
#endif
}

TEST_F(FileSystemTest, OpenDirectoryAsFileForRead) {
std::string Buf(5, '?');
Expected<fs::file_t> 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<size_t> 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;
Expand Down

0 comments on commit 678f19f

Please sign in to comment.