+2018-11-25 Keith Marshall <keith@users.osdn.me>
+
+ Emulate _fseeki64()/_ftelli64() API on legacy platforms.
+
+ * mingwex/stdio/fseeki64.c: New file; it implements...
+ (__mingw_fseeki64, fseeko64): ...both of these functions, avoiding any
+ dependency on undocumented internal implementation details of...
+ (fpos_t): ...this opaque data type, and replacing...
+ * mingwex/stdio/fseeko64.c: ...this; delete it.
+
+ * mingwex/stdio/ftelli64.c: New file; it implements...
+ (_ftelli64, ftello64): ...both of these, again avoiding any dependency
+ on undocumented internal implementation details of...
+ (fpos_t): ...this opaque data type.
+
+ * include/stdio.h (fpos_t): Make it more effectively opaque.
+ (__mingw_fseeki64, __mingw_ftelli64): Declare them for legacy use.
+ [_WIN32_WINNT < VISTA && __MSVCRT_VERSION__ < MSVCR80_DLL] (_fseeki64)
+ (_ftelli64): Map inline emulations, to "__mingw" prefixed names.
+ (ftello64): Remove inline implementation.
+
+ * Makefile.in (libmingwex.a): Add references to...
+ (fseeki64.$OBJEXT, ftelli64.$OBJEXT): these; remove reference to...
+ (fseeko64.$OBJEXT): ...this.
+
2018-10-21 Keith Marshall <keith@users.osdn.me>
Update <conio.h> and <wchar.h> header files.
# compatibility than their Microsoft equivalents.
#
vpath %.c ${mingwrt_srcdir}/mingwex/stdio
-libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeko64 ofmtctl pformat \
- printf snprintf sprintf vfprintf vfscanf vfwscanf vprintf vscanf vsnprintf \
- vsprintf vsscanf vswscanf vwscanf)
+libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeki64 ftelli64 \
+ ofmtctl pformat printf snprintf sprintf vfprintf vfscanf vfwscanf vprintf \
+ vscanf vsnprintf vsprintf vsscanf vswscanf vwscanf)
# pformat.$(OBJEXT) needs an explicit build rule, since we need to
# specify an additional header file path.
* $Id$
*
* Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
- * Copyright (C) 1997-2005, 2007-2010, 2014-2017, MinGW.org Project.
+ * Copyright (C) 1997-2005, 2007-2010, 2014-2018, MinGW.org Project.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a
_CRTIMP __cdecl __MINGW_NOTHROW long ftell (FILE *);
_CRTIMP __cdecl __MINGW_NOTHROW void rewind (FILE *);
+#ifdef __USE_MINGW_FSEEK
+/* Workaround for a limitation on Win9x where a file is not zero padded
+ * on write, following a seek beyond the original end of file; these are
+ * implemented in libmingwex.a
+ */
+__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, long, int);
+__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *);
+
+#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp)
+#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence)
+#endif /* __USE_MINGW_FSEEK */
+
+/* An opaque data type used for storing file positions... The contents
+ * of this type are unknown, but we (the compiler) need to know the size
+ * because the programmer using fgetpos and fsetpos will be setting aside
+ * storage for fpos_t aggregates. Actually I tested using a byte array and
+ * it is fairly evident that fpos_t is a 32-bit type in CRTDLL.DLL, but in
+ * MSVCRT.DLL, it is a 64-bit type. Define it in terms of an int type of
+ * the appropriate size, encapsulated within an aggregate type, to make
+ * it opaque to casting, and so discourage abuse.
+ */
+#ifdef __MSVCRT__
+typedef union { __int64 __value; __off64_t __offset; } fpos_t;
+#else
+typedef union { __int32 __value; __off32_t __offset; } fpos_t;
+#endif
+
+_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *);
+_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *);
+
#if _WIN32_WINNT >= _WIN32_WINNT_VISTA || __MSVCRT_VERSION__ >= __MSVCR80_DLL
/*
* Microsoft introduced a number of variations on fseek() and ftell(),
_CRTIMP __cdecl __MINGW_NOTHROW __int64 _ftelli64_nolock (FILE *);
#endif /* MSVCR80.DLL and later derivatives ONLY */
-#endif /* MSVCR80.DLL and descendants, or MSVCRT.DLL since Vista */
-
-#ifdef __USE_MINGW_FSEEK
-/* Workaround for a limitation on Win9x where a file is not zero padded
- * on write, following a seek beyond the original end of file; these are
- * implemented in libmingwex.a
- */
-__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, long, int);
-__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *);
-
-#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp)
-#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence)
-#endif /* __USE_MINGW_FSEEK */
-/* An opaque data type used for storing file positions... The contents of
- * this type are unknown, but we (the compiler) need to know the size
- * because the programmer using fgetpos and fsetpos will be setting aside
- * storage for fpos_t structres. Actually I tested using a byte array and
- * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL).
- * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in
- * MSVCRT however, and for now `long long' will do.
- */
-#ifdef __MSVCRT__
-typedef long long fpos_t;
-#else
-typedef long fpos_t;
+#else /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */
+/*
+ * The Microsoft DLLs don't provide either _fseeki64() or _ftelli64(), but
+ * they DO provide fgetpos(), fsetpos(), and _lseeki64(), which may be used
+ * to emulate the two missing functions. (Note that we choose to provide
+ * these emulations in the form of MinGW external helper functions, rather
+ * than pollute the <stdio.h> namespace with declarations, such as that
+ * for _lseeki64(), which properly belongs in <io.h>).
+ */
+#ifndef __USE_MINGW_FSEEK
+/* If this option has been selected, an alternative emulation for _fseeki64()
+ * is provided later, to ensure that the call is wrapped in a MinGW specific
+ * fseek() handling API.
+ */
+int __cdecl __MINGW_NOTHROW __mingw_fseeki64 (FILE *, __int64, int);
+__CRT_ALIAS int __cdecl __MINGW_NOTHROW _fseeki64 (FILE *__f, __int64 __o, int __w)
+{ return __mingw_fseeki64 (__f, __o, __w); }
#endif
-_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *);
-_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *);
+__int64 __cdecl __MINGW_NOTHROW __mingw_ftelli64 (FILE *);
+__CRT_ALIAS __int64 __cdecl __MINGW_NOTHROW _ftelli64 (FILE *__file )
+{ return __mingw_ftelli64 (__file); }
+
+#endif /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */
/* Error Functions
*/
_CRTIMP __cdecl __MINGW_NOTHROW void clearerr (FILE *);
_CRTIMP __cdecl __MINGW_NOTHROW void perror (const char *);
-
#ifndef __STRICT_ANSI__
/*
* Pipes
int __cdecl __MINGW_NOTHROW fseeko64 (FILE *, __off64_t, int);
#ifdef __USE_MINGW_FSEEK
+/* When this option is selected, we need to redirect calls to _fseeki64()
+ * and fseeko64() through a MinGW specific wrapper. Since the two functions
+ * are fundamentally identical, differing only in the type of the "offset"
+ * argument, (and both types are effectively 64-bit signed ints anyway),
+ * the same wrapper will suffice for both.
+ */
int __cdecl __MINGW_NOTHROW __mingw_fseeko64 (FILE *, __off64_t, int);
-#define fseeko64(fp, offset, whence) __mingw_fseeko64(fp, offset, whence)
+__CRT_ALIAS int __cdecl __MINGW_NOTHROW fseeko64 (FILE *__f, __off64_t __o, int __w)
+{ return __mingw_fseeko64 (__f, __o, __w); }
+
+__CRT_ALIAS int __cdecl __MINGW_NOTHROW _fseeki64 (FILE *__f, __off64_t __o, int __w)
+{ return __mingw_fseeko64 (__f, (__off64_t)(__o), __w); }
#endif
-__CRT_ALIAS __off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *);
-__CRT_ALIAS __LIBIMPL__(( FUNCTION = ftello64 ))
-__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE * stream)
-{ fpos_t __pos; return (fgetpos(stream, &__pos)) ? -1LL : (__off64_t)(__pos); }
+__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *);
#endif /* __MSVCRT__ && !__NO_MINGW_LFS */
#endif /* !__STRICT_ANSI__ */
--- /dev/null
+/*
+ * fseeki64.c
+ *
+ * Provides a fall-back implementation of Microsoft's _fseeki64() function,
+ * suitable for deployment when linking with legacy MSVCRT.DLL versions, from
+ * which this API is not exported.
+ *
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2018, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <io.h>
+#include <stdio.h>
+
+int __cdecl __mingw_fseeki64( FILE *stream, __int64 offset, int whence )
+{
+ /* Emulate _fseeki64() on the basis of the underlying OS data stream
+ * pointer, as manipulated by the _lseeki64() function, (which, unlike
+ * the _fseeki64() function, has been exported from all known versions
+ * of MSVCRT.DLL). Note that, unlike a previous MinGW implementation of
+ * the effectively equivalent fseeko64() function, this does not rely on
+ * any undocumented assumptions regarding the (opaque) content of fpos_t
+ * data, returned by the fgetpos() function; however, it does first use
+ * fgetpos(), followed by fsetpos(), without moving the FILE stream
+ * pointer, to ensure that the internal buffer associated with the FILE
+ * stream is marked as "clean", and thus that the FILE stream pointer
+ * is synchronized with the underlying OS data stream pointer, before
+ * calling _lseeki64() to adjust the latter; (this has the effect of
+ * keeping the two pointers synchronized, following the adjustment
+ * resulting from the _lseeki64() call).
+ */
+ fpos_t pos;
+ return ((fgetpos( stream, &pos ) == 0) && (fsetpos( stream, &pos ) == 0))
+ ? ((_lseeki64( _fileno( stream ), offset, whence ) == -1LL) ? -1 : 0)
+ : -1;
+}
+
+/* Since __int64 and __off64_t are effectively congruent 64-bit integer
+ * types, the preceding implementation is also suitable as an implementation
+ * for a variation of the POSIX.1 fseeko() function, in which the offset is
+ * specified in terms of the __off64_t data type.
+ */
+int __cdecl fseeko64
+( FILE *, __off64_t, int )__attribute__((alias("__mingw_fseeki64")));
+
+/* $RCSfile$: end of file */
+++ /dev/null
-/*
- * fseeko64.c
- *
- * Seek to 64-offset within a file stream; uses same reference bases
- * as fseek(), but offset is an implementation specific __off64_t type.
- *
- * $Id$
- *
- * Written by Kees Zeelenberg <kzlg@users.sourceforge.net>
- * and Danny Smith <dannysmith@users.sourceforge.net>
- * Copyright (C) 2004, 2005, 2015, MinGW.org Project
- *
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice, this permission notice, and the following
- * disclaimer shall be included in all copies or substantial portions of
- * the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- */
-#include <io.h>
-#include <stdio.h>
-#include <errno.h>
-
-int __cdecl
-fseeko64 (FILE* stream, __off64_t offset, int whence)
-{
- fpos_t pos;
- if (whence == SEEK_CUR)
- {
- /* If stream is invalid, fgetpos sets errno. */
- if (fgetpos (stream, &pos))
- return (-1);
- pos += (fpos_t)(offset);
- }
- else if (whence == SEEK_END)
- {
- /* If writing, we need to flush before getting file length. */
- fflush (stream);
- pos = (fpos_t)(_filelengthi64 (_fileno (stream)) + offset);
- }
- else if (whence == SEEK_SET)
- pos = (fpos_t)(offset);
- else
- {
- errno = EINVAL;
- return (-1);
- }
- return fsetpos (stream, &pos);
-}
-
-/* $RCSfile$: end of file */
--- /dev/null
+/*
+ * ftelli64.c
+ *
+ * Provides a fall-back implementation of Microsoft's _ftelli64() function,
+ * suitable for deployment when linking with legacy MSVCRT.DLL versions, from
+ * which this API is not exported.
+ *
+ *
+ * $Id$
+ *
+ * Written by Keith Marshall <keith@users.osdn.me>
+ * Copyright (C) 2018, MinGW.org Project
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ */
+#include <io.h>
+#include <stdio.h>
+
+__int64 __cdecl __mingw_ftelli64( FILE *stream )
+{
+ /* Emulate _ftelli64() on the basis of the underlying OS data stream
+ * pointer, as returned by the _telli64() function, (which, unlike the
+ * _ftelli64() function, has been exported from all known versions of
+ * MSVCRT.DLL). Note that, unlike a previous MinGW implementation of
+ * the effectively equivalent ftello64() function, this does not rely
+ * on any undocumented assumptions regarding the content of the opaque
+ * fpos_t data, returned by the fgetpos() function; however, it does
+ * still require the use of fgetpos(), followed by fsetpos(), without
+ * moving the FILE stream pointer, to ensure that the internal buffer
+ * associated with the FILE stream is marked as "clean", and thus that
+ * the FILE stream pointer is synchronized with the underlying OS data
+ * stream pointer, before reading the latter.
+ */
+ fpos_t pos;
+ return ((fgetpos( stream, &pos ) == 0) && (fsetpos( stream, &pos ) == 0))
+ ? _telli64( _fileno( stream )) : -1;
+}
+
+/* Since return types __int64 and __off64_t are effectively congruent
+ * 64-bit integer types, the preceding implementation is also suitable
+ * as an implementation for an __off64_t returning variation of the
+ * POSIX.1 ftello() function.
+ */
+__off64_t __cdecl ftello64( FILE * )__attribute__((alias("__mingw_ftelli64")));
+
+/* $RCSfile$: end of file */