Currently the fsetpos emulation supports only 32-bit offsets.
When the new position does not fit into fsetpos32 argument then call
fd-based _lseeki64() function. To ensure that FILE* stream does not have
in-use buffers, call fflush() and fsetpos32() functions which should drop
remaining write and read buffers.
With this change mingw-w64 should fully support for all CRT builds the
fsetpos function with 64-bit offset. It also proves _fseeki64 and fseeko64
emulations which call fsetpos.
---
mingw-w64-crt/stdio/fsetpos.c | 28 ++++++++++++++++++++--------
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/mingw-w64-crt/stdio/fsetpos.c b/mingw-w64-crt/stdio/fsetpos.c
index 4bb9e5cb7e47..4d56648d12d9 100644
--- a/mingw-w64-crt/stdio/fsetpos.c
+++ b/mingw-w64-crt/stdio/fsetpos.c
@@ -7,21 +7,33 @@
#include <stdio.h>
#include <errno.h>
#include <limits.h>
+#include <io.h>
-/* Define 64-bit fsetpos() function via 32-bit fsetpos32() function */
+/* Define 64-bit fsetpos() function via 32-bit fsetpos32() and 64-bit
_lseeki64() functions */
_CRTIMP int __cdecl fsetpos32(FILE *__restrict__ _File, long *__restrict__
_Pos);
int __cdecl fsetpos(FILE *__restrict__ _File, const fpos_t *__restrict__ _Pos)
{
- long pos32;
-
- if (*_Pos < LONG_MIN || *_Pos > LONG_MAX)
+ if (*_Pos < LONG_MIN)
{
- errno = EOVERFLOW;
+ errno = EINVAL;
return -1;
}
-
- pos32 = *_Pos;
- return fsetpos32(_File, &pos32);
+ else if (*_Pos > LONG_MAX)
+ {
+ /* fflush() and fsetpos32() clear read and write buffers, so the followup
+ * _lseeki64() call correctly change offset of the FILE* stream too. */
+ if (fflush(_File) != 0)
+ return -1;
+ if (fsetpos32(_File, &(long){LONG_MAX}) != 0)
+ return -1;
+ if (_lseeki64(fileno(_File), *_Pos, SEEK_SET) == -1)
+ return -1;
+ return 0;
+ }
+ else
+ {
+ return fsetpos32(_File, &(long){*_Pos});
+ }
}
int (__cdecl *__MINGW_IMP_SYMBOL(fsetpos))(FILE *__restrict__ _File, const
fpos_t *__restrict__ _Pos) = fsetpos;
--
2.20.1
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public