Browse Source

Change 'undefined behavior' of fflush() on readonly or reading streams
to match that of current glibc; i.e. don't do anything and return success.
Apparently, php calls fflush() on a file opened as readonly before trying
to read. Eventually I'll add some config options to flag this and several
other instances of nonportable code.

Manuel Novoa III 22 years ago
parent
commit
dba553769e
1 changed files with 18 additions and 8 deletions
  1. 18 8
      libc/stdio/stdio.c

+ 18 - 8
libc/stdio/stdio.c

@@ -2210,14 +2210,18 @@ int fflush_unlocked(register FILE *stream)
 		if (_stdio_fwrite(NULL, 0, stream) > 0) { /* flush buffer contents. */
 		if (_stdio_fwrite(NULL, 0, stream) > 0) { /* flush buffer contents. */
 			rv = -1;			/* Not all chars written. */
 			rv = -1;			/* Not all chars written. */
 		}
 		}
-	} else if (stream->modeflags & __FLAG_READONLY) {
+#ifdef __UCLIBC_MJN3_ONLY__
-		/* According to info, glibc returns an error when the file is opened
+#warning add option to test for undefined behavior of fflush
-		 * in read-only mode.
+#endif /* __UCLIBC_MJN3_ONLY__ */
-		 * ANSI/ISO says behavior in this case is undefined but also says you
+#if 0
-		 * shouldn't flush a stream you were reading from. */
+	} else if (stream->modeflags & (__FLAG_READING|__FLAG_READONLY)) {
-		stream->modeflags |= __FLAG_ERROR; /* TODO - check glibc behavior */
+		/* ANSI/ISO says behavior in this case is undefined but also says you
+		 * shouldn't flush a stream you were reading from.  As usual, glibc
+		 * caters to broken programs and simply ignores this. */
+		stream->modeflags |= __FLAG_ERROR;
 		__set_errno(EBADF);
 		__set_errno(EBADF);
 		rv = -1;
 		rv = -1;
+#endif
 	}
 	}
 
 
 #ifndef NDEBUG
 #ifndef NDEBUG
@@ -2235,11 +2239,17 @@ int fflush_unlocked(register FILE *stream)
 	}
 	}
 #endif
 #endif
 
 
-	/* TODO -- check glibc behavior regarding error indicator */
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning add option to test for undefined behavior of fflush
+#endif /* __UCLIBC_MJN3_ONLY__ */
+#if 0
 	return ((stream != NULL)
 	return ((stream != NULL)
-			&& (stream->modeflags & __FLAG_READONLY)
+			&& (stream->modeflags & (__FLAG_READING|__FLAG_READONLY))
 			? ((stream->modeflags |= __FLAG_ERROR), __set_errno(EBADF), EOF)
 			? ((stream->modeflags |= __FLAG_ERROR), __set_errno(EBADF), EOF)
 			: 0 );
 			: 0 );
+#else
+	return 0;
+#endif
 
 
 #endif /* __STDIO_BUFFERS */
 #endif /* __STDIO_BUFFERS */
 }
 }