diff --git a/newlib/ChangeLog b/newlib/ChangeLog index aab9fb40e..69ef08b8a 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,13 @@ +2009-07-03 Eric Blake + + Add fpurge. + * libc/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. + * libc/stdio/stdio.tex: Build documentation. + 2009-06-23 Jeff Johnston * Makefile.am (MATHOBJS_IN_LIBC): Add s_fpclassify and @@ -23,7 +33,7 @@ * libc/include/sys/types.h: Same. 2009-06-16 Corinna Vinschen - + * libc/include/locale.h (struct lconv): Add missing members required by POSIX.1-2008. * libc/locale/locale.c (lconv): Initialize new members to default diff --git a/newlib/libc/include/stdio.h b/newlib/libc/include/stdio.h index 6db5151ca..cf0be47b9 100644 --- a/newlib/libc/include/stdio.h +++ b/newlib/libc/include/stdio.h @@ -391,6 +391,7 @@ FILE * _EXFUN(_fopen_r, (struct _reent *, const char *, const char *)); 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 *, char *, const char *, __VALIST) 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 *)); diff --git a/newlib/libc/stdio/Makefile.am b/newlib/libc/stdio/Makefile.am index b5895833e..a1ba475df 100644 --- a/newlib/libc/stdio/Makefile.am +++ b/newlib/libc/stdio/Makefile.am @@ -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 diff --git a/newlib/libc/stdio/Makefile.in b/newlib/libc/stdio/Makefile.in index 3dead2c65..3b593e23b 100644 --- a/newlib/libc/stdio/Makefile.in +++ b/newlib/libc/stdio/Makefile.in @@ -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) lib_a-fclose.$(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 fdopen.lo feof.lo ferror.lo \ @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_NEWLIB_ICONV_TRUE@ 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 diff --git a/newlib/libc/stdio/fpurge.c b/newlib/libc/stdio/fpurge.c new file mode 100644 index 000000000..41228efd7 --- /dev/null +++ b/newlib/libc/stdio/fpurge.c @@ -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 +<>---discard pending file I/O + +INDEX + fpurge +INDEX + _fpurge_r + +ANSI_SYNOPSIS + #include + int fpurge(FILE *<[fp]>); + + int _fpurge_r(struct _reent *<[reent]>, FILE *<[fp]>); + +DESCRIPTION +Use <> 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 <> and any data retrieved from disk +but not yet read via <>. This is more severe than <>, +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 +<> returns <<0>> unless <[fp]> is not valid, in which case it +returns <> and sets <>. + +PORTABILITY +These functions are not portable to any standard. + +No supporting OS subroutines are required. +*/ + +#include <_ansi.h> +#include +#include +#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 */ diff --git a/newlib/libc/stdio/stdio.tex b/newlib/libc/stdio/stdio.tex index 28feffbcc..2088d74ed 100644 --- a/newlib/libc/stdio/stdio.tex +++ b/newlib/libc/stdio/stdio.tex @@ -42,6 +42,7 @@ structure. * fmemopen:: Open a stream around a fixed-length buffer * fopen:: Open a file * fopencookie:: Open a stream with custom callbacks +* fpurge:: Discard all pending I/O on a stream * fputc:: Write a character on a stream or file * fputs:: Write a character string in a file or stream * fputwc:: Write a wide character to a file or stream @@ -152,6 +153,9 @@ structure. @page @include stdio/fopencookie.def +@page +@include stdio/fpurge.def + @page @include stdio/fputc.def