[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: workaround ftello/fseeko on cygwin 1.5.x
From: |
Bruno Haible |
Subject: |
Re: workaround ftello/fseeko on cygwin 1.5.x |
Date: |
Thu, 24 May 2007 00:36:02 +0200 |
User-agent: |
KMail/1.5.4 |
Eric Blake wrote:
> It overcomes the
> fact that cygwin was creating the three std streams in 32-bit mode instead
> of 64-bit mode, such that fseeko/ftello failed because they expected the
> stream to be in 64-bit mode.
Glad to see that you found a workaround!
> Index: lib/fseeko.c
> ===================================================================
> RCS file: /sources/gnulib/gnulib/lib/fseeko.c,v
> retrieving revision 1.3
> diff -u -p -r1.3 fseeko.c
> --- lib/fseeko.c 29 Apr 2007 12:16:55 -0000 1.3
> +++ lib/fseeko.c 23 May 2007 16:44:57 -0000
> @@ -44,6 +44,19 @@ rpl_fseeko (FILE *fp, off_t offset, int
> # else /* FreeBSD, MacOS X, Cygwin */
> # define fp_ub fp->_ub
> # endif
> +# if defined __SL64 && defined __SCLE /* Cygwin */
> + if ((fp->_flags & __SL64) == 0)
> + {
> + /* Cygwin 1.5.0 through 1.5.24 failed to open stdin in 64-bit
> + mode; but has an fseeko that requires 64-bit mode. */
> + FILE *tmp = fopen ("/dev/null", "r");
> + if (!tmp)
> + return -1;
> + fp->_flags |= __SL64;
> + fp->_seek64 = tmp->_seek64;
> + fclose (tmp);
> + }
> +# endif
Every time fseeko or ftello is applied for the first time to a stream, this
code will fopen /dev/null. Sounds a bit expensive. Can't you cache the
_seek64 pointer that you found? Something like this:
/* Ensures that the given stream is open in 64-bit mode. */
void
cygfreopen64 (FILE *fp)
{
static _fpos64_t (*seek64_func) (void *_cookie, _fpos64_t _offset, int
_whence);
if (seek64_func == NULL)
{
FILE *tmp = fopen ("/dev/null", "r");
if (tmp != NULL)
{
seek64_func = tmp->_seek64;
fclose (tmp);
}
else
seek64_func = (void *) (-1);
}
if (seek64_func != (void *) (-1))
{
fp->_flags |= __SL64;
fp->_seek64 = seek64_func;
}
}
Put this into a separate compilation unit, so that fseeko and ftello can
share the same cache.
> @@ -233,6 +235,11 @@ typedef int verify_fseeko_types[2 * (siz
> (GL_LINK_WARNING ("fseeko is unportable - " \
> "use gnulib module fseeko for portability"), \
> fseeko (f, o, w))
> +# undef fseek
> +# define fseek(f,o,w) \
> + (GL_LINK_WARNING ("fseek is artificially limited - " \
> + "use gnulib module fseeko for portability"), \
> + fseek (f, o, w))
> #endif
You don't need this: The warning about fseek is already contained in
stdio_.h lines 238..246, and the one for tell is already at stdio_.h lines
262..270.
> @@ -257,6 +267,11 @@ typedef int verify_ftello_types[2 * (siz
> (GL_LINK_WARNING ("ftello is unportable - " \
> "use gnulib module ftello for portability"), \
> ftello (f))
> +# undef ftell
> +# define ftell(f) \
> + (GL_LINK_WARNING ("ftell is artificially limited - " \
> + "use gnulib module ftello for portability"), \
> + ftell (f))
> #endif
Likewise.
> Index: m4/fseeko.m4
> ===================================================================
> RCS file: /sources/gnulib/gnulib/m4/fseeko.m4,v
> retrieving revision 1.3
> diff -u -p -r1.3 fseeko.m4
> --- m4/fseeko.m4 26 Apr 2007 09:33:12 -0000 1.3
> +++ m4/fseeko.m4 23 May 2007 16:44:57 -0000
> @@ -1,4 +1,4 @@
> -# fseeko.m4 serial 1
> +# fseeko.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,
> @@ -8,6 +8,7 @@ AC_DEFUN([gl_FUNC_FSEEKO],
> [
> AC_REQUIRE([gl_STDIO_H_DEFAULTS])
> AC_REQUIRE([AC_PROG_CC])
> + AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
> AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko],
> [
> AC_TRY_LINK([#include <stdio.h>], [fseeko (stdin, 0, 0);],
> @@ -15,5 +16,32 @@ AC_DEFUN([gl_FUNC_FSEEKO],
> ])
> if test $gl_cv_func_fseeko = no; then
> HAVE_FSEEKO=0
> + else
> + AC_CACHE_CHECK([if fseeko(stdin) works], [gl_cv_func_fseeko_stdin],
> + [
> + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>],
> + [
> +#if defined __SL64 && defined __SCLE /* cygwin */
> + /* Cygwin 1.5.24 and earlier fail to put stdin in 64-bit mode, making
> + fseeko/ftello needlessly fail. This bug was fixed at the same time
> + that cygwin started exporting asnprintf (cygwin 1.7.0), so we use
> + that as a link-time test for cross-compiles rather than building
> + a runtime test. */
> + size_t s;
> + if (asnprintf (NULL, &s, ""))
> + return 0;
> +#endif
> + ])],
> + [gl_cv_func_fseeko_stdin=yes], [gl_cv_func_fseeko_stdin=no])])
> + if test $gl_cv_func_fseeko_stdin = no; then
> + gl_REPLACE_FSEEKO
> + fi
This test is duplicated between fseeko.m4 and ftello.m4. Since you use
two different cache variables, it will even be executed twice per 'configure'
run. I would put it into a separate macro, say, in stdio_h.m4.
Bruno