public inbox for [email protected]  
help / color / mirror / Atom feed
From: Juan José Santamaría Flecha <[email protected]>
To: Michael Paquier <[email protected]>
Cc: Pg Hackers <[email protected]>
Subject: Re: Fix fseek() detection of unseekable files on WIN32
Date: Wed, 15 Mar 2023 12:18:25 +0100
Message-ID: <CAC+AXB3BgqAQ4Fmj2h2DhUXyNL1TqH6mi_+nGh+aGun-grF-kQ@mail.gmail.com> (raw)
In-Reply-To: <[email protected]>
References: <CAC+AXB26a4EmxM2suXxPpJaGrqAdxracd7hskLg-zxtPB50h7A@mail.gmail.com>
	<[email protected]>

On Wed, Mar 15, 2023 at 5:57 AM Michael Paquier <[email protected]> wrote:

> On Tue, Mar 14, 2023 at 01:26:27PM +0100, Juan José Santamaría Flecha
> wrote:
> > As highlighted in [1] fseek() might fail to error even when accessing
> > unseekable streams.
> >
> > PFA a patch that checks the file type before the actual fseek(), so only
> > supported calls are made.
>
> + * streams, so harden that funcion with our version.
> s/funcion/function/.
>

Done.

+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)
>
> What about naming the internal wrappers _pgfseeko64() and
> _pgftello64(), located in a new file named win32fseek.c?  It may be
> possible that we would need a similar treatment for fseek(), in the
> future, though I don't see an issue why this would be needed now.
>

Done.


> +   if (GetFileType((HANDLE) _get_osfhandle(_fileno(stream))) !=
> FILE_TYPE_DISK)
> +   {
> +       errno = ESPIPE;
> +       return -1;
> +   }
> Shouldn't there be cases where we should return EINVAL for some of the
> other types, like FILE_TYPE_REMOTE or FILE_TYPE_UNKNOWN?  We should
> return ESPIPE only for FILE_TYPE_PIPE and FILE_TYPE_CHAR, then?
>

Done.

PFA a new version of the patch.

Regards,

Juan José Santamaría Flecha


Attachments:

  [application/octet-stream] v2-0001-fix-fseek-detection-of-unseekable-files-for-WIN32.patch (4.0K, ../CAC+AXB3BgqAQ4Fmj2h2DhUXyNL1TqH6mi_+nGh+aGun-grF-kQ@mail.gmail.com/3-v2-0001-fix-fseek-detection-of-unseekable-files-for-WIN32.patch)
  download | inline diff:
From 45ea3338e10c6b296ddc1cedb80ce8e5f103e51d Mon Sep 17 00:00:00 2001
From: Juan Jose Santamaria Flecha <[email protected]>
Date: Wed, 15 Mar 2023 07:04:44 -0400
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/meson.build          |  1 +
 src/port/win32fseek.c         | 68 +++++++++++++++++++++++++++++++++++++++++++
 src/tools/msvc/Mkvcbuild.pm   |  1 +
 4 files changed, 76 insertions(+), 3 deletions(-)
 create mode 100644 src/port/win32fseek.c

diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 9488195..66553fe 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 function 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  	_pgfseeko64(FILE *stream, pgoff_t offset, int origin);
+extern pgoff_t	_pgftello64(FILE *stream);
+#define fseeko(stream, offset, origin) _pgfseeko64(stream, offset, origin)
+#define ftello(stream) _pgftello64(stream)
 #else
 #ifndef fseeko
 #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin)
diff --git a/src/port/meson.build b/src/port/meson.build
index b174b25..3d8eeb4 100644
--- a/src/port/meson.build
+++ b/src/port/meson.build
@@ -33,6 +33,7 @@ if host_system == 'windows'
     'win32env.c',
     'win32error.c',
     'win32fdatasync.c',
+    'win32fseek.c',
     'win32getrusage.c',
     'win32link.c',
     'win32ntdll.c',
diff --git a/src/port/win32fseek.c b/src/port/win32fseek.c
new file mode 100644
index 0000000..6cf62db
--- /dev/null
+++ b/src/port/win32fseek.c
@@ -0,0 +1,68 @@
+/*-------------------------------------------------------------------------
+ *
+ * win32fseek.c
+ *	  Replacements for fseeko() and ftello().
+ *
+ * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  src/port/win32fseek.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifdef FRONTEND
+#include "postgres_fe.h"
+#else
+#include "postgres.h"
+#endif
+
+#if defined(WIN32) && defined(_MSC_VER)
+
+/*
+ * _pgfseeko64
+ *
+ * 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
+_pgfseeko64(FILE *stream, pgoff_t offset, int origin)
+{
+	DWORD			fileType;
+
+	fileType = GetFileType((HANDLE) _get_osfhandle(_fileno(stream)));
+
+	if (fileType == FILE_TYPE_DISK)
+		return _fseeki64(stream, offset, origin);
+	else if (fileType == FILE_TYPE_CHAR || fileType == FILE_TYPE_PIPE)
+		errno = ESPIPE;
+	else
+		errno = EINVAL;
+
+	return -1;
+}
+
+/*
+ * _pgftello64
+ *
+ * Same as _pgfseeko64().
+ */
+pgoff_t
+_pgftello64(FILE *stream)
+{
+	DWORD			fileType;
+
+	fileType = GetFileType((HANDLE) _get_osfhandle(_fileno(stream)));
+
+	if (fileType == FILE_TYPE_DISK)
+		return _ftelli64(stream);
+	else if (fileType == FILE_TYPE_CHAR || fileType == FILE_TYPE_PIPE)
+		errno = ESPIPE;
+	else
+		errno = EINVAL;
+
+	return -1;
+}
+
+#endif							/* defined(WIN32) && defined(_MSC_VER) */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index f1c9ddf..61ace57 100644
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -111,6 +111,7 @@ sub mkvcbuild
 	  win32dlopen.c
 	  win32env.c win32error.c
 	  win32fdatasync.c
+	  win32fseek.c
 	  win32getrusage.c
 	  win32gettimeofday.c
 	  win32link.c
-- 
2.11.0



view thread (3+ messages)

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected], [email protected]
  Subject: Re: Fix fseek() detection of unseekable files on WIN32
  In-Reply-To: <CAC+AXB3BgqAQ4Fmj2h2DhUXyNL1TqH6mi_+nGh+aGun-grF-kQ@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox