[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 'fflush' test failure on Cygwin
From: |
Bruno Haible |
Subject: |
Re: 'fflush' test failure on Cygwin |
Date: |
Wed, 25 Apr 2007 11:17:26 +0200 |
User-agent: |
KMail/1.5.4 |
On 2007-04-13, I wrote:
> 2) fseek() is heavily optimized: fseeko (fp, pos, SEEK_SET) will position
> the file descriptor to pos & ~fp->_blksize and then read one buffer,
> [or if pos is inside the current buffer, optimize even more: just
> change some pointers and counters, without accessing the file descriptor],
> unless
> - fp is not seekable, or
> - fp is open for writing (__SWR | __SRW), or
> - fp is unbuffered (__SNBF), or
> - fp has an unusual block size set through setvbuf (__SNPT).
> If your fflush or fseek was to invoke setvbuf, it's hard to keep programs
> working that use setvbuf as well.
>
> A solution might be to make a wrapper around fseek() roughly like this:
>
> rpl_fseek (...)
> {
> if (fp is not open for writing
> && fp's buffer is empty, like after fpurge)
> perform just an lseek
> else
> fseek (...);
> }
This implements it.
2007-04-25 Bruno Haible <address@hidden>
Make fflush+fseek POSIX-compliant on FreeBSD and MacOS X.
* lib/fseeko.c: New file.
* lib/stdio_.h: Include <sys/types.h> 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.
======================== lib/fseeko.c ====================================
/* 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 <config.h>
/* Specification. */
#include <stdio.h>
/* Get off_t and lseek. */
#include <unistd.h>
#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
<http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
and
<http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/stdio/fileext.h?rev=HEAD&content-type=text/x-cvsweb-markup>
*/
# 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);
}
==========================================================================
*** lib/stdio_.h 25 Apr 2007 07:51:53 -0000 1.19
--- lib/stdio_.h 25 Apr 2007 09:10:07 -0000
***************
*** 38,43 ****
--- 38,48 ----
#include <stdarg.h>
#include <stddef.h>
+ #if @GNULIB_FFLUSH@ && @REPLACE_FFLUSH@
+ /* Get off_t. */
+ # include <sys/types.h>
+ #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,213 ****
# endif
#endif
! #if @GNULIB_FSEEKO@
# if address@hidden@
/* Assume 'off_t' is the same type as 'long'. */
# define fseeko fseek
--- 212,223 ----
# endif
#endif
! #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 address@hidden@
/* Assume 'off_t' is the same type as 'long'. */
# define fseeko fseek
*** m4/fseeko.m4 25 Apr 2007 07:39:56 -0000 1.1
--- m4/fseeko.m4 25 Apr 2007 09:10:07 -0000
***************
*** 7,19 ****
AC_DEFUN([gl_FUNC_FSEEKO],
[
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
AC_REQUIRE([AC_PROG_CC])
AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko],
[
AC_TRY_LINK([#include <stdio.h>], [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
])
--- 7,24 ----
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 <stdio.h>], [fseeko (stdin, 0, 0);],
[gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no])
])
])
*** m4/fflush.m4 17 Apr 2007 03:40:30 -0000 1.3
--- m4/fflush.m4 25 Apr 2007 09:10:07 -0000
***************
*** 1,4 ****
! #serial 2
# Copyright (C) 2007 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
--- 1,4 ----
! #serial 3
# Copyright (C) 2007 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
***************
*** 45,50 ****
--- 45,56 ----
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
])
*** modules/fflush 25 Apr 2007 07:56:32 -0000 1.4
--- modules/fflush 25 Apr 2007 09:10:07 -0000
***************
*** 3,9 ****
--- 3,11 ----
Files:
lib/fflush.c
+ lib/fseeko.c
m4/fflush.m4
+ m4/fseeko.m4
Depends-on:
fpurge
- Re: new module 'fseeko', (continued)
- Re: new module 'fseeko', Paul Eggert, 2007/04/25
- Re: new module 'fseeko', Bruno Haible, 2007/04/26
- new module 'ftello', Bruno Haible, 2007/04/25
- Re: 'fflush' test failure on Cygwin, Bruno Haible, 2007/04/25
- Re: 'fflush' test failure on Cygwin, Eric Blake, 2007/04/25
- Re: 'fflush' test failure on Cygwin, Bruno Haible, 2007/04/26
- Re: 'fflush' test failure on Cygwin, Eric Blake, 2007/04/26
- Re: 'fflush' test failure on Cygwin,
Bruno Haible <=