|
@@ -25,6 +25,19 @@
|
|
|
*
|
|
|
* ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! */
|
|
|
|
|
|
+
|
|
|
+ * Changed fflush() behavior to no-op for r/w streams in read-mode.
|
|
|
+ * This falls under undefined behavior wrt ANSI/ISO C99, but
|
|
|
+ * SUSv3 seems to treat it as a no-op and it occurs in some apps.
|
|
|
+ * Fixed a problem with _stdio_fwrite() not checking for underlying
|
|
|
+ * write() failures.
|
|
|
+ * Fixed both _stdio_fwrite() and _stdio_fread() to make sure that
|
|
|
+ * the putc and getc macros were disabled if the stream was in
|
|
|
+ * and error state.
|
|
|
+ * The above changes should take care of a problem initially reported
|
|
|
+ * by "Steven J. Hill" <sjhill@realitydiluted.com>.
|
|
|
+ */
|
|
|
+
|
|
|
|
|
|
* and undef L_ctermid if defined. This is necessary as L_ctermid is
|
|
|
* a SUSv3 standard macro defined in stdio.h. */
|
|
@@ -1385,7 +1398,9 @@ size_t _stdio_fread(unsigned char *buffer, size_t bytes, register FILE *stream)
|
|
|
}
|
|
|
|
|
|
#ifdef __STDIO_GETC_MACRO
|
|
|
- if (!(stream->modeflags & (__FLAG_WIDE|__MASK_UNGOT|__MASK_BUFMODE))) {
|
|
|
+ if (!(stream->modeflags
|
|
|
+ & (__FLAG_WIDE|__MASK_UNGOT|__MASK_BUFMODE|__FLAG_ERROR))
|
|
|
+ ) {
|
|
|
stream->bufgetc = stream->bufread;
|
|
|
}
|
|
|
#endif
|
|
@@ -1565,6 +1580,7 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
|
|
|
|
|
|
{
|
|
|
const unsigned char *buf0 = buffer;
|
|
|
+ size_t write_count = 1;
|
|
|
|
|
|
if (!buffer) {
|
|
|
FFLUSH:
|
|
@@ -1578,9 +1594,9 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
|
|
|
}
|
|
|
|
|
|
{
|
|
|
- size_t rv = _stdio_WRITE(stream, p, count);
|
|
|
- p += rv;
|
|
|
- count -= rv;
|
|
|
+ write_count = _stdio_WRITE(stream, p, count);
|
|
|
+ p += write_count;
|
|
|
+ count -= write_count;
|
|
|
}
|
|
|
|
|
|
stream->bufpos = stream->bufstart;
|
|
@@ -1624,21 +1640,23 @@ size_t _stdio_fwrite(const unsigned char *buffer, size_t bytes,
|
|
|
--count;
|
|
|
}
|
|
|
|
|
|
- if (bytes) {
|
|
|
- goto FFLUSH;
|
|
|
- }
|
|
|
+ if (write_count) {
|
|
|
+ if (bytes) {
|
|
|
+ goto FFLUSH;
|
|
|
+ }
|
|
|
|
|
|
- if (stream->modeflags & __FLAG_LBF) {
|
|
|
- while (p < buffer) {
|
|
|
- if (*p++ == '\n') {
|
|
|
- goto FFLUSH;
|
|
|
+ if (stream->modeflags & __FLAG_LBF) {
|
|
|
+ while (p < buffer) {
|
|
|
+ if (*p++ == '\n') {
|
|
|
+ goto FFLUSH;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
#ifdef __STDIO_PUTC_MACRO
|
|
|
- if (!(stream->modeflags & (__FLAG_WIDE|__MASK_BUFMODE))) {
|
|
|
+ if (!(stream->modeflags & (__FLAG_WIDE|__MASK_BUFMODE|__FLAG_ERROR))) {
|
|
|
|
|
|
stream->bufputc = stream->bufend;
|
|
|
}
|
|
@@ -2127,13 +2145,11 @@ int fflush_unlocked(register FILE *stream)
|
|
|
if (_stdio_fwrite(NULL, 0, stream) > 0) {
|
|
|
rv = -1;
|
|
|
}
|
|
|
- } else if (stream->modeflags & (__FLAG_READONLY|__FLAG_READING)) {
|
|
|
-
|
|
|
+ } else if (stream->modeflags & __FLAG_READONLY) {
|
|
|
|
|
|
* in read-only mode.
|
|
|
* ANSI/ISO says behavior in this case is undefined but also says you
|
|
|
- * shouldn't flush a stream you were reading from.
|
|
|
- */
|
|
|
+ * shouldn't flush a stream you were reading from. */
|
|
|
stream->modeflags |= __FLAG_ERROR;
|
|
|
__set_errno(EBADF);
|
|
|
rv = -1;
|
|
@@ -2156,7 +2172,7 @@ int fflush_unlocked(register FILE *stream)
|
|
|
|
|
|
|
|
|
return ((stream != NULL)
|
|
|
- && (stream->modeflags & (__FLAG_READONLY|__FLAG_READING))
|
|
|
+ && (stream->modeflags & __FLAG_READONLY)
|
|
|
? ((stream->modeflags |= __FLAG_ERROR), __set_errno(EBADF), EOF)
|
|
|
: 0 );
|
|
|
|