From 3f3d9b41ce3bcc3f4664512c3756621126a5eab2 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 14 Apr 2012 23:27:45 +0200 Subject: [PATCH] Large File Support for native Windows platforms. * m4/largefile.m4 (gl_LARGEFILE): New macro. * modules/largefile (configure.ac): Require gl_LARGEFILE. * lib/sys_types.in.h (off_t) [WINDOWS_64_BIT_OFF_T]: Define to a 64-bit type. * m4/sys_types_h.m4 (gl_SYS_TYPES_H): Set WINDOWS_64_BIT_OFF_T. * modules/sys_types (Makefile.am): Substitute WINDOWS_64_BIT_OFF_T. * doc/posix-headers/sys_types.texi: Mention the effect of the 'largefile' module. * lib/fcntl.in.h: Add comments about off_t. * modules/fcntl-h (Depends-on): Add sys_types. * lib/unistd.in.h [WINDOWS_64_BIT_OFF_T]: Include . (ftruncate): Replace it if REPLACE_FTRUNCATE is 1. * m4/unistd_h.m4 (gl_UNISTD_H): Require gl_SYS_TYPES_H. (gl_UNISTD_H_DEFAULTS): Initialize REPLACE_FTRUNCATE. * modules/unistd (Depends-on): Add sys_types. (Makefile.am): Substitute WINDOWS_64_BIT_OFF_T, REPLACE_FTRUNCATE. * lib/lseek.c (rpl_lseek) [_GL_WINDOWS_64_BIT_OFF_T]: Use _lseeki64 instead of lseek. * m4/lseek.m4 (gl_FUNC_LSEEK): Require gl_SYS_TYPES_H. Set REPLACE_LSEEK if WINDOWS_64_BIT_OFF_T is 1. * modules/lseek (Depends-on): Add sys_types. * lib/ftruncate.c: Put under GPLv3+. Include , msvc-nothrow.h. (SetFileSize): New function. (ftruncate) [_GL_WINDOWS_64_BIT_OFF_T]: New implementation. * m4/ftruncate.m4 (gl_FUNC_FTRUNCATE): Set REPLACE_FTRUNCATE on Windows if Large File Support is requested. * modules/ftruncate (configure.ac): Consider REPLACE_FTRUNCATE. (Depends-on): Add sys_types, msvc-nothrow. Update conditions. * lib/stdio.in.h: Add comments about off_t. * modules/stdio (Depends-on): Add sys_types. * lib/ftello.c [_GL_WINDOWS_64_BIT_OFF_T]: Use _ftelli64 or ftello64 instead of ftello. * m4/ftello.m4 (gl_FUNC_FTELLO): Require gl_SYS_TYPES_H. Set REPLACE_FTELLO if WINDOWS_64_BIT_OFF_T is 1. (gl_PREREQ_FTELLO): New macro. * modules/ftello (Depends-on): Add sys_types. (configure.ac): Incoke gl_PREREQ_FTELLO. * lib/fseeko.c [_GL_WINDOWS_64_BIT_OFF_T]: Use _fseeki64 or fseeko64 instead of fseeko. * m4/fseeko.m4 (gl_FUNC_FSEEKO): Require gl_SYS_TYPES_H. Set REPLACE_FSEEKO if WINDOWS_64_BIT_OFF_T is 1. (gl_PREREQ_FSEEKO): New macro. * modules/fseeko (Depends-on): Add sys_types. (configure.ac): Invoke gl_PREREQ_FSEEKO. * lib/sys_stat.in.h: Add comments about off_t. (stat, fstat) [WINDOWS_64_BIT_ST_SIZE]: Define to variants that use a 64-bit integer for st_size in 'struct stat'. * m4/sys_stat_h.m4 (gl_HEADER_SYS_STAT_H): Set WINDOWS_64_BIT_ST_SIZE. Define _GL_WINDOWS_64_BIT_ST_SIZE. * modules/sys_stat (Depends-on): Add sys_types. (Makefile.am): Substitute WINDOWS_64_BIT_ST_SIZE. * lib/stat.c (stat) [_GL_WINDOWS_64_BIT_ST_SIZE]: Define to _stati64 instead of stat or _stat. * lib/fstat.c [_GL_WINDOWS_64_BIT_ST_SIZE]: Use _fstati64 and 'struct _stati64' instead of fstat and 'struct stat'. * m4/fstat.m4 (gl_FUNC_FSTAT): Require gl_HEADER_SYS_STAT_H. Set REPLACE_FSTAT if WINDOWS_64_BIT_ST_SIZE is 1. Reported by Ray Satiro . --- ChangeLog | 76 +++++++++++++++++++ doc/posix-headers/sys_types.texi | 5 +- lib/fcntl.in.h | 4 + lib/fseeko.c | 8 ++ lib/fstat.c | 4 + lib/ftello.c | 8 ++ lib/ftruncate.c | 157 +++++++++++++++++++++++++++++++++++++-- lib/lseek.c | 4 + lib/stat.c | 15 ++-- lib/stdio.in.h | 3 +- lib/sys_stat.in.h | 33 +++++++- lib/sys_types.in.h | 12 +++ lib/unistd.in.h | 18 ++++- m4/fseeko.m4 | 14 +++- m4/fstat.m4 | 9 ++- m4/ftello.m4 | 17 ++++- m4/ftruncate.m4 | 21 +++++- m4/largefile.m4 | 45 +++++++++++ m4/lseek.m4 | 8 +- m4/sys_stat_h.m4 | 15 +++- m4/sys_types_h.m4 | 10 ++- m4/unistd_h.m4 | 6 +- modules/fcntl-h | 1 + modules/fseeko | 2 + modules/ftello | 2 + modules/ftruncate | 6 +- modules/largefile | 1 + modules/lseek | 1 + modules/stdio | 1 + modules/sys_stat | 2 + modules/sys_types | 1 + modules/unistd | 3 + 32 files changed, 482 insertions(+), 30 deletions(-) diff --git a/ChangeLog b/ChangeLog index 17d6fb16b..582cecf50 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,79 @@ +2012-04-21 Bruno Haible + + Large File Support for native Windows platforms. + + * m4/largefile.m4 (gl_LARGEFILE): New macro. + * modules/largefile (configure.ac): Require gl_LARGEFILE. + + * lib/sys_types.in.h (off_t) [WINDOWS_64_BIT_OFF_T]: Define to a 64-bit + type. + * m4/sys_types_h.m4 (gl_SYS_TYPES_H): Set WINDOWS_64_BIT_OFF_T. + * modules/sys_types (Makefile.am): Substitute WINDOWS_64_BIT_OFF_T. + * doc/posix-headers/sys_types.texi: Mention the effect of the + 'largefile' module. + + * lib/fcntl.in.h: Add comments about off_t. + * modules/fcntl-h (Depends-on): Add sys_types. + + * lib/unistd.in.h [WINDOWS_64_BIT_OFF_T]: Include . + (ftruncate): Replace it if REPLACE_FTRUNCATE is 1. + * m4/unistd_h.m4 (gl_UNISTD_H): Require gl_SYS_TYPES_H. + (gl_UNISTD_H_DEFAULTS): Initialize REPLACE_FTRUNCATE. + * modules/unistd (Depends-on): Add sys_types. + (Makefile.am): Substitute WINDOWS_64_BIT_OFF_T, REPLACE_FTRUNCATE. + + * lib/lseek.c (rpl_lseek) [_GL_WINDOWS_64_BIT_OFF_T]: Use _lseeki64 + instead of lseek. + * m4/lseek.m4 (gl_FUNC_LSEEK): Require gl_SYS_TYPES_H. Set + REPLACE_LSEEK if WINDOWS_64_BIT_OFF_T is 1. + * modules/lseek (Depends-on): Add sys_types. + + * lib/ftruncate.c: Put under GPLv3+. Include , + msvc-nothrow.h. + (SetFileSize): New function. + (ftruncate) [_GL_WINDOWS_64_BIT_OFF_T]: New implementation. + * m4/ftruncate.m4 (gl_FUNC_FTRUNCATE): Set REPLACE_FTRUNCATE on Windows + if Large File Support is requested. + * modules/ftruncate (configure.ac): Consider REPLACE_FTRUNCATE. + (Depends-on): Add sys_types, msvc-nothrow. Update conditions. + + * lib/stdio.in.h: Add comments about off_t. + * modules/stdio (Depends-on): Add sys_types. + + * lib/ftello.c [_GL_WINDOWS_64_BIT_OFF_T]: Use _ftelli64 or ftello64 + instead of ftello. + * m4/ftello.m4 (gl_FUNC_FTELLO): Require gl_SYS_TYPES_H. Set + REPLACE_FTELLO if WINDOWS_64_BIT_OFF_T is 1. + (gl_PREREQ_FTELLO): New macro. + * modules/ftello (Depends-on): Add sys_types. + (configure.ac): Incoke gl_PREREQ_FTELLO. + + * lib/fseeko.c [_GL_WINDOWS_64_BIT_OFF_T]: Use _fseeki64 or fseeko64 + instead of fseeko. + * m4/fseeko.m4 (gl_FUNC_FSEEKO): Require gl_SYS_TYPES_H. Set + REPLACE_FSEEKO if WINDOWS_64_BIT_OFF_T is 1. + (gl_PREREQ_FSEEKO): New macro. + * modules/fseeko (Depends-on): Add sys_types. + (configure.ac): Invoke gl_PREREQ_FSEEKO. + + * lib/sys_stat.in.h: Add comments about off_t. + (stat, fstat) [WINDOWS_64_BIT_ST_SIZE]: Define to variants that use a + 64-bit integer for st_size in 'struct stat'. + * m4/sys_stat_h.m4 (gl_HEADER_SYS_STAT_H): Set WINDOWS_64_BIT_ST_SIZE. + Define _GL_WINDOWS_64_BIT_ST_SIZE. + * modules/sys_stat (Depends-on): Add sys_types. + (Makefile.am): Substitute WINDOWS_64_BIT_ST_SIZE. + + * lib/stat.c (stat) [_GL_WINDOWS_64_BIT_ST_SIZE]: Define to _stati64 + instead of stat or _stat. + + * lib/fstat.c [_GL_WINDOWS_64_BIT_ST_SIZE]: Use _fstati64 and + 'struct _stati64' instead of fstat and 'struct stat'. + * m4/fstat.m4 (gl_FUNC_FSTAT): Require gl_HEADER_SYS_STAT_H. Set + REPLACE_FSTAT if WINDOWS_64_BIT_ST_SIZE is 1. + + Reported by Ray Satiro . + 2012-04-19 Eric Blake bootstrap: accommodate older libtool diff --git a/doc/posix-headers/sys_types.texi b/doc/posix-headers/sys_types.texi index 249571a8b..29bb9ae58 100644 --- a/doc/posix-headers/sys_types.texi +++ b/doc/posix-headers/sys_types.texi @@ -27,5 +27,8 @@ Portability problems not fixed by Gnulib: On some platforms the types @code{blksize_t} and @code{suseconds_t} are signed integer types that are wider than @code{long}: glibc x32 - @end itemize + +This module, together with the module @code{largefile}, also defines the type +@code{off_t} to a 64-bit integer type on some platforms: +mingw (except mingw64), MSVC 9. diff --git a/lib/fcntl.in.h b/lib/fcntl.in.h index 344bbe4d3..76e12f78a 100644 --- a/lib/fcntl.in.h +++ b/lib/fcntl.in.h @@ -25,6 +25,8 @@ #if defined __need_system_fcntl_h /* Special invocation convention. */ +/* Needed before . + May also define off_t to a 64-bit type on native Windows. */ #include /* On some systems other than glibc, is a prerequisite of . On glibc systems, we would like to avoid namespace pollution. @@ -42,6 +44,8 @@ #ifndef _@GUARD_PREFIX@_FCNTL_H +/* Needed before . + May also define off_t to a 64-bit type on native Windows. */ #include /* On some systems other than glibc, is a prerequisite of . On glibc systems, we would like to avoid namespace pollution. diff --git a/lib/fseeko.c b/lib/fseeko.c index ab05709b3..74465603a 100644 --- a/lib/fseeko.c +++ b/lib/fseeko.c @@ -31,6 +31,14 @@ fseeko (FILE *fp, off_t offset, int whence) # undef fseek # define fseeko fseek #endif +#if _GL_WINDOWS_64_BIT_OFF_T +# undef fseeko +# if HAVE__FSEEKI64 /* msvc, mingw64 */ +# define fseeko _fseeki64 +# else /* mingw */ +# define fseeko fseeko64 +# endif +#endif { #if LSEEK_PIPE_BROKEN /* mingw gives bogus answers rather than failure on non-seekable files. */ diff --git a/lib/fstat.c b/lib/fstat.c index 4918495bc..ac2b1effe 100644 --- a/lib/fstat.c +++ b/lib/fstat.c @@ -23,6 +23,10 @@ /* Get the original definition of fstat. It might be defined as a macro. */ #include #include +#if _GL_WINDOWS_64_BIT_ST_SIZE +# define stat _stati64 +# define fstat _fstati64 +#endif #undef __need_system_sys_stat_h static inline int diff --git a/lib/ftello.c b/lib/ftello.c index 1beb20296..1f581c5a4 100644 --- a/lib/ftello.c +++ b/lib/ftello.c @@ -31,6 +31,14 @@ ftello (FILE *fp) # undef ftell # define ftello ftell #endif +#if _GL_WINDOWS_64_BIT_OFF_T +# undef ftello +# if HAVE__FTELLI64 /* msvc, mingw64 */ +# define ftello _ftelli64 +# else /* mingw */ +# define ftello ftello64 +# endif +#endif { #if LSEEK_PIPE_BROKEN /* mingw gives bogus answers rather than failure on non-seekable files. */ diff --git a/lib/ftruncate.c b/lib/ftruncate.c index ae1e85890..e243adda6 100644 --- a/lib/ftruncate.c +++ b/lib/ftruncate.c @@ -1,5 +1,18 @@ /* ftruncate emulations for native Windows. - This file is in the public domain. */ + Copyright (C) 1992-2012 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 3, 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, see . */ #include @@ -7,12 +20,143 @@ #include #if HAVE_CHSIZE +/* A native Windows platform. */ # include -# include -# if HAVE_MSVC_INVALID_PARAMETER_HANDLER -# include "msvc-inval.h" +# if _GL_WINDOWS_64_BIT_OFF_T + +/* Large File Support: off_t is 64-bit, but chsize() takes only a 32-bit + argument. So, define a 64-bit safe SetFileSize function ourselves. */ + +/* Ensure that declares GetFileSizeEx. */ +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x500 + +/* Get declarations of the native Windows API functions. */ +# define WIN32_LEAN_AND_MEAN +# include + +/* Get _get_osfhandle. */ +# include "msvc-nothrow.h" + +static BOOL +SetFileSize (HANDLE h, LONGLONG size) +{ + LARGE_INTEGER old_size; + + if (!GetFileSizeEx (h, &old_size)) + return FALSE; + + if (size != old_size.QuadPart) + { + /* Duplicate the handle, so we are free to modify its file position. */ + HANDLE curr_process = GetCurrentProcess (); + HANDLE tmph; + + if (!DuplicateHandle (curr_process, /* SourceProcessHandle */ + h, /* SourceHandle */ + curr_process, /* TargetProcessHandle */ + (PHANDLE) &tmph, /* TargetHandle */ + (DWORD) 0, /* DesiredAccess */ + FALSE, /* InheritHandle */ + DUPLICATE_SAME_ACCESS)) /* Options */ + return FALSE; + + if (size < old_size.QuadPart) + { + /* Reduce the size. */ + LONG size_hi = (LONG) (size >> 32); + if (SetFilePointer (tmph, (LONG) size, &size_hi, FILE_BEGIN) + == INVALID_SET_FILE_POINTER + && GetLastError() != NO_ERROR) + { + CloseHandle (tmph); + return FALSE; + } + if (!SetEndOfFile (tmph)) + { + CloseHandle (tmph); + return FALSE; + } + } + else + { + /* Increase the size by adding zero bytes at the end. */ + static char zero_bytes[1024]; + LONG pos_hi = 0; + LONG pos_lo = SetFilePointer (tmph, (LONG) 0, &pos_hi, FILE_END); + LONGLONG pos; + if (pos_lo == INVALID_SET_FILE_POINTER + && GetLastError() != NO_ERROR) + { + CloseHandle (tmph); + return FALSE; + } + pos = ((LONGLONG) pos_hi << 32) | (ULONGLONG) (ULONG) pos_lo; + while (pos < size) + { + DWORD written; + LONGLONG count = size - pos; + if (count > sizeof (zero_bytes)) + count = sizeof (zero_bytes); + if (!WriteFile (tmph, zero_bytes, (DWORD) count, &written, NULL) + || written == 0) + { + CloseHandle (tmph); + return FALSE; + } + pos += (ULONGLONG) (ULONG) written; + } + } + /* Close the handle. */ + CloseHandle (tmph); + } + return TRUE; +} + +int +ftruncate (int fd, off_t length) +{ + HANDLE handle = (HANDLE) _get_osfhandle (fd); + + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + if (length < 0) + { + errno = EINVAL; + return -1; + } + if (!SetFileSize (handle, length)) + { + switch (GetLastError ()) + { + case ERROR_ACCESS_DENIED: + errno = EACCES; + break; + case ERROR_HANDLE_DISK_FULL: + case ERROR_DISK_FULL: + case ERROR_DISK_TOO_FRAGMENTED: + errno = ENOSPC; + break; + default: + errno = EIO; + break; + } + return -1; + } + return 0; +} + +# else + +# include + +# if HAVE_MSVC_INVALID_PARAMETER_HANDLER +# include "msvc-inval.h" static inline int chsize_nothrow (int fd, long length) { @@ -31,8 +175,8 @@ chsize_nothrow (int fd, long length) return result; } -# define chsize chsize_nothrow -# endif +# define chsize chsize_nothrow +# endif int ftruncate (int fd, off_t length) @@ -40,4 +184,5 @@ ftruncate (int fd, off_t length) return chsize (fd, length); } +# endif #endif diff --git a/lib/lseek.c b/lib/lseek.c index 86f500b19..f47ef8f16 100644 --- a/lib/lseek.c +++ b/lib/lseek.c @@ -59,5 +59,9 @@ rpl_lseek (int fd, off_t offset, int whence) return -1; } #endif +#if _GL_WINDOWS_64_BIT_OFF_T + return _lseeki64 (fd, offset, whence); +#else return lseek (fd, offset, whence); +#endif } diff --git a/lib/stat.c b/lib/stat.c index 29acd9a76..1fc633eee 100644 --- a/lib/stat.c +++ b/lib/stat.c @@ -27,13 +27,18 @@ #include #undef __need_system_sys_stat_h -#if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ - && REPLACE_FUNC_STAT_FILE +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ +# if _GL_WINDOWS_64_BIT_ST_SIZE +# define stat _stati64 +# define REPLACE_FUNC_STAT_DIR 1 +# undef REPLACE_FUNC_STAT_FILE +# elif REPLACE_FUNC_STAT_FILE /* mingw64 has a broken stat() function, based on _stat(), in libmingwex.a. Bypass it. */ -# define stat _stat -# define REPLACE_FUNC_STAT_DIR 1 -# undef REPLACE_FUNC_STAT_FILE +# define stat _stat +# define REPLACE_FUNC_STAT_DIR 1 +# undef REPLACE_FUNC_STAT_FILE +# endif #endif static inline int diff --git a/lib/stdio.in.h b/lib/stdio.in.h index c377b6e02..fab325d32 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -52,7 +52,8 @@ #include /* Get off_t and ssize_t. Needed on many systems, including glibc 2.8 - and eglibc 2.11.2. */ + and eglibc 2.11.2. + May also define off_t to a 64-bit type on native Windows. */ #include /* The __attribute__ feature is available in gcc versions 2.5 and later. diff --git a/lib/sys_stat.in.h b/lib/sys_stat.in.h index 476e6f205..e9e06a24d 100644 --- a/lib/sys_stat.in.h +++ b/lib/sys_stat.in.h @@ -35,7 +35,8 @@ #ifndef _@GUARD_PREFIX@_SYS_STAT_H -/* Get nlink_t. */ +/* Get nlink_t. + May also define off_t to a 64-bit type on native Windows. */ #include /* Get struct timespec. */ @@ -66,6 +67,11 @@ # include #endif +/* Large File Support on native Windows. */ +#if @WINDOWS_64_BIT_ST_SIZE@ +# define stat _stati64 +#endif + #ifndef S_IFIFO # ifdef _S_IFIFO # define S_IFIFO _S_IFIFO @@ -335,6 +341,9 @@ _GL_CXXALIAS_RPL (fstat, int, (int fd, struct stat *buf)); _GL_CXXALIAS_SYS (fstat, int, (int fd, struct stat *buf)); # endif _GL_CXXALIASWARN (fstat); +#elif @WINDOWS_64_BIT_ST_SIZE@ +/* Above, we define stat to _stati64. */ +# define fstat _fstati64 #elif defined GNULIB_POSIXCHECK # undef fstat # if HAVE_RAW_DECL_FSTAT @@ -620,6 +629,28 @@ _GL_WARN_ON_USE (mknodat, "mknodat is not portable - " so we have to replace stat64() instead of stat(). */ # undef stat64 # define stat64(name, st) rpl_stat (name, st) +# elif @WINDOWS_64_BIT_ST_SIZE@ + /* Above, we define stat to _stati64. */ +# if defined __MINGW32__ && defined _stati64 +# ifndef _USE_32BIT_TIME_T + /* The system headers define _stati64 to _stat64. */ +# undef _stat64 +# define _stat64(name, st) rpl_stat (name, st) +# endif +# elif defined _MSC_VER && defined _stati64 +# ifdef _USE_32BIT_TIME_T + /* The system headers define _stati64 to _stat32i64. */ +# undef _stat32i64 +# define _stat32i64(name, st) rpl_stat (name, st) +# else + /* The system headers define _stati64 to _stat64. */ +# undef _stat64 +# define _stat64(name, st) rpl_stat (name, st) +# endif +# else +# undef _stati64 +# define _stati64(name, st) rpl_stat (name, st) +# endif # elif defined __MINGW32__ && defined stat # ifdef _USE_32BIT_TIME_T /* The system headers define stat to _stat32i64. */ diff --git a/lib/sys_types.in.h b/lib/sys_types.in.h index 3989de34e..8992dde9a 100644 --- a/lib/sys_types.in.h +++ b/lib/sys_types.in.h @@ -28,6 +28,18 @@ #ifndef _@GUARD_PREFIX@_SYS_TYPES_H #define _@GUARD_PREFIX@_SYS_TYPES_H +/* Override off_t if Large File Support is requested on native Windows. */ +#if @WINDOWS_64_BIT_OFF_T@ +/* Same as int64_t in . */ +# if defined _MSC_VER +# define off_t __int64 +# else +# define off_t long long int +# endif +/* Indicator, for gnulib internal purposes. */ +# define _GL_WINDOWS_64_BIT_OFF_T 1 +#endif + /* MSVC 9 defines size_t in , not in . */ /* But avoid namespace pollution on glibc systems. */ #if ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \ diff --git a/lib/unistd.in.h b/lib/unistd.in.h index 9949df57a..7246d0248 100644 --- a/lib/unistd.in.h +++ b/lib/unistd.in.h @@ -107,8 +107,9 @@ # include #endif -/* MSVC defines off_t in . */ -#if !@HAVE_UNISTD_H@ +/* MSVC defines off_t in . + May also define off_t to a 64-bit type on native Windows. */ +#if !@HAVE_UNISTD_H@ || @WINDOWS_64_BIT_OFF_T@ /* Get off_t. */ # include #endif @@ -562,10 +563,19 @@ _GL_WARN_ON_USE (fsync, "fsync is unportable - " Return 0 if successful, otherwise -1 and errno set. See the POSIX:2008 specification . */ -# if !@HAVE_FTRUNCATE@ +# if @REPLACE_FTRUNCATE@ +# if !(defined __cplusplus && defined GNULIB_NAMESPACE) +# undef ftruncate +# define ftruncate rpl_ftruncate +# endif +_GL_FUNCDECL_RPL (ftruncate, int, (int fd, off_t length)); +_GL_CXXALIAS_RPL (ftruncate, int, (int fd, off_t length)); +# else +# if !@HAVE_FTRUNCATE@ _GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length)); -# endif +# endif _GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length)); +# endif _GL_CXXALIASWARN (ftruncate); #elif defined GNULIB_POSIXCHECK # undef ftruncate diff --git a/m4/fseeko.m4 b/m4/fseeko.m4 index be5bb35ed..1bb88c761 100644 --- a/m4/fseeko.m4 +++ b/m4/fseeko.m4 @@ -1,4 +1,4 @@ -# fseeko.m4 serial 15 +# fseeko.m4 serial 16 dnl Copyright (C) 2007-2012 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([gl_STDIN_LARGE_OFFSET]) + AC_REQUIRE([gl_SYS_TYPES_H]) AC_REQUIRE([AC_PROG_CC]) dnl Persuade glibc to declare fseeko(). @@ -28,6 +29,9 @@ AC_DEFUN([gl_FUNC_FSEEKO], if test $gl_cv_func_fseeko = no; then HAVE_FSEEKO=0 else + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_FSEEKO=1 + fi if test $gl_cv_var_stdin_large_offset = no; then REPLACE_FSEEKO=1 fi @@ -59,3 +63,11 @@ AC_DEFUN([gl_STDIN_LARGE_OFFSET], [gl_cv_var_stdin_large_offset=yes], [gl_cv_var_stdin_large_offset=no])]) ]) + +# Prerequisites of lib/fseeko.c. +AC_DEFUN([gl_PREREQ_FSEEKO], +[ + dnl Native Windows has the function _fseeki64. mingw hides it, but mingw64 + dnl makes it usable again. + AC_CHECK_FUNCS([_fseeki64]) +]) diff --git a/m4/fstat.m4 b/m4/fstat.m4 index e3f8f3e2e..fb07fed4c 100644 --- a/m4/fstat.m4 +++ b/m4/fstat.m4 @@ -1,4 +1,4 @@ -# fstat.m4 serial 1 +# fstat.m4 serial 2 dnl Copyright (C) 2011-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,10 +7,17 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_FSTAT], [ AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS]) + AC_REQUIRE([gl_MSVC_INVAL]) if test $HAVE_MSVC_INVALID_PARAMETER_HANDLER = 1; then REPLACE_FSTAT=1 fi + + AC_REQUIRE([gl_HEADER_SYS_STAT_H]) + if test $WINDOWS_64_BIT_ST_SIZE = 1; then + REPLACE_FSTAT=1 + fi + dnl Replace fstat() for supporting the gnulib-defined open() on directories. m4_ifdef([gl_FUNC_FCHDIR], [ gl_TEST_FCHDIR diff --git a/m4/ftello.m4 b/m4/ftello.m4 index 42be83e5a..ab7b548eb 100644 --- a/m4/ftello.m4 +++ b/m4/ftello.m4 @@ -1,4 +1,4 @@ -# ftello.m4 serial 10 +# ftello.m4 serial 11 dnl Copyright (C) 2007-2012 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,6 +9,7 @@ AC_DEFUN([gl_FUNC_FTELLO], AC_REQUIRE([gl_STDIO_H_DEFAULTS]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([gl_STDIN_LARGE_OFFSET]) + AC_REQUIRE([gl_SYS_TYPES_H]) dnl Persuade glibc to declare ftello(). AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) @@ -30,9 +31,13 @@ AC_DEFUN([gl_FUNC_FTELLO], if test $gl_cv_func_ftello = no; then HAVE_FTELLO=0 else + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_FTELLO=1 + fi if test $gl_cv_var_stdin_large_offset = no; then REPLACE_FTELLO=1 - else + fi + if test $REPLACE_FTELLO = 0; then dnl Detect bug on Solaris. dnl ftell and ftello produce incorrect results after putc that followed a dnl getc call that reached EOF on Solaris. This is because the _IOREAD @@ -125,3 +130,11 @@ main (void) fi fi ]) + +# Prerequisites of lib/ftello.c. +AC_DEFUN([gl_PREREQ_FTELLO], +[ + dnl Native Windows has the function _ftelli64. mingw hides it, but mingw64 + dnl makes it usable again. + AC_CHECK_FUNCS([_ftelli64]) +]) diff --git a/m4/ftruncate.m4 b/m4/ftruncate.m4 index 1007f3412..969eb0412 100644 --- a/m4/ftruncate.m4 +++ b/m4/ftruncate.m4 @@ -1,4 +1,4 @@ -# serial 18 +# serial 19 # See if we need to emulate a missing ftruncate function using chsize. @@ -11,7 +11,24 @@ AC_DEFUN([gl_FUNC_FTRUNCATE], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) AC_CHECK_FUNCS_ONCE([ftruncate]) - if test $ac_cv_func_ftruncate = no; then + if test $ac_cv_func_ftruncate = yes; then + m4_ifdef([gl_LARGEFILE], [ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) + dnl Native Windows, and Large File Support is requested. + dnl The MSVCRT _chsize() function only accepts a 32-bit file size, + dnl and the mingw64 ftruncate64() function is unreliable (it may + dnl delete the file, see + dnl ). + dnl Use gnulib's ftruncate() implementation instead. + REPLACE_FTRUNCATE=1 + ;; + esac + ], [ + : + ]) + else HAVE_FTRUNCATE=0 fi ]) diff --git a/m4/largefile.m4 b/m4/largefile.m4 index 1369bbe52..a159f4ab2 100644 --- a/m4/largefile.m4 +++ b/m4/largefile.m4 @@ -102,3 +102,48 @@ fi ])# AC_SYS_LARGEFILE ])# m4_version_prereq 2.69 + +# Enable large files on systems where this is implemented by Gnulib, not by the +# system headers. +# Set the variables WINDOWS_64_BIT_OFF_T, WINDOWS_64_BIT_ST_SIZE if Gnulib +# overrides ensure that off_t or 'struct size.st_size' are 64-bit, respectively. +AC_DEFUN([gl_LARGEFILE], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + case "$host_os" in + mingw*) + dnl Native Windows. + dnl mingw64 defines off_t to a 64-bit type already, if + dnl _FILE_OFFSET_BITS=64, which is ensured by AC_SYS_LARGEFILE. + AC_CACHE_CHECK([for 64-bit off_t], [gl_cv_type_off_t_64], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[#include + int verify_off_t_size[sizeof (off_t) >= 8 ? 1 : -1]; + ]], + [[]])], + [gl_cv_type_off_t_64=yes], [gl_cv_type_off_t_64=no]) + ]) + if test $gl_cv_type_off_t_64 = no; then + WINDOWS_64_BIT_OFF_T=1 + else + WINDOWS_64_BIT_OFF_T=0 + fi + dnl But all native Windows platforms (including mingw64) have a 32-bit + dnl st_size member in 'struct stat'. + WINDOWS_64_BIT_ST_SIZE=1 + ;; + *) + dnl Nothing to do on gnulib's side. + dnl A 64-bit off_t is + dnl - already the default on MacOS X, FreeBSD, NetBSD, OpenBSD, IRIX, + dnl OSF/1, Cygwin, + dnl - enabled by _FILE_OFFSET_BITS=64 (ensured by AC_SYS_LARGEFILE) on + dnl glibc, HP-UX, Solaris, + dnl - enabled by _LARGE_FILES=1 (ensured by AC_SYS_LARGEFILE) on AIX, + dnl - impossible to achieve on Minix 3.1.8. + WINDOWS_64_BIT_OFF_T=0 + WINDOWS_64_BIT_ST_SIZE=0 + ;; + esac +]) diff --git a/m4/lseek.m4 b/m4/lseek.m4 index 0c51313e1..bdda7f659 100644 --- a/m4/lseek.m4 +++ b/m4/lseek.m4 @@ -1,4 +1,4 @@ -# lseek.m4 serial 9 +# lseek.m4 serial 10 dnl Copyright (C) 2007, 2009-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -7,6 +7,7 @@ dnl with or without modifications, as long as this notice is preserved. AC_DEFUN([gl_FUNC_LSEEK], [ AC_REQUIRE([gl_UNISTD_H_DEFAULTS]) + AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_CHECK_HEADERS_ONCE([unistd.h]) @@ -62,4 +63,9 @@ AC_DEFUN([gl_FUNC_LSEEK], AC_DEFINE([LSEEK_PIPE_BROKEN], [1], [Define to 1 if lseek does not detect pipes.]) fi + + AC_REQUIRE([gl_SYS_TYPES_H]) + if test $WINDOWS_64_BIT_OFF_T = 1; then + REPLACE_LSEEK=1 + fi ]) diff --git a/m4/sys_stat_h.m4 b/m4/sys_stat_h.m4 index a0b96bc37..f45dee1dc 100644 --- a/m4/sys_stat_h.m4 +++ b/m4/sys_stat_h.m4 @@ -1,4 +1,4 @@ -# sys_stat_h.m4 serial 26 -*- Autoconf -*- +# sys_stat_h.m4 serial 27 -*- Autoconf -*- dnl Copyright (C) 2006-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -22,6 +22,19 @@ AC_DEFUN([gl_HEADER_SYS_STAT_H], dnl Ensure the type mode_t gets defined. AC_REQUIRE([AC_TYPE_MODE_T]) + dnl Whether to override 'struct stat'. + m4_ifdef([gl_LARGEFILE], [ + AC_REQUIRE([gl_LARGEFILE]) + ], [ + WINDOWS_64_BIT_ST_SIZE=0 + ]) + AC_SUBST([WINDOWS_64_BIT_ST_SIZE]) + if test $WINDOWS_64_BIT_ST_SIZE = 1; then + AC_DEFINE([_GL_WINDOWS_64_BIT_ST_SIZE], [1], + [Define to 1 if Gnulib overrides 'struct stat' on Windows so that + struct stat.st_size becomes 64-bit.]) + fi + dnl Define types that are supposed to be defined in or dnl . AC_CHECK_TYPE([nlink_t], [], diff --git a/m4/sys_types_h.m4 b/m4/sys_types_h.m4 index 8d18ddb4d..a14ba2447 100644 --- a/m4/sys_types_h.m4 +++ b/m4/sys_types_h.m4 @@ -1,4 +1,4 @@ -# sys_types_h.m4 serial 2 +# sys_types_h.m4 serial 3 dnl Copyright (C) 2011-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -14,6 +14,14 @@ AC_DEFUN([gl_SYS_TYPES_H], dnl Ensure the type mode_t gets defined. AC_REQUIRE([AC_TYPE_MODE_T]) + + dnl Whether to override the 'off_t' type. + m4_ifdef([gl_LARGEFILE], [ + AC_REQUIRE([gl_LARGEFILE]) + ], [ + WINDOWS_64_BIT_OFF_T=0 + ]) + AC_SUBST([WINDOWS_64_BIT_OFF_T]) ]) AC_DEFUN([gl_SYS_TYPES_H_DEFAULTS], diff --git a/m4/unistd_h.m4 b/m4/unistd_h.m4 index 7595534fd..d636caf11 100644 --- a/m4/unistd_h.m4 +++ b/m4/unistd_h.m4 @@ -1,4 +1,4 @@ -# unistd_h.m4 serial 63 +# unistd_h.m4 serial 64 dnl Copyright (C) 2006-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -24,6 +24,9 @@ AC_DEFUN([gl_UNISTD_H], dnl Ensure the type pid_t gets defined. AC_REQUIRE([AC_TYPE_PID_T]) + dnl Determine WINDOWS_64_BIT_OFF_T. + AC_REQUIRE([gl_SYS_TYPES_H]) + dnl Check for declarations of anything we want to poison if the dnl corresponding gnulib module is not in use. gl_WARN_ON_USE_PREPARE([[ @@ -155,6 +158,7 @@ AC_DEFUN([gl_UNISTD_H_DEFAULTS], REPLACE_DUP=0; AC_SUBST([REPLACE_DUP]) REPLACE_DUP2=0; AC_SUBST([REPLACE_DUP2]) REPLACE_FCHOWNAT=0; AC_SUBST([REPLACE_FCHOWNAT]) + REPLACE_FTRUNCATE=0; AC_SUBST([REPLACE_FTRUNCATE]) REPLACE_GETCWD=0; AC_SUBST([REPLACE_GETCWD]) REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME]) REPLACE_GETLOGIN_R=0; AC_SUBST([REPLACE_GETLOGIN_R]) diff --git a/modules/fcntl-h b/modules/fcntl-h index a687eebee..eeac31f1b 100644 --- a/modules/fcntl-h +++ b/modules/fcntl-h @@ -12,6 +12,7 @@ include_next snippet/arg-nonnull snippet/c++defs snippet/warn-on-use +sys_types unistd configure.ac: diff --git a/modules/fseeko b/modules/fseeko index 75b129ca5..cd106aa5e 100644 --- a/modules/fseeko +++ b/modules/fseeko @@ -11,6 +11,7 @@ extensions largefile lseek stdio +sys_types # Just to guarantee consistency between fseek() and fseeko(). fseek @@ -21,6 +22,7 @@ configure.ac: gl_FUNC_FSEEKO if test $HAVE_FSEEKO = 0 || test $REPLACE_FSEEKO = 1; then AC_LIBOBJ([fseeko]) + gl_PREREQ_FSEEKO fi gl_STDIO_MODULE_INDICATOR([fseeko]) diff --git a/modules/ftello b/modules/ftello index b64d80eea..4e81f71b5 100644 --- a/modules/ftello +++ b/modules/ftello @@ -11,6 +11,7 @@ Depends-on: stdio extensions largefile +sys_types lseek [test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1] # Just to guarantee consistency between ftell() and ftello(). ftell @@ -22,6 +23,7 @@ configure.ac: gl_FUNC_FTELLO if test $HAVE_FTELLO = 0 || test $REPLACE_FTELLO = 1; then AC_LIBOBJ([ftello]) + gl_PREREQ_FTELLO fi gl_STDIO_MODULE_INDICATOR([ftello]) diff --git a/modules/ftruncate b/modules/ftruncate index 097ed9c77..5a8913975 100644 --- a/modules/ftruncate +++ b/modules/ftruncate @@ -7,12 +7,14 @@ m4/ftruncate.m4 Depends-on: unistd +sys_types largefile -msvc-inval [test $HAVE_FTRUNCATE = 0] +msvc-nothrow [test $HAVE_FTRUNCATE = 0 || test $REPLACE_FTRUNCATE = 1] +msvc-inval [test $HAVE_FTRUNCATE = 0 || test $REPLACE_FTRUNCATE = 1] configure.ac: gl_FUNC_FTRUNCATE -if test $HAVE_FTRUNCATE = 0; then +if test $HAVE_FTRUNCATE = 0 || test $REPLACE_FTRUNCATE = 1; then AC_LIBOBJ([ftruncate]) gl_PREREQ_FTRUNCATE fi diff --git a/modules/largefile b/modules/largefile index ca10d480e..4700bef25 100644 --- a/modules/largefile +++ b/modules/largefile @@ -10,6 +10,7 @@ configure.ac-early: AC_REQUIRE([AC_SYS_LARGEFILE]) configure.ac: +AC_REQUIRE([gl_LARGEFILE]) Makefile.am: diff --git a/modules/lseek b/modules/lseek index 1ec6e2a90..ced443123 100644 --- a/modules/lseek +++ b/modules/lseek @@ -7,6 +7,7 @@ m4/lseek.m4 Depends-on: unistd +sys_types largefile msvc-nothrow [test $REPLACE_LSEEK = 1] fstat [test $REPLACE_LSEEK = 1] diff --git a/modules/stdio b/modules/stdio index a3894400b..1eec2bf26 100644 --- a/modules/stdio +++ b/modules/stdio @@ -12,6 +12,7 @@ snippet/c++defs snippet/warn-on-use ssize_t stddef +sys_types configure.ac: gl_STDIO_H diff --git a/modules/sys_stat b/modules/sys_stat index 372e65389..f8d863321 100644 --- a/modules/sys_stat +++ b/modules/sys_stat @@ -11,6 +11,7 @@ include_next snippet/arg-nonnull snippet/c++defs snippet/warn-on-use +sys_types time configure.ac: @@ -31,6 +32,7 @@ sys/stat.h: sys_stat.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNU -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_STAT_H''@|$(NEXT_SYS_STAT_H)|g' \ + -e 's|@''WINDOWS_64_BIT_ST_SIZE''@|$(WINDOWS_64_BIT_ST_SIZE)|g' \ -e 's/@''GNULIB_FCHMODAT''@/$(GNULIB_FCHMODAT)/g' \ -e 's/@''GNULIB_FSTAT''@/$(GNULIB_FSTAT)/g' \ -e 's/@''GNULIB_FSTATAT''@/$(GNULIB_FSTATAT)/g' \ diff --git a/modules/sys_types b/modules/sys_types index 810f640cd..ac0ca1daf 100644 --- a/modules/sys_types +++ b/modules/sys_types @@ -27,6 +27,7 @@ sys/types.h: sys_types.in.h $(top_builddir)/config.status -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_TYPES_H''@|$(NEXT_SYS_TYPES_H)|g' \ + -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ < $(srcdir)/sys_types.in.h; \ } > $@-t && \ mv $@-t $@ diff --git a/modules/unistd b/modules/unistd index 38f051503..0d444126d 100644 --- a/modules/unistd +++ b/modules/unistd @@ -12,6 +12,7 @@ snippet/c++defs snippet/warn-on-use ssize_t stddef +sys_types configure.ac: gl_UNISTD_H @@ -30,6 +31,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \ -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \ + -e 's|@''WINDOWS_64_BIT_OFF_T''@|$(WINDOWS_64_BIT_OFF_T)|g' \ -e 's/@''GNULIB_CHDIR''@/$(GNULIB_CHDIR)/g' \ -e 's/@''GNULIB_CHOWN''@/$(GNULIB_CHOWN)/g' \ -e 's/@''GNULIB_CLOSE''@/$(GNULIB_CLOSE)/g' \ @@ -128,6 +130,7 @@ unistd.h: unistd.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \ -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \ -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \ + -e 's|@''REPLACE_FTRUNCATE''@|$(REPLACE_FTRUNCATE)|g' \ -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \ -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \ -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \ -- 2.11.0