[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