This is the mail archive of the newlib@sourceware.org mailing list for the newlib project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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 */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]