Skip to content

Commit

Permalink
Filesystem/Windows: fix inconsistency in readNativeFileSlice API
Browse files Browse the repository at this point in the history
Summary:
The windows version implementation of readNativeFileSlice, was trying to
match the POSIX behavior of not treating EOF as an error, but it was
only handling the case of reading from a pipe. Attempting to read past
the end of a regular file returns a slightly different error code, which
needs to be handled too. This patch adds ERROR_HANDLE_EOF to the list of
error codes to be treated as an end of file, and adds some unit tests
for the API.

This issue was found while attempting to land D66224, which caused a bunch of
lldb tests to start failing on windows.

Reviewers: rnk, aganea

Subscribers: kristina, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66344

llvm-svn: 369269
  • Loading branch information
labath committed Aug 19, 2019
1 parent edfaee0 commit 08c77b9
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 3 deletions.
4 changes: 2 additions & 2 deletions llvm/lib/Support/Windows/Path.inc
Expand Up @@ -1229,8 +1229,8 @@ std::error_code readNativeFileImpl(file_t FileHandle, char *BufPtr, size_t Bytes
*BytesRead = BytesRead32;
if (!Success) {
DWORD Err = ::GetLastError();
// Pipe EOF is not an error.
if (Err == ERROR_BROKEN_PIPE)
// EOF is not an error.
if (Err == ERROR_BROKEN_PIPE || Err == ERROR_HANDLE_EOF)
return std::error_code();
return mapWindowsError(Err);
}
Expand Down
27 changes: 26 additions & 1 deletion llvm/unittests/Support/Path.cpp
Expand Up @@ -20,8 +20,9 @@
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include "gtest/gtest.h"
#include "llvm/Testing/Support/Error.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"

#ifdef _WIN32
#include "llvm/ADT/ArrayRef.h"
Expand Down Expand Up @@ -1513,6 +1514,30 @@ TEST_F(FileSystemTest, ReadWriteFileCanReadOrWrite) {
verifyWrite(FD, "Buzz", true);
}

TEST_F(FileSystemTest, readNativeFileSlice) {
char Data[10] = {'0', '1', '2', '3', '4', 0, 0, 0, 0, 0};
createFileWithData(NonExistantFile, false, fs::CD_CreateNew,
StringRef(Data, 5));
FileRemover Cleanup(NonExistantFile);
Expected<fs::file_t> FD = fs::openNativeFileForRead(NonExistantFile);
ASSERT_THAT_EXPECTED(FD, Succeeded());
char Buf[10];
const auto &Read = [&](size_t Offset,
size_t ToRead) -> Expected<ArrayRef<char>> {
std::memset(Buf, 0x47, sizeof(Buf));
if (std::error_code EC = fs::readNativeFileSlice(
*FD, makeMutableArrayRef(Buf, ToRead), Offset))
return errorCodeToError(EC);
return makeArrayRef(Buf, ToRead);
};
EXPECT_THAT_EXPECTED(Read(0, 5), HasValue(makeArrayRef(Data + 0, 5)));
EXPECT_THAT_EXPECTED(Read(0, 3), HasValue(makeArrayRef(Data + 0, 3)));
EXPECT_THAT_EXPECTED(Read(2, 3), HasValue(makeArrayRef(Data + 2, 3)));
EXPECT_THAT_EXPECTED(Read(0, 6), HasValue(makeArrayRef(Data + 0, 6)));
EXPECT_THAT_EXPECTED(Read(2, 6), HasValue(makeArrayRef(Data + 2, 6)));
EXPECT_THAT_EXPECTED(Read(5, 5), HasValue(makeArrayRef(Data + 5, 5)));
}

TEST_F(FileSystemTest, is_local) {
bool TestDirectoryIsLocal;
ASSERT_NO_ERROR(fs::is_local(TestDirectory, TestDirectoryIsLocal));
Expand Down

0 comments on commit 08c77b9

Please sign in to comment.