Skip to content

Commit 53c251b

Browse files
author
Siva Chandra Reddy
committed
[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.
1 parent 8b1865b commit 53c251b

File tree

3 files changed

+46
-2
lines changed

3 files changed

+46
-2
lines changed

libc/src/stdio/fread.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ namespace __llvm_libc {
1616
LLVM_LIBC_FUNCTION(size_t, fread,
1717
(void *__restrict buffer, size_t size, size_t nmemb,
1818
::FILE *stream)) {
19+
if (size == 0 || nmemb == 0)
20+
return 0;
1921
return reinterpret_cast<__llvm_libc::File *>(stream)->read(buffer,
20-
size * nmemb);
22+
size * nmemb) /
23+
size;
2124
}
2225

2326
} // namespace __llvm_libc

libc/src/stdio/fwrite.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@ namespace __llvm_libc {
1616
LLVM_LIBC_FUNCTION(size_t, fwrite,
1717
(const void *__restrict buffer, size_t size, size_t nmemb,
1818
::FILE *stream)) {
19+
if (size == 0 || nmemb == 0)
20+
return 0;
1921
return reinterpret_cast<__llvm_libc::File *>(stream)->write(buffer,
20-
size * nmemb);
22+
size * nmemb) /
23+
size;
2124
}
2225

2326
} // namespace __llvm_libc

libc/test/src/stdio/fileop_test.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,41 @@ TEST(LlvmLibcFILETest, FFlush) {
122122

123123
ASSERT_EQ(__llvm_libc::fclose(file), 0);
124124
}
125+
126+
TEST(LlvmLibcFILETest, FOpenFWriteSizeGreaterThanOne) {
127+
using MyStruct = struct {
128+
char c;
129+
unsigned long long i;
130+
};
131+
constexpr MyStruct WRITE_DATA[] = {{'a', 1}, {'b', 2}, {'c', 3}};
132+
constexpr size_t WRITE_NMEMB = sizeof(WRITE_DATA) / sizeof(MyStruct);
133+
constexpr char FILENAME[] = "testdata/fread_fwrite.test";
134+
135+
FILE *file = __llvm_libc::fopen(FILENAME, "w");
136+
ASSERT_FALSE(file == nullptr);
137+
ASSERT_EQ(size_t(0), __llvm_libc::fwrite(WRITE_DATA, 0, 1, file));
138+
ASSERT_EQ(WRITE_NMEMB, __llvm_libc::fwrite(WRITE_DATA, sizeof(MyStruct),
139+
WRITE_NMEMB, file));
140+
EXPECT_EQ(errno, 0);
141+
ASSERT_EQ(__llvm_libc::fclose(file), 0);
142+
143+
file = __llvm_libc::fopen(FILENAME, "r");
144+
ASSERT_FALSE(file == nullptr);
145+
MyStruct read_data[WRITE_NMEMB];
146+
ASSERT_EQ(size_t(0), __llvm_libc::fread(read_data, 0, 1, file));
147+
ASSERT_EQ(WRITE_NMEMB,
148+
__llvm_libc::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file));
149+
EXPECT_EQ(errno, 0);
150+
// Trying to read more should fetch nothing.
151+
ASSERT_EQ(size_t(0),
152+
__llvm_libc::fread(read_data, sizeof(MyStruct), WRITE_NMEMB, file));
153+
EXPECT_EQ(errno, 0);
154+
EXPECT_NE(__llvm_libc::feof(file), 0);
155+
EXPECT_EQ(__llvm_libc::ferror(file), 0);
156+
ASSERT_EQ(__llvm_libc::fclose(file), 0);
157+
// Verify that the data which was read is correct.
158+
for (size_t i = 0; i < WRITE_NMEMB; ++i) {
159+
ASSERT_EQ(read_data[i].c, WRITE_DATA[i].c);
160+
ASSERT_EQ(read_data[i].i, WRITE_DATA[i].i);
161+
}
162+
}

0 commit comments

Comments
 (0)