This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
add fpurge
- From: Eric Blake <ebb9 at byu dot net>
- To: newlib at sources dot redhat dot com
- Date: Sat, 27 Jun 2009 12:49:26 -0600
- Subject: add fpurge
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Bash would like to use fpurge, as part of making file redirections to
builtin operators work correctly. It is not (yet) standardized, but does
provide some useful semantics. BSD has fpurge in <stdio.h>, Linux has
__fpurge (same behavior, but no return value) in <stdio_ext.h>.
OK to commit? I wrote this implementation from scratch using fflush.c as
a reference, then tested it in cygwin, and verified that it passes the
gnulib unit test for fpurge (some BSD implementations fail the gnulib unit
test, because they leave read-write FILEs in an inconsistent state,
otherwise I might have just copied a BSD version).
I'm not sure why my rebuilt Makefile.in diff is larger than I expected; I
used autoconf 2.59 and automake 1.9.6 as directed in README.
2009-06-27 Eric Blake <ebb9@byu.net>
Add fpurge.
* stdio/fpurge.c (fpurge, _fpurge_r): New file.
* libc/stdio/Makefile.am (ELIX_4_SOURCES, CHEWOUT_FILES, fpurge):
Build it.
* libc/stdio/Makefile.in: Regenerated.
* libc/include/stdio.h (fpurge, _fpurge_r): New declarations.
- --
Don't work too hard, make some time for fun as well!
Eric Blake ebb9@byu.net
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iEYEARECAAYFAkpGabYACgkQ84KuGfSFAYBQ9gCgvq3Vfbc+3FJA+vWqPWMq3KGh
CC0An0Kw+AJPPXYXloBaT6mf+l7mi3/4
=6wtg
-----END PGP SIGNATURE-----
? libc/autom4te.cache
Index: libc/include/stdio.h
===================================================================
RCS file: /cvs/src/src/newlib/libc/include/stdio.h,v
retrieving revision 1.57
diff -u -p -r1.57 stdio.h
--- libc/include/stdio.h 4 Apr 2009 15:44:19 -0000 1.57
+++ libc/include/stdio.h 27 Jun 2009 18:49:07 -0000
@@ -391,6 +391,7 @@ FILE * _EXFUN(_fopen_r, (struct _reent *
FILE * _EXFUN(_freopen_r, (struct _reent *, const char *, const char *, FILE *));
int _EXFUN(_fprintf_r, (struct _reent *, FILE *, const char *, ...)
_ATTRIBUTE ((__format__ (__printf__, 3, 4))));
+int _EXFUN(_fpurge_r, (struct _reent *, FILE *));
int _EXFUN(_fputc_r, (struct _reent *, int, FILE *));
int _EXFUN(_fputs_r, (struct _reent *, const char *, FILE *));
size_t _EXFUN(_fread_r, (struct _reent *, _PTR, size_t _size, size_t _n, FILE *));
@@ -482,6 +483,9 @@ int _EXFUN(_vsprintf_r, (struct _reent *
int _EXFUN(_vsscanf_r, (struct _reent *, const char *, const char *, __VALIST)
_ATTRIBUTE ((__format__ (__scanf__, 3, 0))));
+/* Other extensions. */
+
+int _EXFUN(fpurge, (FILE *));
ssize_t _EXFUN(__getdelim, (char **, size_t *, int, FILE *));
ssize_t _EXFUN(__getline, (char **, size_t *, FILE *));
Index: libc/stdio/Makefile.am
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.am,v
retrieving revision 1.31
diff -u -p -r1.31 Makefile.am
--- libc/stdio/Makefile.am 11 Mar 2009 11:53:22 -0000 1.31
+++ libc/stdio/Makefile.am 27 Jun 2009 18:49:07 -0000
@@ -121,6 +121,7 @@ ELIX_4_SOURCES = \
fgetws.c \
fmemopen.c \
fopencookie.c \
+ fpurge.c \
fputwc.c \
fputws.c \
funopen.c \
@@ -250,6 +251,7 @@ CHEWOUT_FILES = \
fmemopen.def \
fopen.def \
fopencookie.def \
+ fpurge.def \
fputc.def \
fputs.def \
fputwc.def \
@@ -331,6 +333,7 @@ $(lpfx)findfp.$(oext): local.h
$(lpfx)fmemopen.$(oext): local.h
$(lpfx)fopen.$(oext): local.h
$(lpfx)fopencookie.$(oext): local.h
+$(lpfx)fpurge.$(oext): local.h
$(lpfx)fputs.$(oext): fvwrite.h
$(lpfx)fputwc.$(oext): local.h
$(lpfx)fputws.$(oext): local.h fvwrite.h
Index: libc/stdio/Makefile.in
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/Makefile.in,v
retrieving revision 1.45
diff -u -p -r1.45 Makefile.in
--- libc/stdio/Makefile.in 11 Mar 2009 11:53:22 -0000 1.45
+++ libc/stdio/Makefile.in 27 Jun 2009 18:49:07 -0000
@@ -38,7 +38,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
-LIBOBJDIR =
DIST_COMMON = $(srcdir)/../../Makefile.shared $(srcdir)/Makefile.in \
$(srcdir)/Makefile.am
subdir = stdio
@@ -124,6 +123,7 @@ am__objects_1 = lib_a-clearerr.$(OBJEXT)
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fgetws.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fmemopen.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fopencookie.$(OBJEXT) \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fpurge.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fputwc.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-fputws.$(OBJEXT) \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ lib_a-funopen.$(OBJEXT) \
@@ -178,6 +178,7 @@ am__objects_4 = clearerr.lo fclose.lo fd
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetws.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fmemopen.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.lo \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fpurge.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputwc.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputws.lo \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.lo \
@@ -263,6 +264,8 @@ ENABLE_NEWLIB_ICONV_TRUE = @ENABLE_NEWLI
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
+HAVE_LONG_DOUBLE_FALSE = @HAVE_LONG_DOUBLE_FALSE@
+HAVE_LONG_DOUBLE_TRUE = @HAVE_LONG_DOUBLE_TRUE@
HAVE_POSIX_DIR_FALSE = @HAVE_POSIX_DIR_FALSE@
HAVE_POSIX_DIR_TRUE = @HAVE_POSIX_DIR_TRUE@
HAVE_SIGNAL_DIR_FALSE = @HAVE_SIGNAL_DIR_FALSE@
@@ -329,8 +332,20 @@ STRIP = @STRIP@
USE_LIBTOOL_FALSE = @USE_LIBTOOL_FALSE@
USE_LIBTOOL_TRUE = @USE_LIBTOOL_TRUE@
VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_AS = @ac_ct_AS@
ac_ct_CC = @ac_ct_CC@
+ac_ct_DLLTOOL = @ac_ct_DLLTOOL@
+ac_ct_DSYMUTIL = @ac_ct_DSYMUTIL@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_LIPO = @ac_ct_LIPO@
+ac_ct_NMEDIT = @ac_ct_NMEDIT@
+ac_ct_OBJDUMP = @ac_ct_OBJDUMP@
+ac_ct_OTOOL = @ac_ct_OTOOL@
+ac_ct_OTOOL64 = @ac_ct_OTOOL64@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_READELF = @ac_ct_READELF@
+ac_ct_STRIP = @ac_ct_STRIP@
aext = @aext@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
@@ -346,9 +361,6 @@ build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
exec_prefix = @exec_prefix@
extra_dir = @extra_dir@
host = @host@
@@ -356,14 +368,12 @@ host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
-htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
libm_machine_dir = @libm_machine_dir@
-localedir = @localedir@
localstatedir = @localstatedir@
lpfx = @lpfx@
lt_ECHO = @lt_ECHO@
@@ -373,10 +383,8 @@ mkdir_p = @mkdir_p@
newlib_basedir = @newlib_basedir@
oext = @oext@
oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
-psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
subdirs = @subdirs@
@@ -488,6 +496,7 @@ GENERAL_SOURCES = \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fgetws.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fmemopen.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fopencookie.c \
+@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fpurge.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputwc.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ fputws.c \
@ELIX_LEVEL_1_FALSE@@ELIX_LEVEL_2_FALSE@@ELIX_LEVEL_3_FALSE@ funopen.c \
@@ -558,6 +567,7 @@ CHEWOUT_FILES = \
fmemopen.def \
fopen.def \
fopencookie.def \
+ fpurge.def \
fputc.def \
fputs.def \
fputwc.def \
@@ -1268,6 +1278,12 @@ lib_a-fopencookie.o: fopencookie.c
lib_a-fopencookie.obj: fopencookie.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fopencookie.obj `if test -f 'fopencookie.c'; then $(CYGPATH_W) 'fopencookie.c'; else $(CYGPATH_W) '$(srcdir)/fopencookie.c'; fi`
+lib_a-fpurge.o: fpurge.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fpurge.o `test -f 'fpurge.c' || echo '$(srcdir)/'`fpurge.c
+
+lib_a-fpurge.obj: fpurge.c
+ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fpurge.obj `if test -f 'fpurge.c'; then $(CYGPATH_W) 'fpurge.c'; else $(CYGPATH_W) '$(srcdir)/fpurge.c'; fi`
+
lib_a-fputwc.o: fputwc.c
$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(lib_a_CFLAGS) $(CFLAGS) -c -o lib_a-fputwc.o `test -f 'fputwc.c' || echo '$(srcdir)/'`fputwc.c
@@ -1413,7 +1429,7 @@ clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
- -rm -f libtool config.lt
+ -rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
@@ -1627,6 +1643,7 @@ $(lpfx)findfp.$(oext): local.h
$(lpfx)fmemopen.$(oext): local.h
$(lpfx)fopen.$(oext): local.h
$(lpfx)fopencookie.$(oext): local.h
+$(lpfx)fpurge.$(oext): local.h
$(lpfx)fputs.$(oext): fvwrite.h
$(lpfx)fputwc.$(oext): local.h
$(lpfx)fputws.$(oext): local.h fvwrite.h
Index: libc/stdio/fpurge.c
===================================================================
RCS file: libc/stdio/fpurge.c
diff -N libc/stdio/fpurge.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ libc/stdio/fpurge.c 27 Jun 2009 18:49:07 -0000
@@ -0,0 +1,90 @@
+/* Copyright (C) 2009 Eric Blake
+ * Permission to use, copy, modify, and distribute this software
+ * is freely granted, provided that this notice is preserved.
+ */
+
+/*
+FUNCTION
+<<fpurge>>---discard pending file I/O
+
+INDEX
+ fpurge
+INDEX
+ _fpurge_r
+
+ANSI_SYNOPSIS
+ #include <stdio.h>
+ int fpurge(FILE *<[fp]>);
+
+ int _purge_r(struct _reent *<[reent]>, FILE *<[fp]>);
+
+DESCRIPTION
+Use <<fpurge>> to clear all buffers of the given stream. For output
+streams, this discards data not yet written to disk. For input streams,
+this discards any data from <<ungetc>> and any data retrieved from disk
+but not yet read via <<getc>>. This is more severe than <<fflush>>,
+and generally is only needed when manually altering the underlying file
+descriptor of a stream.
+
+The alternate function <<_fpurge_r>> is a reentrant version, where the
+extra argument <[reent]> is a pointer to a reentrancy structure, and
+<[fp]> must not be NULL.
+
+RETURNS
+<<fpurge>> returns <<0>> unless <[fp]> is not valid, in which case it
+returns <<EOF>> and sets <<errno>>.
+
+PORTABILITY
+These functions are not portable to any standard.
+
+No supporting OS subroutines are required.
+*/
+
+#include <_ansi.h>
+#include <stdio.h>
+#include <errno.h>
+#include "local.h"
+
+/* Discard I/O from a single file. */
+
+int
+_DEFUN(_fpurge_r, (ptr, fp),
+ struct _reent *ptr _AND
+ register FILE * fp)
+{
+ int t;
+
+ CHECK_INIT (ptr, fp);
+
+ _flockfile (fp);
+
+ t = fp->_flags;
+ if (!t)
+ {
+ ptr->_errno = EBADF;
+ _funlockfile (fp);
+ return EOF;
+ }
+ fp->_p = fp->_bf._base;
+ if ((t & __SWR) == 0)
+ {
+ fp->_r = 0;
+ if (HASUB (fp))
+ FREEUB (ptr, fp);
+ }
+ else
+ fp->_w = t & (__SLBF | __SNBF) ? 0 : fp->_bf._size;
+ _funlockfile (fp);
+ return 0;
+}
+
+#ifndef _REENT_ONLY
+
+int
+_DEFUN(fpurge, (fp),
+ register FILE * fp)
+{
+ return _fpurge_r (_REENT, fp);
+}
+
+#endif /* _REENT_ONLY */