On Sat, 15 Nov 2025, Pali Rohár wrote:
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;
So there's no FILE* level caching of the file offset, which this bypasses? E.g. a ftell() after this won't give the wrong result?
If there's no such issue, then this looks fine. // Martin _______________________________________________ Mingw-w64-public mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
