From 2795a047b6e9d35821fb9780886f746666cd74e8 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Sat, 15 Aug 2009 16:43:58 -0600 Subject: [PATCH] fpurge: don't wrap working cygwin implementation * lib/fpurge.c (fpurge): Fix comment typo. * modules/fpurge (Makefile.am): Make replacement conditional, partially reverting 2007-04-29 change. * tests/test-fpurge.c (main): Enhance test. Signed-off-by: Eric Blake --- ChangeLog | 14 +++++++++++--- lib/fpurge.c | 4 ++-- m4/fpurge.m4 | 31 ++++++++++++++++++++++++++++--- tests/test-fpurge.c | 30 ++++++++++++++++++++++++++---- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index b919f1d85..bb286dce9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,12 @@ 2009-08-15 Eric Blake + + fpurge: don't wrap working cygwin implementation + * lib/fpurge.c (fpurge): Fix comment typo. + * modules/fpurge (Makefile.am): Make replacement conditional, + partially reverting 2007-04-29 change. + * tests/test-fpurge.c (main): Enhance test. + +2009-08-15 Eric Blake and Jim Meyering test-update-copyright: skip if perl is insufficient @@ -580,7 +588,7 @@ different project/version. 2009-08-02 Paolo Bonzini - Bruno Haible + Bruno Haible Tests for module 'pipe-filter-gi'. * modules/pipe-filter-gi-tests: New file. @@ -595,7 +603,7 @@ * modules/pipe-filter-gi: New file. 2009-08-02 Bruno Haible - Paolo Bonzini + Paolo Bonzini Tests for module 'pipe-filter-ii'. * modules/pipe-filter-ii-tests: New file. @@ -621,7 +629,7 @@ * lib/gethostname.c: Include limits.h. 2009-08-02 Simon Josefsson - Bruno Haible + Bruno Haible Ensure HOST_NAME_MAX as part of the gethostname module. * m4/gethostname.m4 (gl_FUNC_GETHOSTNAME): On native Windows platforms, diff --git a/lib/fpurge.c b/lib/fpurge.c index dc6414778..114dabf19 100644 --- a/lib/fpurge.c +++ b/lib/fpurge.c @@ -35,7 +35,7 @@ fpurge (FILE *fp) /* The __fpurge function does not have a return value. */ return 0; -#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X */ +#elif HAVE_FPURGE /* FreeBSD, NetBSD, OpenBSD, DragonFly, MacOS X, Cygwin 1.7 */ /* Call the system's fpurge function. */ # undef fpurge @@ -49,7 +49,7 @@ fpurge (FILE *fp) 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 + currently reading, 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; diff --git a/m4/fpurge.m4 b/m4/fpurge.m4 index 1c3ca1033..99b9a6ee1 100644 --- a/m4/fpurge.m4 +++ b/m4/fpurge.m4 @@ -1,4 +1,4 @@ -# fpurge.m4 serial 3 +# fpurge.m4 serial 4 dnl Copyright (C) 2007, 2009 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -10,11 +10,36 @@ AC_DEFUN([gl_FUNC_FPURGE], AC_CHECK_FUNCS_ONCE([fpurge]) AC_CHECK_FUNCS_ONCE([__fpurge]) AC_CHECK_DECLS([fpurge], , , [[#include ]]) - dnl For now, lib/fpurge.c is always compiled. if test "x$ac_cv_func_fpurge" = xyes; then - REPLACE_FPURGE=1 + # Detect BSD bug. Only cygwin 1.7 is known to be immune. + AC_CACHE_CHECK([whether fpurge works], [gl_cv_func_fpurge_works], + [AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include +]], [FILE *f = fopen ("conftest.txt", "w+"); + if (!f) return 1; + if (fputc ('a', f) != 'a') return 2; + rewind (f); + if (fgetc (f) != 'a') return 3; + if (fgetc (f) != EOF) return 4; + if (fpurge (f) != 0) return 5; + if (putc ('b', f) != 'b') return 6; + if (fclose (f) != 0) return 7; + if ((f = fopen ("conftest.txt", "r")) == NULL) return 8; + if (fgetc (f) != 'a') return 9; + if (fgetc (f) != 'b') return 10; + if (fgetc (f) != EOF) return 11; + if (fclose (f) != 0) return 12; + if (remove ("conftest.txt") != 0) return 13; + return 0;])], + [gl_cv_func_fpurge_works=yes], [gl_cv_func_fpurge_works=no], + [gl_cv_func_fpurge_works='guessing no'])]) + if test "x$gl_cv_func_fpurge_works" != xyes; then + REPLACE_FPURGE=1 + fi fi if test "x$ac_cv_have_decl_fpurge" = xno; then HAVE_DECL_FPURGE=0 fi + if test "$REPLACE_FPURGE$HAVE_DECL_FPURGE" != 01; then + AC_LIBOBJ([fpurge]) + fi ]) diff --git a/tests/test-fpurge.c b/tests/test-fpurge.c index 75a75c9dc..f63484034 100644 --- a/tests/test-fpurge.c +++ b/tests/test-fpurge.c @@ -61,8 +61,9 @@ main () goto skip; if (fflush (fp)) goto skip; - if (fwrite ("az", 1, 2, fp) < 2) + if (fwrite ("bz", 1, 2, fp) < 2) goto skip; + /* Discard pending write. */ ASSERT (fpurge (fp) == 0); ASSERT (fclose (fp) == 0); @@ -72,16 +73,37 @@ main () goto skip; { char buf[8]; - if (fread (buf, 1, 8, fp) < 8) + if (fread (buf, 1, 7, fp) < 7) goto skip; - ASSERT (memcmp (buf, "foogarsh", 8) == 0); + ASSERT (memcmp (buf, "foogars", 7) == 0); } + /* Discard the buffered 'h', leaving position at EOF. */ ASSERT (fpurge (fp) == 0); + ASSERT (getc (fp) == EOF); ASSERT (fclose (fp) == 0); + /* Ensure that purging a read does not corrupt subsequent writes. */ + fp = fopen (TESTFILE, "r+"); + ASSERT (fp); + ASSERT (fseek (fp, -1, SEEK_END) == 0); + ASSERT (getc (fp) == 'h'); + ASSERT (getc (fp) == EOF); + ASSERT (fpurge (fp) == 0); + ASSERT (putc ('!', fp) == '!'); + ASSERT (fclose (fp) == 0); + fp = fopen (TESTFILE, "r"); + ASSERT (fp); + { + char buf[9]; + ASSERT (fread (buf, 1, 9, fp) == 9); + ASSERT (memcmp (buf, "foogarsh!", 9) == 0); + } + + remove (TESTFILE); return 0; skip: - fprintf (stderr, "Skipping test: file operations failed.\n"); + fprintf (stderr, "Skipping test: prerequisite file operations failed.\n"); + remove (TESTFILE); return 77; } -- 2.11.0