1/* fpurge - Flushing buffers of a FILE stream. */ 2 3/* Copyright (C) 2007 Free Software Foundation, Inc. 4 5 This file is part of GNU Bash, the Bourne Again SHell. 6 7 Bash is free software: you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation, either version 3 of the License, or 10 (at your option) any later version. 11 12 Bash is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Bash. If not, see <http://www.gnu.org/licenses/>. 19*/ 20 21#include <config.h> 22 23#include "stdc.h" 24 25#include <stdio.h> 26 27/* Specification. Same as in ../../externs.h. */ 28#define NEED_FPURGE_DECL 29#if HAVE_FPURGE 30# define fpurge _bash_fpurge 31#endif 32extern int fpurge __P((FILE *stream)); 33 34#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */ 35# include <stdio_ext.h> 36#endif 37#include <stdlib.h> 38 39int 40fpurge (FILE *fp) 41{ 42#if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */ 43 44 __fpurge (fp); 45 /* The __fpurge function does not have a return value. */ 46 return 0; 47 48#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, MacOS X */ 49 50 /* Call the system's fpurge function. */ 51# undef fpurge 52# if !HAVE_DECL_FPURGE 53 extern int fpurge (FILE *); 54# endif 55 int result = fpurge (fp); 56# if defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ 57 if (result == 0) 58 /* Correct the invariants that fpurge broke. 59 <stdio.h> on BSD systems says: 60 "The following always hold: if _flags & __SRD, _w is 0." 61 If this invariant is not fulfilled and the stream is read-write but 62 currently writing, subsequent putc or fputc calls will write directly 63 into the buffer, although they shouldn't be allowed to. */ 64 if ((fp->_flags & __SRD) != 0) 65 fp->_w = 0; 66# endif 67 return result; 68 69#else 70 71 /* Most systems provide FILE as a struct and the necessary bitmask in 72 <stdio.h>, because they need it for implementing getc() and putc() as 73 fast macros. */ 74# if defined _IO_ferror_unlocked /* GNU libc, BeOS */ 75 fp->_IO_read_end = fp->_IO_read_ptr; 76 fp->_IO_write_ptr = fp->_IO_write_base; 77 /* Avoid memory leak when there is an active ungetc buffer. */ 78 if (fp->_IO_save_base != NULL) 79 { 80 free (fp->_IO_save_base); 81 fp->_IO_save_base = NULL; 82 } 83 return 0; 84# elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ 85 fp->_p = fp->_bf._base; 86 fp->_r = 0; 87 fp->_w = ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ 88 ? fp->_bf._size 89 : 0); 90 /* Avoid memory leak when there is an active ungetc buffer. */ 91# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */ 92 /* See <http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> 93 and <http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup> */ 94# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub 95# else /* FreeBSD, MacOS X, Cygwin */ 96# define fp_ub fp->_ub 97# endif 98 if (fp_ub._base != NULL) 99 { 100 if (fp_ub._base != fp->_ubuf) 101 free (fp_ub._base); 102 fp_ub._base = NULL; 103 } 104 return 0; 105# elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ 106 fp->_ptr = fp->_base; 107 if (fp->_ptr != NULL) 108 fp->_cnt = 0; 109 return 0; 110# elif defined __UCLIBC__ /* uClibc */ 111# ifdef __STDIO_BUFFERS 112 if (fp->__modeflags & __FLAG_WRITING) 113 fp->__bufpos = fp->__bufstart; 114 else if (fp->__modeflags & (__FLAG_READONLY | __FLAG_READING)) 115 fp->__bufpos = fp->__bufread; 116# endif 117 return 0; 118# else 119 #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." 120# endif 121 122#endif 123} 124