From 8ab433df132aa59db08b4548155d72574ad06421 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 9 Oct 2015 17:57:26 -0700 Subject: [PATCH] Fix stdio read after EOF behavior. Bug: https://code.google.com/p/android/issues/detail?id=184847 Change-Id: Ia20ce94007c2a09649f0763b1dc7ba959f2f618d --- libc/Android.mk | 2 +- .../lib/libc => }/stdio/refill.c | 2 ++ tests/stdio_test.cpp | 36 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) rename libc/{upstream-openbsd/lib/libc => }/stdio/refill.c (99%) diff --git a/libc/Android.mk b/libc/Android.mk index 8322c26c4..140ec82d3 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -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 \ diff --git a/libc/upstream-openbsd/lib/libc/stdio/refill.c b/libc/stdio/refill.c similarity index 99% rename from libc/upstream-openbsd/lib/libc/stdio/refill.c rename to libc/stdio/refill.c index 165c72a64..e87c7b93e 100644 --- a/libc/upstream-openbsd/lib/libc/stdio/refill.c +++ b/libc/stdio/refill.c @@ -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) { diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp index 62677cdff..afb1511fb 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -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); +}