[PATCH] D66344: Filesystem/Windows: fix inconsistency in readNativeFileSlice API

Pavel Labath via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 16 06:09:32 PDT 2019


labath created this revision.
labath added reviewers: rnk, aganea.
Herald added a subscriber: kristina.
Herald added a project: LLVM.

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 <https://reviews.llvm.org/D66224>, which caused a bunch of
lldb tests to start failing on windows.


Repository:
  rL LLVM

https://reviews.llvm.org/D66344

Files:
  lib/Support/Windows/Path.inc
  unittests/Support/Path.cpp


Index: unittests/Support/Path.cpp
===================================================================
--- unittests/Support/Path.cpp
+++ unittests/Support/Path.cpp
@@ -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"
@@ -1513,6 +1514,30 @@
   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, 0, 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));
Index: lib/Support/Windows/Path.inc
===================================================================
--- lib/Support/Windows/Path.inc
+++ lib/Support/Windows/Path.inc
@@ -1229,8 +1229,8 @@
   *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);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66344.215577.patch
Type: text/x-patch
Size: 2352 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190816/9308d32d/attachment.bin>


More information about the llvm-commits mailing list