From cec93e99d19f54c8f310b8290bab9014891530e3 Mon Sep 17 00:00:00 2001 From: Eric Blake Date: Thu, 24 May 2007 03:53:37 +0000 Subject: [PATCH] Fix fseeko/ftello on cygwin 1.5.24. * doc/functions/fseeko.texi (fseeko): Document the fix. * doc/functions/ftello.texi (ftello): Document the fix. * doc/functions/stdin.texi (stdin): Document the cygwin bug. * doc/functions/stdout.text (stdout): New file. * doc/functions/stderr.text (stderr): New file. * doc/gnulib.texi (Function Substitutes): Use new files. * tests/test-fseeko.c (main): Check for broken fseeko on cygwin prior to 1.7.0. * tests/test-ftello.c (main): Likewise for ftello. * tests/test-fseeko.sh: New file. * tests/test-ftello.sh: New file. * modules/fseeko-tests (Makefile.am): Ensure test-fseeko is run with seekable stdin. * modules/ftello-tests (Makefile.am): Likewise for test-ftello. * m4/fseeko.m4 (gl_FUNC_FSEEKO): Detect the cygwin bug. (gl_REPLACE_FSEEKO): New macro. * m4/ftello.m4 (gl_FUNC_FTELLO, gl_REPLACE_FTELLO): Likewise. * modules/fseeko (Files): Distribute fseeko.c. * modules/ftello (Files): Distribute ftello.c. * lib/fseeko.c (rpl_fseeko) [__CYGWIN__]: Convert stdin to 64-bit mode. * lib/ftello.c (rpl_ftello): New file. * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Allow replacement of fseeko, ftello. (gl_STDIN_LARGE_OFFSET): New macro. * modules/stdio (Makefile.am): Perform the replacement. * lib/stdio_.h (rpl_fseeko, rpl_ftello): Define when needed. --- ChangeLog | 31 +++++++++++++++++++++++++++++++ doc/functions/fseeko.texi | 2 ++ doc/functions/ftello.texi | 2 ++ doc/functions/stderr.texi | 20 ++++++++++++++++++++ doc/functions/stdin.texi | 5 +++++ doc/functions/stdout.texi | 20 ++++++++++++++++++++ doc/gnulib.texi | 13 +++++++++++-- lib/fseeko.c | 21 +++++++++++++++++---- lib/ftello.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/stdio_.h | 9 +++++++-- m4/fseeko.m4 | 14 ++++++++++++-- m4/ftello.m4 | 14 ++++++++++++-- m4/stdio_h.m4 | 25 ++++++++++++++++++++++++- modules/fseeko | 1 + modules/fseeko-tests | 5 ++++- modules/ftello | 1 + modules/ftello-tests | 5 ++++- modules/stdio | 2 ++ tests/test-fseeko.c | 6 ++---- tests/test-fseeko.sh | 3 +++ tests/test-ftello.c | 5 ++--- tests/test-ftello.sh | 3 +++ 22 files changed, 230 insertions(+), 22 deletions(-) create mode 100644 doc/functions/stderr.texi create mode 100644 doc/functions/stdout.texi create mode 100644 lib/ftello.c create mode 100755 tests/test-fseeko.sh create mode 100755 tests/test-ftello.sh diff --git a/ChangeLog b/ChangeLog index 8d8868cd9..e99058d8d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2007-05-23 Eric Blake + + Fix fseeko/ftello on cygwin 1.5.24. + * doc/functions/fseeko.texi (fseeko): Document the fix. + * doc/functions/ftello.texi (ftello): Document the fix. + * doc/functions/stdin.texi (stdin): Document the cygwin bug. + * doc/functions/stdout.text (stdout): New file. + * doc/functions/stderr.text (stderr): New file. + * doc/gnulib.texi (Function Substitutes): Use new files. + * tests/test-fseeko.c (main): Check for broken fseeko on cygwin + prior to 1.7.0. + * tests/test-ftello.c (main): Likewise for ftello. + * tests/test-fseeko.sh: New file. + * tests/test-ftello.sh: New file. + * modules/fseeko-tests (Makefile.am): Ensure test-fseeko is run + with seekable stdin. + * modules/ftello-tests (Makefile.am): Likewise for test-ftello. + * m4/fseeko.m4 (gl_FUNC_FSEEKO): Detect the cygwin bug. + (gl_REPLACE_FSEEKO): New macro. + * m4/ftello.m4 (gl_FUNC_FTELLO, gl_REPLACE_FTELLO): Likewise. + * modules/fseeko (Files): Distribute fseeko.c. + * modules/ftello (Files): Distribute ftello.c. + * lib/fseeko.c (rpl_fseeko) [__CYGWIN__]: Convert stdin to 64-bit + mode. + * lib/ftello.c (rpl_ftello): New file. + * m4/stdio_h.m4 (gl_STDIO_H_DEFAULTS): Allow replacement of + fseeko, ftello. + (gl_STDIN_LARGE_OFFSET): New macro. + * modules/stdio (Makefile.am): Perform the replacement. + * lib/stdio_.h (rpl_fseeko, rpl_ftello): Define when needed. + 2007-05-23 Bruno Haible * lib/stdio_.h (fseeko, ftello): Provide a link warning only if diff --git a/doc/functions/fseeko.texi b/doc/functions/fseeko.texi index d724e59da..7d8c0a6aa 100644 --- a/doc/functions/fseeko.texi +++ b/doc/functions/fseeko.texi @@ -14,6 +14,8 @@ OSF/1 4.0, Solaris 2.5.1, mingw. @item The declaration of @code{fseeko} in @code{} is not enabled by default on some platforms: glibc 2.3.6. +@item +This function fails on seekable stdin, stdout, and stderr: cygwin 1.5.x. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/functions/ftello.texi b/doc/functions/ftello.texi index af16b3dee..d6789b752 100644 --- a/doc/functions/ftello.texi +++ b/doc/functions/ftello.texi @@ -14,6 +14,8 @@ OSF/1 4.0, Solaris 2.5.1, mingw. @item The declaration of @code{ftello} in @code{} is not enabled by default on some platforms: glibc 2.3.6. +@item +This function fails on seekable stdin, stdout, and stderr: cygwin 1.5.x. @end itemize Portability problems not fixed by Gnulib: diff --git a/doc/functions/stderr.texi b/doc/functions/stderr.texi new file mode 100644 index 000000000..66f594266 --- /dev/null +++ b/doc/functions/stderr.texi @@ -0,0 +1,20 @@ +@node stderr +@section @code{stderr} +@findex stderr + +POSIX specification: @url{http://www.opengroup.org/susv3xsh/stderr.html} + +Gnulib module: --- + +Portability problems fixed by Gnulib: +@itemize +@end itemize + +Portability problems not fixed by Gnulib: +@itemize +@item +stderr is created in 32-bit mode instead of 64-bit mode: Cygwin 1.5.x. +One workaround is to use freopen(NULL, ``r+'', stderr) on Cygwin 1.5.21 +or newer. Another is to use the gnulib ftello module and do +ftello(stderr). +@end itemize diff --git a/doc/functions/stdin.texi b/doc/functions/stdin.texi index 5a4f852a1..7a597e67f 100644 --- a/doc/functions/stdin.texi +++ b/doc/functions/stdin.texi @@ -12,4 +12,9 @@ Portability problems fixed by Gnulib: Portability problems not fixed by Gnulib: @itemize +@item +stdin is created in 32-bit mode instead of 64-bit mode: Cygwin 1.5.x. +One workaround is to use freopen(NULL, ``r'', stdin) on Cygwin 1.5.21 +or newer. Another is to use the gnulib ftello module and do +ftello(stdin). @end itemize diff --git a/doc/functions/stdout.texi b/doc/functions/stdout.texi new file mode 100644 index 000000000..b9544c882 --- /dev/null +++ b/doc/functions/stdout.texi @@ -0,0 +1,20 @@ +@node stdout +@section @code{stdout} +@findex stdout + +POSIX specification: @url{http://www.opengroup.org/susv3xsh/stdout.html} + +Gnulib module: --- + +Portability problems fixed by Gnulib: +@itemize +@end itemize + +Portability problems not fixed by Gnulib: +@itemize +@item +stdout is created in 32-bit mode instead of 64-bit mode: Cygwin 1.5.x. +One workaround is to use freopen(NULL, ``w'', stdout) on Cygwin 1.5.21 +or newer. Another is to use the gnulib ftello module and do +ftello(stdout). +@end itemize diff --git a/doc/gnulib.texi b/doc/gnulib.texi index ab537300e..34e893672 100644 --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -1,5 +1,5 @@ \input texinfo @c -*-texinfo-*- -@comment $Id: gnulib.texi,v 1.40 2007-05-01 22:37:10 haible Exp $ +@comment $Id: gnulib.texi,v 1.41 2007-05-24 03:53:38 ericb Exp $ @comment %**start of header @setfilename gnulib.info @settitle GNU Gnulib @@ -7,7 +7,7 @@ @syncodeindex pg cp @comment %**end of header -@set UPDATED $Date: 2007-05-01 22:37:10 $ +@set UPDATED $Date: 2007-05-24 03:53:38 $ @copying This manual is for GNU Gnulib (updated @value{UPDATED}), @@ -1543,7 +1543,9 @@ by Gnulib. * sscanf:: * stat:: * statvfs:: +* stderr:: * stdin:: +* stdout:: * strcasecmp:: * strcat:: * strchr:: @@ -2659,7 +2661,9 @@ by Gnulib. @include functions/sscanf.texi @include functions/stat.texi @include functions/statvfs.texi +@include functions/stderr.texi @include functions/stdin.texi +@include functions/stdout.texi @include functions/strcasecmp.texi @include functions/strcat.texi @include functions/strchr.texi @@ -2877,3 +2881,8 @@ generated automatically. @printindex cp @bye + +@c Local Variables: +@c indent-tabs-mode: nil +@c whitespace-check-buffer-indent: nil +@c End: diff --git a/lib/fseeko.c b/lib/fseeko.c index adb6c64f3..cece4911c 100644 --- a/lib/fseeko.c +++ b/lib/fseeko.c @@ -44,6 +44,19 @@ rpl_fseeko (FILE *fp, off_t offset, int whence) # 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 if (fp->_p == fp->_bf._base && fp->_r == 0 && fp->_w == ((fp->_flags & (__SLBF | __SNBF | __SRD)) == 0 /* fully buffered and not currently reading? */ @@ -53,10 +66,10 @@ rpl_fseeko (FILE *fp, off_t offset, int whence) #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) + unsigned char *_base; \ + unsigned char *_end; \ + long _cnt; \ + } *) fp) if (fp_->_ptr == fp_->_base && (fp_->_ptr == NULL || fp_->_cnt == 0)) # else diff --git a/lib/ftello.c b/lib/ftello.c new file mode 100644 index 000000000..7054dd5b2 --- /dev/null +++ b/lib/ftello.c @@ -0,0 +1,45 @@ +/* An ftello() function that works around platform bugs. + 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 + +/* Specification. */ +#include + +#undef ftello +#if !HAVE_FTELLO +# define ftello ftell +#endif + +off_t +rpl_ftello (FILE *fp) +{ +#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 ftello 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 + return ftello (fp); +} diff --git a/lib/stdio_.h b/lib/stdio_.h index 93ef31a54..f429caaf7 100644 --- a/lib/stdio_.h +++ b/lib/stdio_.h @@ -42,7 +42,9 @@ #include #include -#if (@GNULIB_FFLUSH@ && @REPLACE_FFLUSH@) || (@GNULIB_FSEEKO@ && !@HAVE_FSEEKO@) || (@GNULIB_FTELLO@ && !@HAVE_FTELLO@) +#if (@GNULIB_FFLUSH@ && @REPLACE_FFLUSH@) \ + || (@GNULIB_FSEEKO@ && (!@HAVE_FSEEKO@ || @REPLACE_FSEEKO@)) \ + || (@GNULIB_FTELLO@ && (!@HAVE_FTELLO@ || @REPLACE_FTELLO@)) /* Get off_t. */ # include #endif @@ -216,7 +218,7 @@ extern int vsprintf (char *str, const char *format, va_list args) # endif #endif -#if @GNULIB_FFLUSH@ && @REPLACE_FFLUSH@ +#if (@GNULIB_FFLUSH@ && @REPLACE_FFLUSH@) || (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) /* 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); @@ -250,6 +252,9 @@ typedef int verify_fseeko_types[2 * (sizeof (off_t) == sizeof (long)) - 1]; /* Assume 'off_t' is the same type as 'long'. */ typedef int verify_ftello_types[2 * (sizeof (off_t) == sizeof (long)) - 1]; # define ftello ftell +# elif @REPLACE_FTELLO@ +# define ftello rpl_ftello +extern off_t ftello (FILE *fp); # endif #elif defined GNULIB_POSIXCHECK # undef ftello diff --git a/m4/fseeko.m4 b/m4/fseeko.m4 index 86d42f40c..3d79276f7 100644 --- a/m4/fseeko.m4 +++ b/m4/fseeko.m4 @@ -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,12 +8,22 @@ AC_DEFUN([gl_FUNC_FSEEKO], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) AC_CACHE_CHECK([for fseeko], [gl_cv_func_fseeko], [ AC_TRY_LINK([#include ], [fseeko (stdin, 0, 0);], - [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no]) + [gl_cv_func_fseeko=yes], [gl_cv_func_fseeko=no]) ]) if test $gl_cv_func_fseeko = no; then HAVE_FSEEKO=0 + elif test $gl_cv_var_stdin_large_offset = no; then + gl_REPLACE_FSEEKO fi ]) + +AC_DEFUN([gl_REPLACE_FSEEKO], +[ + AC_LIBOBJ([fseeko]) + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + REPLACE_FSEEKO=1 +]) diff --git a/m4/ftello.m4 b/m4/ftello.m4 index c2b826df8..474bf5313 100644 --- a/m4/ftello.m4 +++ b/m4/ftello.m4 @@ -1,4 +1,4 @@ -# ftello.m4 serial 1 +# ftello.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,12 +8,22 @@ AC_DEFUN([gl_FUNC_FTELLO], [ AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_REQUIRE([AC_PROG_CC]) + AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) AC_CACHE_CHECK([for ftello], [gl_cv_func_ftello], [ AC_TRY_LINK([#include ], [ftello (stdin);], - [gl_cv_func_ftello=yes], [gl_cv_func_ftello=no]) + [gl_cv_func_ftello=yes], [gl_cv_func_ftello=no]) ]) if test $gl_cv_func_ftello = no; then HAVE_FTELLO=0 + elif test $gl_cv_var_stdin_large_offset = no; then + gl_REPLACE_FTELLO fi ]) + +AC_DEFUN([gl_REPLACE_FTELLO], +[ + AC_LIBOBJ([ftello]) + AC_REQUIRE([gl_STDIO_H_DEFAULTS]) + REPLACE_FTELLO=1 +]) diff --git a/m4/stdio_h.m4 b/m4/stdio_h.m4 index c696ee2ee..2cddcc331 100644 --- a/m4/stdio_h.m4 +++ b/m4/stdio_h.m4 @@ -1,4 +1,4 @@ -# stdio_h.m4 serial 4 +# stdio_h.m4 serial 5 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, @@ -47,6 +47,29 @@ AC_DEFUN([gl_STDIO_H_DEFAULTS], HAVE_VASPRINTF=1; AC_SUBST([HAVE_VASPRINTF]) REPLACE_VASPRINTF=0; AC_SUBST([REPLACE_VASPRINTF]) HAVE_FSEEKO=1; AC_SUBST([HAVE_FSEEKO]) + REPLACE_FSEEKO=0; AC_SUBST([REPLACE_FSEEKO]) HAVE_FTELLO=1; AC_SUBST([HAVE_FTELLO]) + REPLACE_FTELLO=0; AC_SUBST([REPLACE_FTELLO]) REPLACE_FFLUSH=0; AC_SUBST([REPLACE_FFLUSH]) ]) + +dnl Code shared by fseeko and ftello. Determine if large files are supported, +dnl but stdin does not start as a large file by default. +AC_DEFUN([gl_STDIN_LARGE_OFFSET], + [ + AC_CACHE_CHECK([whether stdin defaults to large file offsets], + [gl_cv_var_stdin_large_offset], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], +[#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_var_stdin_large_offset=yes], + [gl_cv_var_stdin_large_offset=no])]) +]) diff --git a/modules/fseeko b/modules/fseeko index e8c10f2d5..af6eccbd1 100644 --- a/modules/fseeko +++ b/modules/fseeko @@ -2,6 +2,7 @@ Description: fseeko() function: Reposition a FILE stream. Files: +lib/fseeko.c m4/fseeko.m4 Depends-on: diff --git a/modules/fseeko-tests b/modules/fseeko-tests index 055e2af79..718832af8 100644 --- a/modules/fseeko-tests +++ b/modules/fseeko-tests @@ -1,10 +1,13 @@ Files: tests/test-fseeko.c +tests/test-fseeko.sh Depends-on: configure.ac: Makefile.am: -TESTS += test-fseeko +TESTS += test-fseeko.sh +TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)' check_PROGRAMS += test-fseeko +EXTRA_DIST += test-fseeko.sh diff --git a/modules/ftello b/modules/ftello index daac68405..2d6b72448 100644 --- a/modules/ftello +++ b/modules/ftello @@ -2,6 +2,7 @@ Description: ftello() function: Retrieve the position of a FILE stream. Files: +lib/ftello.c m4/ftello.m4 Depends-on: diff --git a/modules/ftello-tests b/modules/ftello-tests index fef915900..1d4279d1f 100644 --- a/modules/ftello-tests +++ b/modules/ftello-tests @@ -1,10 +1,13 @@ Files: tests/test-ftello.c +tests/test-ftello.sh Depends-on: configure.ac: Makefile.am: -TESTS += test-ftello +TESTS += test-ftello.sh +TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)' check_PROGRAMS += test-ftello +EXTRA_DIST += test-ftello.sh diff --git a/modules/stdio b/modules/stdio index eba4c8b04..dd49435c4 100644 --- a/modules/stdio +++ b/modules/stdio @@ -47,7 +47,9 @@ stdio.h: stdio_.h -e 's|@''HAVE_VASPRINTF''@|$(HAVE_VASPRINTF)|g' \ -e 's|@''REPLACE_VASPRINTF''@|$(REPLACE_VASPRINTF)|g' \ -e 's|@''HAVE_FSEEKO''@|$(HAVE_FSEEKO)|g' \ + -e 's|@''REPLACE_FSEEKO''@|$(REPLACE_FSEEKO)|g' \ -e 's|@''HAVE_FTELLO''@|$(HAVE_FTELLO)|g' \ + -e 's|@''REPLACE_FTELLO''@|$(REPLACE_FTELLO)|g' \ -e 's|@''REPLACE_FFLUSH''@|$(REPLACE_FFLUSH)|g' \ -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \ < $(srcdir)/stdio_.h; \ diff --git a/tests/test-fseeko.c b/tests/test-fseeko.c index 1b4c9e8d1..198cbfce3 100644 --- a/tests/test-fseeko.c +++ b/tests/test-fseeko.c @@ -27,8 +27,6 @@ int main () { - off_t pos = fseeko (stdin, (off_t)0, SEEK_CUR); - (void)pos; - - return 0; + /* This test assumes stdin is seekable. */ + return fseeko (stdin, (off_t)0, SEEK_CUR) != 0; } diff --git a/tests/test-fseeko.sh b/tests/test-fseeko.sh new file mode 100755 index 000000000..d6310c7b9 --- /dev/null +++ b/tests/test-fseeko.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./test-fseeko${EXEEXT} < "$srcdir/test-fseeko.sh" diff --git a/tests/test-ftello.c b/tests/test-ftello.c index 3feefe147..f87783fc2 100644 --- a/tests/test-ftello.c +++ b/tests/test-ftello.c @@ -27,8 +27,7 @@ int main () { + /* This test assumes stdin is seekable. */ off_t pos = ftello (stdin); - (void)pos; - - return 0; + return pos < 0; } diff --git a/tests/test-ftello.sh b/tests/test-ftello.sh new file mode 100755 index 000000000..8774c6e09 --- /dev/null +++ b/tests/test-ftello.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +./test-ftello${EXEEXT} < "$srcdir/test-ftello.sh" -- 2.11.0