OSDN Git Service

Fix stdio read after EOF behavior.
authorElliott Hughes <enh@google.com>
Sat, 10 Oct 2015 00:57:26 +0000 (17:57 -0700)
committerElliott Hughes <enh@google.com>
Sat, 10 Oct 2015 00:57:26 +0000 (17:57 -0700)
Bug: https://code.google.com/p/android/issues/detail?id=184847
Change-Id: Ia20ce94007c2a09649f0763b1dc7ba959f2f618d

libc/Android.mk
libc/stdio/refill.c [moved from libc/upstream-openbsd/lib/libc/stdio/refill.c with 99% similarity]
tests/stdio_test.cpp

index 8322c26..140ec82 100644 (file)
@@ -59,6 +59,7 @@ libc_common_src_files := \
     bionic/system_properties_compat.c \
     stdio/findfp.c \
     stdio/fread.c \
+    stdio/refill.c \
     stdio/snprintf.c\
     stdio/sprintf.c \
     stdio/stdio.c \
@@ -458,7 +459,6 @@ libc_upstream_openbsd_ndk_src_files := \
     upstream-openbsd/lib/libc/stdio/puts.c \
     upstream-openbsd/lib/libc/stdio/putwc.c \
     upstream-openbsd/lib/libc/stdio/putwchar.c \
-    upstream-openbsd/lib/libc/stdio/refill.c \
     upstream-openbsd/lib/libc/stdio/remove.c \
     upstream-openbsd/lib/libc/stdio/rewind.c \
     upstream-openbsd/lib/libc/stdio/rget.c \
similarity index 99%
rename from libc/upstream-openbsd/lib/libc/stdio/refill.c
rename to libc/stdio/refill.c
index 165c72a..e87c7b9 100644 (file)
@@ -58,9 +58,11 @@ __srefill(FILE *fp)
 
        fp->_r = 0;             /* largely a convenience for callers */
 
+#if !defined(__ANDROID__)
        /* SysV does not make this test; take it out for compatibility */
        if (fp->_flags & __SEOF)
                return (EOF);
+#endif
 
        /* if not already reading, have to be reading and writing */
        if ((fp->_flags & __SRD) == 0) {
index 62677cd..afb1511 100644 (file)
@@ -1012,3 +1012,39 @@ TEST(stdio, fread_after_fseek) {
 
   fclose(fp);
 }
+
+// https://code.google.com/p/android/issues/detail?id=184847
+TEST(stdio, fread_EOF_184847) {
+  TemporaryFile tf;
+  char buf[6] = {0};
+
+  FILE* fw = fopen(tf.filename, "w");
+  ASSERT_TRUE(fw != nullptr);
+
+  FILE* fr = fopen(tf.filename, "r");
+  ASSERT_TRUE(fr != nullptr);
+
+  fwrite("a", 1, 1, fw);
+  fflush(fw);
+  ASSERT_EQ(1U, fread(buf, 1, 1, fr));
+  ASSERT_STREQ("a", buf);
+
+  // 'fr' is now at EOF.
+  ASSERT_EQ(0U, fread(buf, 1, 1, fr));
+  ASSERT_TRUE(feof(fr));
+
+  // Write some more...
+  fwrite("z", 1, 1, fw);
+  fflush(fw);
+
+  // ...and check that we can read it back.
+  // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.)
+  ASSERT_EQ(1U, fread(buf, 1, 1, fr));
+  ASSERT_STREQ("z", buf);
+
+  // But now we're done.
+  ASSERT_EQ(0U, fread(buf, 1, 1, fr));
+
+  fclose(fr);
+  fclose(fw);
+}