bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: no new modules 'freading', 'fwriting'


From: Bruno Haible
Subject: Re: no new modules 'freading', 'fwriting'
Date: Sun, 29 Apr 2007 14:15:21 +0200
User-agent: KMail/1.5.4

These added tests show an fflush bug on BSD systems, introduced by use of
a buggy fpurge() function in the system. This fixes it.


2007-04-29  Bruno Haible  <address@hidden>

        Work around fpurge bug on BSD systems.
        * modules/fpurge (Makefile.am): Compile fpurge.c unconditionally.
        * m4/fpurge.m4 (gl_FUNC_FPURGE): Don't invoke AC_LIBOBJ.
        * lib/fpurge.h (fpurge): Don't handle __fpurge wrapper here. Define
        fpurge to rpl_fpurge if the system already has this function.
        * lib/fpurge.c (fpurge): Handle also the __fpurge wrapper case and
        the case where the system already has this function. Correct invariants
        on BSD systems.
        * lib/fseeko.c (rpl_fseeko): Update recognition of preceding fflush on
        BSD systems.

*** modules/fpurge      14 Apr 2007 00:25:21 -0000      1.1
--- modules/fpurge      29 Apr 2007 12:06:16 -0000
***************
*** 12,17 ****
--- 12,18 ----
  gl_FUNC_FPURGE
  
  Makefile.am:
+ lib_SOURCES += fpurge.c
  
  Include:
  "fpurge.h"
*** m4/fpurge.m4        14 Apr 2007 00:25:21 -0000      1.1
--- m4/fpurge.m4        29 Apr 2007 12:06:16 -0000
***************
*** 1,4 ****
! # fpurge.m4 serial 1
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # fpurge.m4 serial 2
  dnl Copyright (C) 2007 Free Software Foundation, Inc.
  dnl This file is free software; the Free Software Foundation
  dnl gives unlimited permission to copy and/or distribute it,
***************
*** 9,16 ****
    AC_CHECK_FUNCS_ONCE([fpurge])
    AC_CHECK_FUNCS_ONCE([__fpurge])
    AC_CHECK_DECLS([fpurge], , , [#include <stdio.h>])
-   if test $ac_cv_func_fpurge = no && test $ac_cv_func___fpurge = no; then
-     AC_LIBOBJ([fpurge])
-     AC_CHECK_FUNCS([fpurge])
-   fi
  ])
--- 9,12 ----
*** lib/fpurge.h        14 Apr 2007 00:25:21 -0000      1.1
--- lib/fpurge.h        29 Apr 2007 12:06:16 -0000
***************
*** 15,41 ****
     with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
  #include <stdio.h>
  
  /* Discard all pending buffered I/O on the stream STREAM.
     STREAM must not be wide-character oriented.
     Return 0 if successful.  Upon error, return -1 and set errno.  */
! 
! #if HAVE___FPURGE /* glibc >= 2.2, Solaris >= 7 */
! 
! # include <stdio_ext.h>
! # define fpurge(stream) (__fpurge (stream), 0)
! 
! #elif ! HAVE_DECL_FPURGE
! 
! # ifdef __cplusplus
! extern "C" {
! # endif
! 
  extern int fpurge (FILE *stream);
  
! # ifdef __cplusplus
  }
- # endif
- 
  #endif
--- 15,39 ----
     with this program; if not, write to the Free Software Foundation,
     Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
  
+ #ifndef _GL_FPURGE_H
+ #define _GL_FPURGE_H
+ 
  #include <stdio.h>
  
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
  /* Discard all pending buffered I/O on the stream STREAM.
     STREAM must not be wide-character oriented.
     Return 0 if successful.  Upon error, return -1 and set errno.  */
! #if HAVE_FPURGE
! # define fpurge rpl_fpurge
! #endif
  extern int fpurge (FILE *stream);
  
! #ifdef __cplusplus
  }
  #endif
+ 
+ #endif /* _GL_FPURGE_H */
*** lib/fpurge.c        25 Apr 2007 13:22:15 -0000      1.4
--- lib/fpurge.c        29 Apr 2007 12:06:16 -0000
***************
*** 20,34 ****
  /* Specification.  */
  #include "fpurge.h"
  
  #include <stdlib.h>
  
  int
  fpurge (FILE *fp)
  {
    /* Most systems provide FILE as a struct and the necessary bitmask in
       <stdio.h>, because they need it for implementing getc() and putc() as
       fast macros.  */
! #if defined _IO_ferror_unlocked     /* GNU libc, BeOS */
    fp->_IO_read_end = fp->_IO_read_ptr;
    fp->_IO_write_ptr = fp->_IO_write_base;
    /* Avoid memory leak when there is an active ungetc buffer.  */
--- 20,66 ----
  /* Specification.  */
  #include "fpurge.h"
  
+ #if HAVE___FPURGE                   /* glibc >= 2.2, Solaris >= 7 */
+ # include <stdio_ext.h>
+ #endif
  #include <stdlib.h>
  
  int
  fpurge (FILE *fp)
  {
+ #if HAVE___FPURGE                   /* glibc >= 2.2, Solaris >= 7 */
+ 
+   __fpurge (fp);
+   /* The __fpurge function does not have a return value.  */
+   return 0;
+ 
+ #elif HAVE_FPURGE                   /* FreeBSD, NetBSD, OpenBSD, MacOS X */
+ 
+   /* Call the system's fpurge function.  */
+ # undef fpurge
+ # if !HAVE_DECL_FPURGE
+   extern int fpurge (FILE *);
+ # endif
+   int result = fpurge (fp);
+ # if defined __sferror              /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
+   if (result == 0)
+     /* Correct the invariants that fpurge broke.
+        <stdio.h> on BSD systems says:
+          "The following always hold: if _flags & __SRD, _w is 0."
+        If this invariant is not fulfilled and the stream is read-write but
+        currently writing, subsequent putc or fputc calls will write directly
+        into the buffer, although they shouldn't be allowed to.  */
+     if ((fp->_flags & __SRD) != 0)
+       fp->_w = 0;
+ # endif
+   return result;
+ 
+ #else
+ 
    /* Most systems provide FILE as a struct and the necessary bitmask in
       <stdio.h>, because they need it for implementing getc() and putc() as
       fast macros.  */
! # if defined _IO_ferror_unlocked    /* GNU libc, BeOS */
    fp->_IO_read_end = fp->_IO_read_ptr;
    fp->_IO_write_ptr = fp->_IO_write_base;
    /* Avoid memory leak when there is an active ungetc buffer.  */
***************
*** 38,57 ****
        fp->_IO_save_base = NULL;
      }
    return 0;
! #elif defined __sferror             /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
    fp->_p = fp->_bf._base;
    fp->_r = 0;
!   fp->_w = ((fp->_flags & (__SLBF | __SNBF)) == 0 /* fully buffered? */
            ? fp->_bf._size
            : 0);
    /* Avoid memory leak when there is an active ungetc buffer.  */
! # 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_ub._base != NULL)
      {
        if (fp_ub._base != fp->_ubuf)
--- 70,89 ----
        fp->_IO_save_base = NULL;
      }
    return 0;
! # elif defined __sferror            /* FreeBSD, NetBSD, OpenBSD, MacOS X, 
Cygwin */
    fp->_p = fp->_bf._base;
    fp->_r = 0;
!   fp->_w = ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered 
and not currently reading? */
            ? fp->_bf._size
            : 0);
    /* Avoid memory leak when there is an active ungetc buffer.  */
! #  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_ub._base != NULL)
      {
        if (fp_ub._base != fp->_ubuf)
***************
*** 59,70 ****
        fp_ub._base = NULL;
      }
    return 0;
! #elif defined _IOERR                /* AIX, HP-UX, IRIX, OSF/1, Solaris, 
mingw */
    fp->_ptr = fp->_base;
    if (fp->_ptr != NULL)
      fp->_cnt = 0;
    return 0;
! #else
   #error "Please port gnulib fpurge.c to your platform! Look at the 
definitions of fflush, setvbuf and ungetc on your system, then report this to 
bug-gnulib."
  #endif
  }
--- 91,104 ----
        fp_ub._base = NULL;
      }
    return 0;
! # elif defined _IOERR               /* AIX, HP-UX, IRIX, OSF/1, Solaris, 
mingw */
    fp->_ptr = fp->_base;
    if (fp->_ptr != NULL)
      fp->_cnt = 0;
    return 0;
! # else
   #error "Please port gnulib fpurge.c to your platform! Look at the 
definitions of fflush, setvbuf and ungetc on your system, then report this to 
bug-gnulib."
+ # endif
+ 
  #endif
  }
*** lib/fseeko.c        26 Apr 2007 09:25:05 -0000      1.2
--- lib/fseeko.c        29 Apr 2007 12:06:16 -0000
***************
*** 46,52 ****
  # 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)
--- 46,52 ----
  # endif
    if (fp->_p == fp->_bf._base
        && fp->_r == 0
!       && fp->_w == ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully 
buffered and not currently reading? */
                    ? fp->_bf._size
                    : 0)
        && fp_ub._base == NULL)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]