• R/O
  • HTTP
  • SSH
  • HTTPS

mingw-org-wsl: Commit

The MinGW.org Windows System Libraries


Commit MetaInfo

Revision09fb4c40cbb1a2cdf51fd587e8c121289d914303 (tree)
Time2018-11-26 02:51:48
AuthorKeith Marshall <keith@user...>
CommiterKeith Marshall

Log Message

Emulate _fseeki64()/_ftelli64() API on legacy platforms.

Change Summary

Incremental Difference

--- a/mingwrt/ChangeLog
+++ b/mingwrt/ChangeLog
@@ -1,3 +1,28 @@
1+2018-11-25 Keith Marshall <keith@users.osdn.me>
2+
3+ Emulate _fseeki64()/_ftelli64() API on legacy platforms.
4+
5+ * mingwex/stdio/fseeki64.c: New file; it implements...
6+ (__mingw_fseeki64, fseeko64): ...both of these functions, avoiding any
7+ dependency on undocumented internal implementation details of...
8+ (fpos_t): ...this opaque data type, and replacing...
9+ * mingwex/stdio/fseeko64.c: ...this; delete it.
10+
11+ * mingwex/stdio/ftelli64.c: New file; it implements...
12+ (_ftelli64, ftello64): ...both of these, again avoiding any dependency
13+ on undocumented internal implementation details of...
14+ (fpos_t): ...this opaque data type.
15+
16+ * include/stdio.h (fpos_t): Make it more effectively opaque.
17+ (__mingw_fseeki64, __mingw_ftelli64): Declare them for legacy use.
18+ [_WIN32_WINNT < VISTA && __MSVCRT_VERSION__ < MSVCR80_DLL] (_fseeki64)
19+ (_ftelli64): Map inline emulations, to "__mingw" prefixed names.
20+ (ftello64): Remove inline implementation.
21+
22+ * Makefile.in (libmingwex.a): Add references to...
23+ (fseeki64.$OBJEXT, ftelli64.$OBJEXT): these; remove reference to...
24+ (fseeko64.$OBJEXT): ...this.
25+
126 2018-10-21 Keith Marshall <keith@users.osdn.me>
227
328 Update <conio.h> and <wchar.h> header files.
--- a/mingwrt/Makefile.in
+++ b/mingwrt/Makefile.in
@@ -425,9 +425,9 @@ libmingwex.a: $(addsuffix .$(OBJEXT), cosf cosl acosf acosl sinf sinl asinf \
425425 # compatibility than their Microsoft equivalents.
426426 #
427427 vpath %.c ${mingwrt_srcdir}/mingwex/stdio
428-libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeko64 ofmtctl pformat \
429- printf snprintf sprintf vfprintf vfscanf vfwscanf vprintf vscanf vsnprintf \
430- vsprintf vsscanf vswscanf vwscanf)
428+libmingwex.a: $(addsuffix .$(OBJEXT), btowc fprintf fseeki64 ftelli64 \
429+ ofmtctl pformat printf snprintf sprintf vfprintf vfscanf vfwscanf vprintf \
430+ vscanf vsnprintf vsprintf vsscanf vswscanf vwscanf)
431431
432432 # pformat.$(OBJEXT) needs an explicit build rule, since we need to
433433 # specify an additional header file path.
--- a/mingwrt/include/stdio.h
+++ b/mingwrt/include/stdio.h
@@ -7,7 +7,7 @@
77 * $Id$
88 *
99 * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
10- * Copyright (C) 1997-2005, 2007-2010, 2014-2017, MinGW.org Project.
10+ * Copyright (C) 1997-2005, 2007-2010, 2014-2018, MinGW.org Project.
1111 *
1212 *
1313 * Permission is hereby granted, free of charge, to any person obtaining a
@@ -740,6 +740,36 @@ _CRTIMP __cdecl __MINGW_NOTHROW int fseek (FILE *, long, int);
740740 _CRTIMP __cdecl __MINGW_NOTHROW long ftell (FILE *);
741741 _CRTIMP __cdecl __MINGW_NOTHROW void rewind (FILE *);
742742
743+#ifdef __USE_MINGW_FSEEK
744+/* Workaround for a limitation on Win9x where a file is not zero padded
745+ * on write, following a seek beyond the original end of file; these are
746+ * implemented in libmingwex.a
747+ */
748+__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, long, int);
749+__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *);
750+
751+#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp)
752+#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence)
753+#endif /* __USE_MINGW_FSEEK */
754+
755+/* An opaque data type used for storing file positions... The contents
756+ * of this type are unknown, but we (the compiler) need to know the size
757+ * because the programmer using fgetpos and fsetpos will be setting aside
758+ * storage for fpos_t aggregates. Actually I tested using a byte array and
759+ * it is fairly evident that fpos_t is a 32-bit type in CRTDLL.DLL, but in
760+ * MSVCRT.DLL, it is a 64-bit type. Define it in terms of an int type of
761+ * the appropriate size, encapsulated within an aggregate type, to make
762+ * it opaque to casting, and so discourage abuse.
763+ */
764+#ifdef __MSVCRT__
765+typedef union { __int64 __value; __off64_t __offset; } fpos_t;
766+#else
767+typedef union { __int32 __value; __off32_t __offset; } fpos_t;
768+#endif
769+
770+_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *);
771+_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *);
772+
743773 #if _WIN32_WINNT >= _WIN32_WINNT_VISTA || __MSVCRT_VERSION__ >= __MSVCR80_DLL
744774 /*
745775 * Microsoft introduced a number of variations on fseek() and ftell(),
@@ -761,36 +791,31 @@ _CRTIMP __cdecl __MINGW_NOTHROW int _fseeki64_nolock (FILE *, __int64, int);
761791 _CRTIMP __cdecl __MINGW_NOTHROW __int64 _ftelli64_nolock (FILE *);
762792
763793 #endif /* MSVCR80.DLL and later derivatives ONLY */
764-#endif /* MSVCR80.DLL and descendants, or MSVCRT.DLL since Vista */
765-
766-#ifdef __USE_MINGW_FSEEK
767-/* Workaround for a limitation on Win9x where a file is not zero padded
768- * on write, following a seek beyond the original end of file; these are
769- * implemented in libmingwex.a
770- */
771-__cdecl __MINGW_NOTHROW int __mingw_fseek (FILE *, long, int);
772-__cdecl __MINGW_NOTHROW size_t __mingw_fwrite (const void *, size_t, size_t, FILE *);
773-
774-#define fwrite(buffer, size, count, fp) __mingw_fwrite(buffer, size, count, fp)
775-#define fseek(fp, offset, whence) __mingw_fseek(fp, offset, whence)
776-#endif /* __USE_MINGW_FSEEK */
777794
778-/* An opaque data type used for storing file positions... The contents of
779- * this type are unknown, but we (the compiler) need to know the size
780- * because the programmer using fgetpos and fsetpos will be setting aside
781- * storage for fpos_t structres. Actually I tested using a byte array and
782- * it is fairly evident that the fpos_t type is a long (in CRTDLL.DLL).
783- * Perhaps an unsigned long? TODO? It's definitely a 64-bit number in
784- * MSVCRT however, and for now `long long' will do.
785- */
786-#ifdef __MSVCRT__
787-typedef long long fpos_t;
788-#else
789-typedef long fpos_t;
795+#else /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */
796+/*
797+ * The Microsoft DLLs don't provide either _fseeki64() or _ftelli64(), but
798+ * they DO provide fgetpos(), fsetpos(), and _lseeki64(), which may be used
799+ * to emulate the two missing functions. (Note that we choose to provide
800+ * these emulations in the form of MinGW external helper functions, rather
801+ * than pollute the <stdio.h> namespace with declarations, such as that
802+ * for _lseeki64(), which properly belongs in <io.h>).
803+ */
804+#ifndef __USE_MINGW_FSEEK
805+/* If this option has been selected, an alternative emulation for _fseeki64()
806+ * is provided later, to ensure that the call is wrapped in a MinGW specific
807+ * fseek() handling API.
808+ */
809+int __cdecl __MINGW_NOTHROW __mingw_fseeki64 (FILE *, __int64, int);
810+__CRT_ALIAS int __cdecl __MINGW_NOTHROW _fseeki64 (FILE *__f, __int64 __o, int __w)
811+{ return __mingw_fseeki64 (__f, __o, __w); }
790812 #endif
791813
792-_CRTIMP __cdecl __MINGW_NOTHROW int fgetpos (FILE *, fpos_t *);
793-_CRTIMP __cdecl __MINGW_NOTHROW int fsetpos (FILE *, const fpos_t *);
814+__int64 __cdecl __MINGW_NOTHROW __mingw_ftelli64 (FILE *);
815+__CRT_ALIAS __int64 __cdecl __MINGW_NOTHROW _ftelli64 (FILE *__file )
816+{ return __mingw_ftelli64 (__file); }
817+
818+#endif /* pre-MSVCR80.DLL or MSVCRT.DLL pre-Vista */
794819
795820 /* Error Functions
796821 */
@@ -808,7 +833,6 @@ inline __cdecl __MINGW_NOTHROW int ferror (FILE * __F){ return __F->_flag & _IO
808833 _CRTIMP __cdecl __MINGW_NOTHROW void clearerr (FILE *);
809834 _CRTIMP __cdecl __MINGW_NOTHROW void perror (const char *);
810835
811-
812836 #ifndef __STRICT_ANSI__
813837 /*
814838 * Pipes
@@ -935,14 +959,21 @@ FILE * __cdecl __MINGW_NOTHROW fopen64 (const char * filename, const char * mod
935959 int __cdecl __MINGW_NOTHROW fseeko64 (FILE *, __off64_t, int);
936960
937961 #ifdef __USE_MINGW_FSEEK
962+/* When this option is selected, we need to redirect calls to _fseeki64()
963+ * and fseeko64() through a MinGW specific wrapper. Since the two functions
964+ * are fundamentally identical, differing only in the type of the "offset"
965+ * argument, (and both types are effectively 64-bit signed ints anyway),
966+ * the same wrapper will suffice for both.
967+ */
938968 int __cdecl __MINGW_NOTHROW __mingw_fseeko64 (FILE *, __off64_t, int);
939-#define fseeko64(fp, offset, whence) __mingw_fseeko64(fp, offset, whence)
969+__CRT_ALIAS int __cdecl __MINGW_NOTHROW fseeko64 (FILE *__f, __off64_t __o, int __w)
970+{ return __mingw_fseeko64 (__f, __o, __w); }
971+
972+__CRT_ALIAS int __cdecl __MINGW_NOTHROW _fseeki64 (FILE *__f, __off64_t __o, int __w)
973+{ return __mingw_fseeko64 (__f, (__off64_t)(__o), __w); }
940974 #endif
941975
942-__CRT_ALIAS __off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *);
943-__CRT_ALIAS __LIBIMPL__(( FUNCTION = ftello64 ))
944-__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE * stream)
945-{ fpos_t __pos; return (fgetpos(stream, &__pos)) ? -1LL : (__off64_t)(__pos); }
976+__off64_t __cdecl __MINGW_NOTHROW ftello64 (FILE *);
946977
947978 #endif /* __MSVCRT__ && !__NO_MINGW_LFS */
948979 #endif /* !__STRICT_ANSI__ */
--- /dev/null
+++ b/mingwrt/mingwex/stdio/fseeki64.c
@@ -0,0 +1,69 @@
1+/*
2+ * fseeki64.c
3+ *
4+ * Provides a fall-back implementation of Microsoft's _fseeki64() function,
5+ * suitable for deployment when linking with legacy MSVCRT.DLL versions, from
6+ * which this API is not exported.
7+ *
8+ *
9+ * $Id$
10+ *
11+ * Written by Keith Marshall <keith@users.osdn.me>
12+ * Copyright (C) 2018, MinGW.org Project
13+ *
14+ *
15+ * Permission is hereby granted, free of charge, to any person obtaining a
16+ * copy of this software and associated documentation files (the "Software"),
17+ * to deal in the Software without restriction, including without limitation
18+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19+ * and/or sell copies of the Software, and to permit persons to whom the
20+ * Software is furnished to do so, subject to the following conditions:
21+ *
22+ * The above copyright notice and this permission notice (including the next
23+ * paragraph) shall be included in all copies or substantial portions of the
24+ * Software.
25+ *
26+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32+ * DEALINGS IN THE SOFTWARE.
33+ *
34+ */
35+#include <io.h>
36+#include <stdio.h>
37+
38+int __cdecl __mingw_fseeki64( FILE *stream, __int64 offset, int whence )
39+{
40+ /* Emulate _fseeki64() on the basis of the underlying OS data stream
41+ * pointer, as manipulated by the _lseeki64() function, (which, unlike
42+ * the _fseeki64() function, has been exported from all known versions
43+ * of MSVCRT.DLL). Note that, unlike a previous MinGW implementation of
44+ * the effectively equivalent fseeko64() function, this does not rely on
45+ * any undocumented assumptions regarding the (opaque) content of fpos_t
46+ * data, returned by the fgetpos() function; however, it does first use
47+ * fgetpos(), followed by fsetpos(), without moving the FILE stream
48+ * pointer, to ensure that the internal buffer associated with the FILE
49+ * stream is marked as "clean", and thus that the FILE stream pointer
50+ * is synchronized with the underlying OS data stream pointer, before
51+ * calling _lseeki64() to adjust the latter; (this has the effect of
52+ * keeping the two pointers synchronized, following the adjustment
53+ * resulting from the _lseeki64() call).
54+ */
55+ fpos_t pos;
56+ return ((fgetpos( stream, &pos ) == 0) && (fsetpos( stream, &pos ) == 0))
57+ ? ((_lseeki64( _fileno( stream ), offset, whence ) == -1LL) ? -1 : 0)
58+ : -1;
59+}
60+
61+/* Since __int64 and __off64_t are effectively congruent 64-bit integer
62+ * types, the preceding implementation is also suitable as an implementation
63+ * for a variation of the POSIX.1 fseeko() function, in which the offset is
64+ * specified in terms of the __off64_t data type.
65+ */
66+int __cdecl fseeko64
67+( FILE *, __off64_t, int )__attribute__((alias("__mingw_fseeki64")));
68+
69+/* $RCSfile$: end of file */
--- a/mingwrt/mingwex/stdio/fseeko64.c
+++ /dev/null
@@ -1,65 +0,0 @@
1-/*
2- * fseeko64.c
3- *
4- * Seek to 64-offset within a file stream; uses same reference bases
5- * as fseek(), but offset is an implementation specific __off64_t type.
6- *
7- * $Id$
8- *
9- * Written by Kees Zeelenberg <kzlg@users.sourceforge.net>
10- * and Danny Smith <dannysmith@users.sourceforge.net>
11- * Copyright (C) 2004, 2005, 2015, MinGW.org Project
12- *
13- *
14- * Permission is hereby granted, free of charge, to any person obtaining a
15- * copy of this software and associated documentation files (the "Software"),
16- * to deal in the Software without restriction, including without limitation
17- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18- * and/or sell copies of the Software, and to permit persons to whom the
19- * Software is furnished to do so, subject to the following conditions:
20- *
21- * The above copyright notice, this permission notice, and the following
22- * disclaimer shall be included in all copies or substantial portions of
23- * the Software.
24- *
25- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
31- * DEALINGS IN THE SOFTWARE.
32- *
33- */
34-#include <io.h>
35-#include <stdio.h>
36-#include <errno.h>
37-
38-int __cdecl
39-fseeko64 (FILE* stream, __off64_t offset, int whence)
40-{
41- fpos_t pos;
42- if (whence == SEEK_CUR)
43- {
44- /* If stream is invalid, fgetpos sets errno. */
45- if (fgetpos (stream, &pos))
46- return (-1);
47- pos += (fpos_t)(offset);
48- }
49- else if (whence == SEEK_END)
50- {
51- /* If writing, we need to flush before getting file length. */
52- fflush (stream);
53- pos = (fpos_t)(_filelengthi64 (_fileno (stream)) + offset);
54- }
55- else if (whence == SEEK_SET)
56- pos = (fpos_t)(offset);
57- else
58- {
59- errno = EINVAL;
60- return (-1);
61- }
62- return fsetpos (stream, &pos);
63-}
64-
65-/* $RCSfile$: end of file */
--- /dev/null
+++ b/mingwrt/mingwex/stdio/ftelli64.c
@@ -0,0 +1,65 @@
1+/*
2+ * ftelli64.c
3+ *
4+ * Provides a fall-back implementation of Microsoft's _ftelli64() function,
5+ * suitable for deployment when linking with legacy MSVCRT.DLL versions, from
6+ * which this API is not exported.
7+ *
8+ *
9+ * $Id$
10+ *
11+ * Written by Keith Marshall <keith@users.osdn.me>
12+ * Copyright (C) 2018, MinGW.org Project
13+ *
14+ *
15+ * Permission is hereby granted, free of charge, to any person obtaining a
16+ * copy of this software and associated documentation files (the "Software"),
17+ * to deal in the Software without restriction, including without limitation
18+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
19+ * and/or sell copies of the Software, and to permit persons to whom the
20+ * Software is furnished to do so, subject to the following conditions:
21+ *
22+ * The above copyright notice and this permission notice (including the next
23+ * paragraph) shall be included in all copies or substantial portions of the
24+ * Software.
25+ *
26+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
31+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32+ * DEALINGS IN THE SOFTWARE.
33+ *
34+ */
35+#include <io.h>
36+#include <stdio.h>
37+
38+__int64 __cdecl __mingw_ftelli64( FILE *stream )
39+{
40+ /* Emulate _ftelli64() on the basis of the underlying OS data stream
41+ * pointer, as returned by the _telli64() function, (which, unlike the
42+ * _ftelli64() function, has been exported from all known versions of
43+ * MSVCRT.DLL). Note that, unlike a previous MinGW implementation of
44+ * the effectively equivalent ftello64() function, this does not rely
45+ * on any undocumented assumptions regarding the content of the opaque
46+ * fpos_t data, returned by the fgetpos() function; however, it does
47+ * still require the use of fgetpos(), followed by fsetpos(), without
48+ * moving the FILE stream pointer, to ensure that the internal buffer
49+ * associated with the FILE stream is marked as "clean", and thus that
50+ * the FILE stream pointer is synchronized with the underlying OS data
51+ * stream pointer, before reading the latter.
52+ */
53+ fpos_t pos;
54+ return ((fgetpos( stream, &pos ) == 0) && (fsetpos( stream, &pos ) == 0))
55+ ? _telli64( _fileno( stream )) : -1;
56+}
57+
58+/* Since return types __int64 and __off64_t are effectively congruent
59+ * 64-bit integer types, the preceding implementation is also suitable
60+ * as an implementation for an __off64_t returning variation of the
61+ * POSIX.1 ftello() function.
62+ */
63+__off64_t __cdecl ftello64( FILE * )__attribute__((alias("__mingw_ftelli64")));
64+
65+/* $RCSfile$: end of file */
Show on old repository browser