Blame lib/fpurge.c

Packit Service a2489d
/* Flushing buffers of a FILE stream.
Packit Service a2489d
   Copyright (C) 2007-2018 Free Software Foundation, Inc.
Packit Service a2489d
Packit Service a2489d
   This program is free software: you can redistribute it and/or modify
Packit Service a2489d
   it under the terms of the GNU General Public License as published by
Packit Service a2489d
   the Free Software Foundation; either version 3 of the License, or
Packit Service a2489d
   (at your option) any later version.
Packit Service a2489d
Packit Service a2489d
   This program is distributed in the hope that it will be useful,
Packit Service a2489d
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service a2489d
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service a2489d
   GNU General Public License for more details.
Packit Service a2489d
Packit Service a2489d
   You should have received a copy of the GNU General Public License
Packit Service a2489d
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service a2489d
Packit Service a2489d
#include <config.h>
Packit Service a2489d
Packit Service a2489d
/* Specification.  */
Packit Service a2489d
#include <stdio.h>
Packit Service a2489d
Packit Service a2489d
#if HAVE___FPURGE                   /* glibc >= 2.2, Haiku, Solaris >= 7, Android API >= 23 */
Packit Service a2489d
# include <stdio_ext.h>
Packit Service a2489d
#endif
Packit Service a2489d
#include <stdlib.h>
Packit Service a2489d
Packit Service a2489d
#include "stdio-impl.h"
Packit Service a2489d
Packit Service a2489d
int
Packit Service a2489d
fpurge (FILE *fp)
Packit Service a2489d
{
Packit Service a2489d
#if HAVE___FPURGE                   /* glibc >= 2.2, Haiku, Solaris >= 7, Android API >= 23, musl libc */
Packit Service a2489d
Packit Service a2489d
  __fpurge (fp);
Packit Service a2489d
  /* The __fpurge function does not have a return value.  */
Packit Service a2489d
  return 0;
Packit Service a2489d
Packit Service a2489d
#elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin 1.7 */
Packit Service a2489d
Packit Service a2489d
  /* Call the system's fpurge function.  */
Packit Service a2489d
# undef fpurge
Packit Service a2489d
# if !HAVE_DECL_FPURGE
Packit Service a2489d
  extern int fpurge (FILE *);
Packit Service a2489d
# endif
Packit Service a2489d
  int result = fpurge (fp);
Packit Service a2489d
# if defined __sferror || defined __DragonFly__ || defined __ANDROID__
Packit Service a2489d
  /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
Packit Service a2489d
  if (result == 0)
Packit Service a2489d
    /* Correct the invariants that fpurge broke.
Packit Service a2489d
       <stdio.h> on BSD systems says:
Packit Service a2489d
         "The following always hold: if _flags & __SRD, _w is 0."
Packit Service a2489d
       If this invariant is not fulfilled and the stream is read-write but
Packit Service a2489d
       currently reading, subsequent putc or fputc calls will write directly
Packit Service a2489d
       into the buffer, although they shouldn't be allowed to.  */
Packit Service a2489d
    if ((fp_->_flags & __SRD) != 0)
Packit Service a2489d
      fp_->_w = 0;
Packit Service a2489d
# endif
Packit Service a2489d
  return result;
Packit Service a2489d
Packit Service a2489d
#else
Packit Service a2489d
Packit Service a2489d
  /* Most systems provide FILE as a struct and the necessary bitmask in
Packit Service a2489d
     <stdio.h>, because they need it for implementing getc() and putc() as
Packit Service a2489d
     fast macros.  */
Packit Service a2489d
# if defined _IO_EOF_SEEN || defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1
Packit Service a2489d
  /* GNU libc, BeOS, Haiku, Linux libc5 */
Packit Service a2489d
  fp->_IO_read_end = fp->_IO_read_ptr;
Packit Service a2489d
  fp->_IO_write_ptr = fp->_IO_write_base;
Packit Service a2489d
  /* Avoid memory leak when there is an active ungetc buffer.  */
Packit Service a2489d
  if (fp->_IO_save_base != NULL)
Packit Service a2489d
    {
Packit Service a2489d
      free (fp->_IO_save_base);
Packit Service a2489d
      fp->_IO_save_base = NULL;
Packit Service a2489d
    }
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
Packit Service a2489d
  /* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Minix 3, Android */
Packit Service a2489d
  fp_->_p = fp_->_bf._base;
Packit Service a2489d
  fp_->_r = 0;
Packit Service a2489d
  fp_->_w = ((fp_->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */
Packit Service a2489d
             ? fp_->_bf._size
Packit Service a2489d
             : 0);
Packit Service a2489d
  /* Avoid memory leak when there is an active ungetc buffer.  */
Packit Service a2489d
  if (fp_ub._base != NULL)
Packit Service a2489d
    {
Packit Service a2489d
      if (fp_ub._base != fp_->_ubuf)
Packit Service a2489d
        free (fp_ub._base);
Packit Service a2489d
      fp_ub._base = NULL;
Packit Service a2489d
    }
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __EMX__              /* emx+gcc */
Packit Service a2489d
  fp->_ptr = fp->_buffer;
Packit Service a2489d
  fp->_rcount = 0;
Packit Service a2489d
  fp->_wcount = 0;
Packit Service a2489d
  fp->_ungetc_count = 0;
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __minix              /* Minix */
Packit Service a2489d
  fp->_ptr = fp->_buf;
Packit Service a2489d
  if (fp->_ptr != NULL)
Packit Service a2489d
    fp->_count = 0;
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined _IOERR               /* AIX, HP-UX, IRIX, OSF/1, Solaris, OpenServer, mingw, MSVC, NonStop Kernel, OpenVMS */
Packit Service a2489d
  fp_->_ptr = fp_->_base;
Packit Service a2489d
  if (fp_->_ptr != NULL)
Packit Service a2489d
    fp_->_cnt = 0;
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __UCLIBC__           /* uClibc */
Packit Service a2489d
#  ifdef __STDIO_BUFFERS
Packit Service a2489d
  if (fp->__modeflags & __FLAG_WRITING)
Packit Service a2489d
    fp->__bufpos = fp->__bufstart;
Packit Service a2489d
  else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING))
Packit Service a2489d
    fp->__bufpos = fp->__bufread;
Packit Service a2489d
#  endif
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __QNX__              /* QNX */
Packit Service a2489d
  fp->_Rback = fp->_Back + sizeof (fp->_Back);
Packit Service a2489d
  fp->_Rsave = NULL;
Packit Service a2489d
  if (fp->_Mode & 0x2000 /* _MWRITE */)
Packit Service a2489d
    /* fp->_Buf <= fp->_Next <= fp->_Wend */
Packit Service a2489d
    fp->_Next = fp->_Buf;
Packit Service a2489d
  else
Packit Service a2489d
    /* fp->_Buf <= fp->_Next <= fp->_Rend */
Packit Service a2489d
    fp->_Rend = fp->_Next;
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined __MINT__             /* Atari FreeMiNT */
Packit Service a2489d
  if (fp->__pushed_back)
Packit Service a2489d
    {
Packit Service a2489d
      fp->__bufp = fp->__pushback_bufp;
Packit Service a2489d
      fp->__pushed_back = 0;
Packit Service a2489d
    }
Packit Service a2489d
  /* Preserve the current file position.  */
Packit Service a2489d
  if (fp->__target != -1)
Packit Service a2489d
    fp->__target += fp->__bufp - fp->__buffer;
Packit Service a2489d
  fp->__bufp = fp->__buffer;
Packit Service a2489d
  /* Nothing in the buffer, next getc is nontrivial.  */
Packit Service a2489d
  fp->__get_limit = fp->__bufp;
Packit Service a2489d
  /* Nothing in the buffer, next putc is nontrivial.  */
Packit Service a2489d
  fp->__put_limit = fp->__buffer;
Packit Service a2489d
  return 0;
Packit Service a2489d
# elif defined EPLAN9               /* Plan9 */
Packit Service a2489d
  fp->rp = fp->wp = fp->lp = fp->buf;
Packit Service a2489d
  return 0;
Packit Service a2489d
# else
Packit Service a2489d
#  error "Please port gnulib fpurge.c to your platform! Look at the definitions of fflush, setvbuf and ungetc on your system, then report this to bug-gnulib."
Packit Service a2489d
# endif
Packit Service a2489d
Packit Service a2489d
#endif
Packit Service a2489d
}