Bug 12799 - fflush violates POSIX on seekable input streams
Summary: fflush violates POSIX on seekable input streams
Status: NEW
Alias: None
Product: glibc
Classification: Unclassified
Component: stdio (show other bugs)
Version: 2.13
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2011-05-23 17:14 UTC by Eric Blake
Modified: 2018-03-06 13:08 UTC (History)
3 users (show)

See Also:
Last reconfirmed:
fweimer: security-


Note You need to log in before you can comment on or make changes to this bug.
Description Eric Blake 2011-05-23 17:14:06 UTC
Per http://austingroupbugs.net/view.php?id=87, fflush is required to discard any ungetc() bytes and set the underlying file position to the point as though the pushed-back bytes had never been read.  That is, in the sequence:

{ app1; app2; } < seekable

if app1 reads one byte too many, then does ungetc() to push it back, then app2 should start reading at the byte that app1 did not want, rather than at the point that app1 reached before using ungetc().  More concretely, this program should exit with status 0, but right now it is exiting with status 7 (glibc is reading 'w' instead of ' ' after the fflush):

#define _POSIX_C_SOURCE 200112L
#include <stdio.h>
int main (void)
  FILE *f;
  char buffer[10];
  int fd;
  int c;

  f = fopen ("file", "w+");
  if (f == NULL)
    return 1;
  if (fputs ("hello world", f) == EOF)
    return 2;
  rewind (f);

  fd = fileno (f);
  if (fd < 0 || fread (buffer, 1, 5, f) != 5)
    return 3;
  c = fgetc (f);
  if (c != ' ')
    return 4;
  if (ungetc ('@', f) != '@')
    return 5;
  if (fflush (f) == EOF)
    return 6;
  if (fgetc (f) != c)
    return 7;
  return 0;

This program returns 0 on Solaris and Cygwin.
Comment 1 Eric Blake 2018-03-05 19:20:41 UTC
The removal of libio.h is making this bug all the more important to fix, so that gnulib can quit mucking around in glibc internals:

Is there a chance that it can be fixed for 2.28?