diff --git a/src/header/stdio/mod.rs b/src/header/stdio/mod.rs
index aa0da97d78a27cc800c0f1084130d9eac3a7acfe..bf145326f07ce6ace0d719b1c5f3523a4592aba8 100644
--- a/src/header/stdio/mod.rs
+++ b/src/header/stdio/mod.rs
@@ -71,20 +71,21 @@ pub struct FILE {
 }
 
 impl Read for FILE {
-    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
-        if !buf.is_empty() {
+    fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
+        if !out.is_empty() {
             if let Some(c) = self.unget.take() {
-                buf[0] = c;
+                out[0] = c;
                 return Ok(1);
             }
         }
 
-        if self.read_pos == self.read_size {
-            self.fill_buf()?;
-        }
+        let len = {
+            let buf = self.fill_buf()?;
+            let len = buf.len().min(out.len());
 
-        let len = buf.len().min(self.read_size);
-        buf[..len].copy_from_slice(&mut self.read_buf[..len]);
+            out[..len].copy_from_slice(&buf[..len]);
+            len
+        };
         self.consume(len);
         Ok(len)
     }
diff --git a/tests/Makefile b/tests/Makefile
index 34bc799f3d5b1a3bd804bc3246aa7d78589c151d..59e0834bc490a2096292ac1cfc651b21e13432f8 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -17,6 +17,7 @@ EXPECT_BINS=\
 	stdio/all \
 	stdio/buffer \
 	stdio/fgets \
+	stdio/fread \
 	stdio/freopen \
 	stdio/fseek \
 	stdio/fwrite \
diff --git a/tests/expected/stdio/fread.stderr b/tests/expected/stdio/fread.stderr
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/tests/expected/stdio/fread.stdout b/tests/expected/stdio/fread.stdout
new file mode 100644
index 0000000000000000000000000000000000000000..f3fbf213be64e57d0ff7473f681d6e142b3dddc3
--- /dev/null
+++ b/tests/expected/stdio/fread.stdout
@@ -0,0 +1,32 @@
+1
+22
+333
+4444
+55555
+666666
+7777777
+88888888
+999999999
+AAAAAAAAAA
+BBBBBBBBBBB
+CCCCCCCCCCCC
+DDDDDDDDDDDDD
+EEEEEEEEEEEEEE
+FFFFFFFFFFFFFFF
+0000000000000000
+11111111111111111
+222222222222222222
+3333333333333333333
+44444444444444444444
+555555555555555555555
+6666666666666666666666
+77777777777777777777777
+888888888888888888888888
+9999999999999999999999999
+AAAAAAAAAAAAAAAAAAAAAAAAAA
+BBBBBBBBBBBBBBBBBBBBBBBBBBB
+CCCCCCCCCCCCCCCCCCCCCCCCCCCC
+DDDDDDDDDDDDDDDDDDDDDDDDDDDDD
+EEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
+FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+00000000000000000000000000000000
diff --git a/tests/stdio/fread.c b/tests/stdio/fread.c
new file mode 100644
index 0000000000000000000000000000000000000000..40b6f69e579b0ac406e80a5c438c53544dbf8be4
--- /dev/null
+++ b/tests/stdio/fread.c
@@ -0,0 +1,21 @@
+#include <errno.h>
+#include <stdio.h>
+
+int main(int argc, char *argv[]) {
+    FILE *fp = fopen("stdio/fread.in", "rb");
+
+    char buf[33] = { 0 };
+    for (int i = 1; i <= 32; ++i) {
+        if (fread(buf, 1, i, fp) < 0) {
+            perror("fread");
+            return 0;
+        }
+        buf[i] = 0;
+
+        printf("%s\n", buf);
+    }
+
+    fclose(fp);
+
+    return 0;
+}
diff --git a/tests/stdio/fread.in b/tests/stdio/fread.in
new file mode 100644
index 0000000000000000000000000000000000000000..94b32220d79e4694cef7c6ae5eec43238b8f3d68
--- /dev/null
+++ b/tests/stdio/fread.in
@@ -0,0 +1 @@
+122333444455555666666777777788888888999999999AAAAAAAAAABBBBBBBBBBBCCCCCCCCCCCCDDDDDDDDDDDDDEEEEEEEEEEEEEEFFFFFFFFFFFFFFF0000000000000000111111111111111112222222222222222223333333333333333333444444444444444444445555555555555555555556666666666666666666666777777777777777777777778888888888888888888888889999999999999999999999999AAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000