[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: 'fflush' test failure on Cygwin
From: |
Eric Blake |
Subject: |
Re: 'fflush' test failure on Cygwin |
Date: |
Mon, 16 Apr 2007 21:38:13 -0600 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.10) Gecko/20070221 Thunderbird/1.5.0.10 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
According to Bruno Haible on 4/12/2007 7:30 PM:
>
> 1) fpurge exists on MacOS X, but only clears the buffer, without changing
> the file descriptor's position in the kernel. So it needs this change
> (otherwise the stream's position before the fflush() call is lost):
>
> *** lib/fflush.c 2007-04-13 00:15:11.000000000 +0200
> --- lib/fflush.c 2007-04-13 02:44:10.000000000 +0200
> ***************
> *** 57,63 ****
> /* To get here, we must be flushing a seekable input stream, so the
> semantics of fpurge are now appropriate. */
> #if HAVE_FPURGE
> ! result = fpurge (stream);
> #elif HAVE___FPURGE
> /* __fpurge has no return value, and on Solaris, we can't even trust
> errno. So assume it succeeds. */
> --- 57,72 ----
> /* To get here, we must be flushing a seekable input stream, so the
> semantics of fpurge are now appropriate. */
> #if HAVE_FPURGE
> ! {
> ! off_t pos = ftello (stream);
> !
> ! result = fpurge (stream);
> ! if (result == 0)
> ! {
> ! if (lseek (fileno (stream), pos, SEEK_SET) == -1)
> ! result = EOF;
> ! }
> ! }
This is now done as part of my refactoring of fflush to depend on your new
fpurge module:
2007-04-16 Eric Blake <address@hidden>
Make fflush rely on fpurge.
* lib/fflush.c (rpl_fflush): Rely on fpurge module, rather than
open coding all variants.
* modules/fflush (Depends-on): Add fpurge and unistd.
* modules/fflush-tests (Depends-on): Unistd is no longer extra.
* m4/fflush.m4 (gl_REPLACE_FFLUSH): Simplify.
>
> 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 (...);
> }
A module for fseek/fseeko still needs to be written. And in the process,
I discovered that mingw lacks ftello, so we also need a module for
ftell/ftello (until that is written, fflush fails to compile on mingw).
Unfortunately, on mingw, Microsoft has chosen for off_t to be 4 bytes
(plain 'long'), which means fseeko is no more accurate than fseek; then
changed their mind to provide 64-bit file offsets, but via the
non-standard _ftelli64 and _fseeki64 on the type __int64 (basically 'long
long'), along with non-standard _stat64 to make stat() use 64-bit
timestamps and file lengths rather than 32-bit. I guess we implement
fseeko using mingw's choice of off_t, even though it is an artificial
limit compared to what the platform is capable of via non-standard functions.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFGJEEi84KuGfSFAYARAhmiAJ0T7nw1PIMXMvixV+xFOjJNizEzaQCeNPeq
QKKMu8C0w4uyTGwEQmE7Jc0=
=X9Py
-----END PGP SIGNATURE-----
Index: lib/fflush.c
===================================================================
RCS file: /sources/gnulib/gnulib/lib/fflush.c,v
retrieving revision 1.2
diff -u -p -r1.2 fflush.c
--- lib/fflush.c 12 Apr 2007 11:59:14 -0000 1.2
+++ lib/fflush.c 17 Apr 2007 03:25:02 -0000
@@ -21,13 +21,7 @@
#include <errno.h>
#include <stdio.h>
-#if HAVE_STDIO_EXT_H
-# include <stdio_ext.h>
-#endif
-
-#if HAVE_FPURGE && ! HAVE_DECL_FPURGE
-int fpurge (FILE *);
-#endif
+#include "fpurge.h"
#undef fflush
@@ -36,53 +30,31 @@ int fpurge (FILE *);
int
rpl_fflush (FILE *stream)
{
- int e; /* Capture errno of first fflush if nothing else succeeds. */
int result;
+ off_t pos;
/* Try flushing the stream. C89 guarantees behavior of output
streams, so we only need to worry if failure might have been on
an input stream. When stream is NULL, POSIX only requires
flushing of output streams. */
result = fflush (stream);
- if (! stream || result == 0 || (e = errno) != EBADF)
+ if (! stream || result == 0 || errno != EBADF)
return result;
- /* POSIX does not specify behavior for non-seekable streams. */
- if (fseeko (stream, 0, SEEK_CUR) != 0)
+ /* POSIX does not specify fflush behavior for non-seekable input
+ streams. */
+ pos = ftello (stream);
+ if (pos == -1)
{
- errno = e;
+ errno = EBADF;
return EOF;
}
/* To get here, we must be flushing a seekable input stream, so the
- semantics of fpurge are now appropriate. */
-#if HAVE_FPURGE
+ semantics of fpurge are now appropriate to clear the buffer. To
+ avoid losing data, the lseek is also necessary. */
result = fpurge (stream);
-#elif HAVE___FPURGE
- /* __fpurge has no return value, and on Solaris, we can't even trust
- errno. So assume it succeeds. */
- __fpurge (stream);
- result = 0;
-#else /* ! HAVE___FPURGE */
-
- /* No single replacement; do it manually. */
- {
- off_t position = ftello (stream);
- if (position == -1)
- {
- result = EOF; /* Should not happen; we know stream is seekable. */
- }
- /* Set position of stream; hopefully the stdio routines don't
- overoptimize by not setting the underlying file position. */
- else if (fseeko (stream, position, SEEK_SET) != 0)
- {
- result = EOF;
- errno = e;
- }
- else
- result = 0;
- }
-#endif /* ! HAVE___FPURGE */
-
+ if (result == 0 && lseek (fileno (stream), pos, SEEK_SET) == -1)
+ return EOF;
return result;
}
Index: m4/fflush.m4
===================================================================
RCS file: /sources/gnulib/gnulib/m4/fflush.m4,v
retrieving revision 1.1
diff -u -p -r1.1 fflush.m4
--- m4/fflush.m4 10 Apr 2007 03:09:07 -0000 1.1
+++ m4/fflush.m4 17 Apr 2007 03:25:02 -0000
@@ -8,8 +8,7 @@
dnl From Eric Blake
dnl Find out how to obey POSIX semantics of fflush(stdin) discarding
-dnl unread input, rather than C99 undefined semantics. fpurge is not
-dnl standardized, but has the desired properties.
+dnl unread input on seekable streams, rather than C99 undefined semantics.
AC_DEFUN([gl_FUNC_FFLUSH],
[
@@ -45,15 +44,6 @@ AC_DEFUN([gl_FUNC_FFLUSH],
AC_DEFUN([gl_REPLACE_FFLUSH],
[
- AC_CHECK_HEADERS_ONCE([stdio_ext.h])
- AC_CHECK_FUNCS_ONCE([fpurge __fpurge])
-dnl Linux documents int fpurge(), but only declares void __fpurge().
- AC_CHECK_DECLS([fpurge], [], [], [[
-#include <stdio.h>
-#if HAVE_STDIO_EXT_H
-# include <stdio_ext.h>
-#endif
-]])
AC_LIBOBJ([fflush])
AC_REQUIRE([gl_STDIO_H_DEFAULTS])
REPLACE_FFLUSH=1
Index: modules/fflush
===================================================================
RCS file: /sources/gnulib/gnulib/modules/fflush,v
retrieving revision 1.2
diff -u -p -r1.2 fflush
--- modules/fflush 13 Apr 2007 01:46:18 -0000 1.2
+++ modules/fflush 17 Apr 2007 03:25:02 -0000
@@ -6,7 +6,9 @@ lib/fflush.c
m4/fflush.m4
Depends-on:
+fpurge
stdio
+unistd
configure.ac:
gl_FUNC_FFLUSH
Index: modules/fflush-tests
===================================================================
RCS file: /sources/gnulib/gnulib/modules/fflush-tests,v
retrieving revision 1.2
diff -u -p -r1.2 fflush-tests
--- modules/fflush-tests 13 Apr 2007 23:50:49 -0000 1.2
+++ modules/fflush-tests 17 Apr 2007 03:25:02 -0000
@@ -2,7 +2,6 @@ Files:
tests/test-fflush.c
Depends-on:
-unistd
configure.ac:
- Re: 'fflush' test failure on Cygwin, (continued)
- Re: operations on FILE streams, Bruno Haible, 2007/04/13
- Re: operations on FILE streams, Paul Eggert, 2007/04/13
- Re: operations on FILE streams, Bruno Haible, 2007/04/13
- Re: operations on FILE streams, Eric Blake-1, 2007/04/13
- Re: operations on FILE streams, Bruno Haible, 2007/04/13
- Re: operations on FILE streams, Paul Eggert, 2007/04/13
- Re: operations on FILE streams, Bruno Haible, 2007/04/13
- Re: 'fflush' test failure on Cygwin,
Eric Blake <=
- Re: 'fflush' test failure on Cygwin, Bruno Haible, 2007/04/23
- Re: 'fflush' test failure on Cygwin, Eric Blake, 2007/04/23
- new module 'fseeko', Bruno Haible, 2007/04/25
- Re: new module 'fseeko', Eric Blake, 2007/04/25
- Re: new module 'fseeko', Bruno Haible, 2007/04/26
- Re: new module 'fseeko', Bruno Haible, 2007/04/28
- 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