From c7a183bc950495ddbf66aa31f3d6fe3074c5446a Mon Sep 17 00:00:00 2001 From: Juan Jose Santamaria Flecha Date: Thu, 9 Mar 2023 23:14:42 -0500 Subject: [PATCH] fix fseek detection of unseekable files for WIN32 Calling fseek() on a handle to a non-seeking device such as a pipe or a communications device is not supported, even though the fseek() may not return an error, so harden that funcion with our version. --- src/include/port/win32_port.h | 9 ++++++--- src/port/dirmod.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h index 9488195..8679a0a 100644 --- a/src/include/port/win32_port.h +++ b/src/include/port/win32_port.h @@ -206,13 +206,16 @@ int setitimer(int which, const struct itimerval *value, struct itimerval *oval /* * WIN32 does not provide 64-bit off_t, but does provide the functions operating - * with 64-bit offsets. + * with 64-bit offsets. Also, fseek() might not give an error for unseekable + * streams, so harden that funcion with our version. */ #define pgoff_t __int64 #ifdef _MSC_VER -#define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin) -#define ftello(stream) _ftelli64(stream) +extern int pgfseek64(FILE *stream, pgoff_t offset, int origin); +extern pgoff_t pgftell64(FILE *stream); +#define fseeko(stream, offset, origin) pgfseek64(stream, offset, origin) +#define ftello(stream) pgftell64(stream) #else #ifndef fseeko #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin) diff --git a/src/port/dirmod.c b/src/port/dirmod.c index bf7f068..3770efc 100644 --- a/src/port/dirmod.c +++ b/src/port/dirmod.c @@ -419,4 +419,42 @@ pgreadlink(const char *path, char *buf, size_t size) return r; } +#ifdef _MSC_VER +/* + * pgfseek64 + * + * Calling fseek() on a handle to a non-seeking device such as a pipe or + * a communications device is not supported, even though the fseek() may + * not return an error. + */ +int +pgfseek64(FILE *stream, pgoff_t offset, int origin) +{ + if (GetFileType((HANDLE) _get_osfhandle(_fileno(stream))) != FILE_TYPE_DISK) + { + errno = ESPIPE; + return -1; + } + + return _fseeki64(stream, offset, origin); +} + +/* + * pgftell64 + * + * Same as pgfseek64(). + */ +pgoff_t +pgftell64(FILE *stream) +{ + if (GetFileType((HANDLE) _get_osfhandle(_fileno(stream))) != FILE_TYPE_DISK) + { + errno = ESPIPE; + return -1; + } + + return _ftelli64(stream); +} +#endif /* defined(_MSC_VER) */ + #endif /* defined(WIN32) && !defined(__CYGWIN__) */ -- 2.11.0