Optimized fread.

This makes us competitive with glibc for fully-buffered and unbuffered reads,
except in single-threaded situations where glibc avoids locking, but since
we're never really single-threaded anyway, that isn't a priority.

Bug: 18593728
Change-Id: Ib776bfba422ccf46209581fc0dc54f3567645b8f
diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp
index de5eea3..6d7e72b 100644
--- a/tests/stdio_test.cpp
+++ b/tests/stdio_test.cpp
@@ -888,3 +888,25 @@
     ASSERT_EQ('\xff', buf[i]);
   }
 }
+
+TEST(fread, fread_EOF) {
+  const char* digits = "0123456789";
+  FILE* fp = fmemopen((char*) digits, sizeof(digits), "r");
+
+  // Try to read too much, but little enough that it still fits in the FILE's internal buffer.
+  char buf1[4 * 4];
+  memset(buf1, 0, sizeof(buf1));
+  ASSERT_EQ(2U, fread(buf1, 4, 4, fp));
+  ASSERT_STREQ(buf1, "01234567");
+  ASSERT_TRUE(feof(fp));
+
+  rewind(fp);
+
+  char buf2[4 * 4];
+  memset(buf2, 0, sizeof(buf2));
+  ASSERT_EQ(2U, fread(buf2, 4, 4096, fp));
+  ASSERT_STREQ(buf2, "01234567");
+  ASSERT_TRUE(feof(fp));
+
+  fclose(fp);
+}