[libc-commits] [libc] 53c251b - [libc] Fix the return value of fread and fwrite.

Siva Chandra Reddy via libc-commits libc-commits at lists.llvm.org
Fri Oct 28 23:11:12 PDT 2022


Author: Siva Chandra Reddy
Date: 2022-10-29T06:10:35Z
New Revision: 53c251bd05704a3f76f660c3b715bf3f35e7d594

URL: https://github.com/llvm/llvm-project/commit/53c251bd05704a3f76f660c3b715bf3f35e7d594
DIFF: https://github.com/llvm/llvm-project/commit/53c251bd05704a3f76f660c3b715bf3f35e7d594.diff

LOG: [libc] Fix the return value of fread and fwrite.

They were previously returning the number of bytes read. They should
instead be returning the number of objects read.

Added: 
    

Modified: 
    libc/src/stdio/fread.cpp
    libc/src/stdio/fwrite.cpp
    libc/test/src/stdio/fileop_test.cpp

Removed: 
    


################################################################################
diff  --git a/libc/src/stdio/fread.cpp b/libc/src/stdio/fread.cpp
index c6a16e24beef6..779816ecfb220 100644
--- a/libc/src/stdio/fread.cpp
+++ b/libc/src/stdio/fread.cpp
@@ -16,8 +16,11 @@ namespace __llvm_libc {
 LLVM_LIBC_FUNCTION(size_t, fread,
                    (void *__restrict buffer, size_t size, size_t nmemb,
                     ::FILE *stream)) {
+  if (size == 0 || nmemb == 0)
+    return 0;
   return reinterpret_cast<__llvm_libc::File *>(stream)->read(buffer,
-                                                             size * nmemb);
+                                                             size * nmemb) /
+         size;
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/src/stdio/fwrite.cpp b/libc/src/stdio/fwrite.cpp
index 0ea0611370dc3..ffa555839bc71 100644
--- a/libc/src/stdio/fwrite.cpp
+++ b/libc/src/stdio/fwrite.cpp
@@ -16,8 +16,11 @@ namespace __llvm_libc {
 LLVM_LIBC_FUNCTION(size_t, fwrite,
                    (const void *__restrict buffer, size_t size, size_t nmemb,
                     ::FILE *stream)) {
+  if (size == 0 || nmemb == 0)
+    return 0;
   return reinterpret_cast<__llvm_libc::File *>(stream)->write(buffer,
-                                                              size * nmemb);
+                                                              size * nmemb) /
+         size;
 }
 
 } // namespace __llvm_libc

diff  --git a/libc/test/src/stdio/fileop_test.cpp b/libc/test/src/stdio/fileop_test.cpp
index 399cc799a9382..6f80163ae421a 100644
--- a/libc/test/src/stdio/fileop_test.cpp
+++ b/libc/test/src/stdio/fileop_test.cpp
@@ -122,3 +122,41 @@ TEST(LlvmLibcFILETest, FFlush) {
 
   ASSERT_EQ(__llvm_libc::fclose(file), 0);
 }
+
+TEST(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) {
+  using MyStruct = struct {
+    char c;
+    unsigned long long i;
+  };
+  constexpr MyStruct WRITE_DATA[] = {{'a', 1}, {'b', 2}, {'c', 3}};
+  constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct);
+  constexpr char FILENAME[] = "testdata/fread_fwrite.test";
+
+  FILE *file = __llvm_libc::fopen(FILENAME, "w");
+  ASSERT_FALSE(file == nullptr);
+  ASSERT_EQ(size_t(0), __llvm_libc::fwrite(WRITE_DATA, 0, 1, file));
+  ASSERT_EQ(WRITE_NMEMB, __llvm_libc::fwrite(WRITE_DATA, sizeof(MyStruct),
+                                             WRITE_NMEMB, file));
+  EXPECT_EQ(errno, 0);
+  ASSERT_EQ(__llvm_libc::fclose(file), 0);
+
+  file = __llvm_libc::fopen(FILENAME, "r");
+  ASSERT_FALSE(file == nullptr);
+  MyStruct read_data[WRITE_NMEMB];
+  ASSERT_EQ(size_t(0), __llvm_libc::fread(read_data, 0, 1, file));
+  ASSERT_EQ(WRITE_NMEMB,
+            __llvm_libc::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file));
+  EXPECT_EQ(errno, 0);
+  // Trying to read more should fetch nothing.
+  ASSERT_EQ(size_t(0),
+            __llvm_libc::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file));
+  EXPECT_EQ(errno, 0);
+  EXPECT_NE(__llvm_libc::feof(file), 0);
+  EXPECT_EQ(__llvm_libc::ferror(file), 0);
+  ASSERT_EQ(__llvm_libc::fclose(file), 0);
+  // Verify that the data which was read is correct.
+  for (size_t i = 0; i < WRITE_NMEMB; ++i) {
+    ASSERT_EQ(read_data[i].c, WRITE_DATA[i].c);
+    ASSERT_EQ(read_data[i].i, WRITE_DATA[i].i);
+  }
+}


        


More information about the libc-commits mailing list