From 16332895663c60d815322830a027ec5f660e2639 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Wed, 25 Apr 2007 09:14:49 +0000 Subject: [PATCH] Make the combination of fflush and fseek/fseeko POSIX compliant. --- ChangeLog | 13 +++++++++++ lib/fseeko.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/stdio_.h | 12 +++++++++- m4/fflush.m4 | 8 ++++++- m4/fseeko.m4 | 11 ++++++--- modules/fflush | 2 ++ 6 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 lib/fseeko.c diff --git a/ChangeLog b/ChangeLog index 244370a2a..6218a8e72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2007-04-25 Bruno Haible + Make fflush+fseek POSIX-compliant on FreeBSD and MacOS X. + * lib/fseeko.c: New file. + * lib/stdio_.h: Include when off_t is needed. + (fseeko, fseek): Define to replacements if REPLACE_FFLUSH. + * m4/fseeko.m4 (gl_CHECK_FSEEKO): New macro, extracted from + gl_FUNC_FSEEKO. + (gl_FUNC_FSEEKO): Invoke it. + * m4/fflush.m4 (gl_REPLACE_FFLUSH): Arrange to compile fseeko.c. Invoke + gl_CHECK_FSEEKO. Define HAVE_FSEEKO. + * modules/fflush (Files): Add lib/fseeko.c, m4/fseeko.m4. + +2007-04-25 Bruno Haible + * modules/fflush (Depends-on): Add ftello. 2007-04-25 Bruno Haible diff --git a/lib/fseeko.c b/lib/fseeko.c new file mode 100644 index 000000000..de44802b6 --- /dev/null +++ b/lib/fseeko.c @@ -0,0 +1,72 @@ +/* An fseek() function that, together with fflush(), is POSIX compliant. + Copyright (C) 2007 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, + Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ + +#include + +/* Specification. */ +#include + +/* Get off_t and lseek. */ +#include + +#undef fseeko +#if !HAVE_FSEEKO +# define fseeko fseek +#endif + +int +rpl_fseeko (FILE *fp, off_t offset, int whence) +{ + /* These tests are based on fpurge.c. */ +#if defined _IO_ferror_unlocked /* GNU libc, BeOS */ + if (fp->_IO_read_end == fp->_IO_read_ptr + && fp->_IO_write_ptr == fp->_IO_write_base + && fp->_IO_save_base == NULL) +#elif defined __sferror /* FreeBSD, NetBSD, OpenBSD, MacOS X, Cygwin */ +# if defined __NetBSD__ || defined __OpenBSD__ /* NetBSD, OpenBSD */ + /* See + and */ +# define fp_ub ((struct { struct __sbuf _ub; } *) fp->_ext._base)->_ub +# else /* FreeBSD, MacOS X, Cygwin */ +# define fp_ub fp->_ub +# endif + if (fp->_p == fp->_bf._base + && fp->_r == 0 + && fp->_w == ((fp->_flags & (__SLBF | __SNBF)) == 0 /* fully buffered? */ + ? fp->_bf._size + : 0) + && fp_ub._base == NULL) +#elif defined _IOERR /* AIX, HP-UX, IRIX, OSF/1, Solaris, mingw */ +# if defined __sun && defined __sparc && defined _LP64 /* Solaris/SPARC 64-bit */ +# define fp_ ((struct { unsigned char *_ptr; \ + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + } *) fp) + if (fp_->_ptr == fp_->_base + && (fp_->_ptr == NULL || fp_->_cnt == 0)) +# else + if (fp->_ptr == fp->_base + && (fp->_ptr == NULL || fp->_cnt == 0)) +# endif +#else + #error "Please port gnulib fseeko.c to your platform! Look at the code in fpurge.c, then report this to bug-gnulib." +#endif + return (lseek (fileno (fp), offset, whence) == (off_t)(-1) ? -1 : 0); + else + return fseeko (fp, offset, whence); +} diff --git a/lib/stdio_.h b/lib/stdio_.h index 46ec407c9..8b78d7bcc 100644 --- a/lib/stdio_.h +++ b/lib/stdio_.h @@ -38,6 +38,11 @@ #include #include +#if @GNULIB_FFLUSH@ && @REPLACE_FFLUSH@ +/* Get off_t. */ +# include +#endif + #ifndef __attribute__ /* This feature is available in gcc versions 2.5 and later. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ @@ -207,7 +212,12 @@ extern int vsprintf (char *str, const char *format, va_list args) # endif #endif -#if @GNULIB_FSEEKO@ +#if @GNULIB_FFLUSH@ && @REPLACE_FFLUSH@ +/* Provide fseek, fseeko functions that are aware of a preceding fflush(). */ +# define fseeko rpl_fseeko +extern int fseeko (FILE *fp, off_t offset, int whence); +# define fseek(fp, offset, whence) fseeko (fp, (off_t)(offset), whence) +#elif @GNULIB_FSEEKO@ # if !@HAVE_FSEEKO@ /* Assume 'off_t' is the same type as 'long'. */ # define fseeko fseek diff --git a/m4/fflush.m4 b/m4/fflush.m4 index d4ebeccb6..fca7769be 100755 --- a/m4/fflush.m4 +++ b/m4/fflush.m4 @@ -1,4 +1,4 @@ -#serial 2 +#serial 3 # Copyright (C) 2007 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation @@ -45,6 +45,12 @@ AC_DEFUN([gl_FUNC_FFLUSH], AC_DEFUN([gl_REPLACE_FFLUSH], [ AC_LIBOBJ([fflush]) + AC_LIBOBJ([fseeko]) AC_REQUIRE([gl_STDIO_H_DEFAULTS]) REPLACE_FFLUSH=1 + gl_CHECK_FSEEKO + if test $gl_cv_func_fseeko = yes; then + AC_DEFINE([HAVE_FSEEKO], 1, + [Define to 1 if you have the fseeko() function or macro.]) + fi ]) diff --git a/m4/fseeko.m4 b/m4/fseeko.m4 index 86d42f40c..fd3f019f7 100644 --- a/m4/fseeko.m4 +++ b/m4/fseeko.m4 @@ -7,13 +7,18 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_FSEEKO], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + gl_CHECK_FSEEKO + if test $gl_cv_func_fseeko = no; then + HAVE_FSEEKO=0 + fi +]) + +AC_DEFUN([gl_CHECK_FSEEKO], +[ AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko], [ AC_TRY_LINK([#include ], [fseeko (stdin, 0, 0);], [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no]) ]) - if test $gl_cv_func_fseeko = no; then - HAVE_FSEEKO=0 - fi ]) diff --git a/modules/fflush b/modules/fflush index b23b44a85..62a2d5970 100755 --- a/modules/fflush +++ b/modules/fflush @@ -3,7 +3,9 @@ Discard pending data on both input and output streams. Files: lib/fflush.c +lib/fseeko.c m4/fflush.m4 +m4/fseeko.m4 Depends-on: fpurge -- 2.11.0