On Fri, Dec 6, 2024 at 11:31 AM Thomas Munro <thomas.mu...@gmail.com> wrote:

> Some better new:
>
> 1.  _chsize_s does in fact seem to work in an msvcrt.dll build.
> Thanks to Andres for testing that for me on Windows with a standalone
> 2 line program on ucrt and msvcrt runtimes.
>
> 2.  MinGW always has _chsize_s, but it does more or less what I had
> been proposing already if it can't find the function by the Windows
> thing like dlsym, so there's no point in writing another thing like that.
> The test was with a 3G file though so it was the real function.
>
>
> https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-crt/secapi/_chsize_s.c
>
> 3.  After a long time trying various ways to make it tidy and getting
> incomprehensible results I eventually realised that precompiled
> headers were causing strange results on MinGW/Meson builds (on CI),
> due to fighting over macros with this guy:
>
>
> https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/crt/unistd.h
>
> I found it easiest to completely stop it from getting in our way
> completely, with the attached.  Thoughts, anyone?
>
> Davinder, Jakub, are you in a position repro the issue and make
> versions of the patch for the 13, 15 and master branches on top of
> that?
>

Yes, Thomas, the issue is reproducible.
After applying your patch and replacing off_t with pgoff_t, the problem has
been resolved. I have attached the patches for the 13, 15, and master.
These patches include only the changes related to pgoff_t, intended for use
with the v3-0001 patch--


Regards,
Davinder.
diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c
index ee5193bcb4..19dc681629 100644
--- a/src/bin/pg_basebackup/walmethods.c
+++ b/src/bin/pg_basebackup/walmethods.c
@@ -55,7 +55,7 @@ static DirectoryMethodData *dir_data = NULL;
 typedef struct DirectoryMethodFile
 {
 	int			fd;
-	off_t		currpos;
+	pgoff_t		currpos;
 	char	   *pathname;
 	char	   *fullpath;
 	char	   *temp_suffix;
@@ -241,7 +241,7 @@ dir_write(Walfile f, const void *buf, size_t count)
 	return r;
 }
 
-static off_t
+static pgoff_t
 dir_get_current_pos(Walfile f)
 {
 	Assert(f != NULL);
@@ -468,8 +468,8 @@ FreeWalDirectoryMethod(void)
 
 typedef struct TarMethodFile
 {
-	off_t		ofs_start;		/* Where does the *header* for this file start */
-	off_t		currpos;
+	pgoff_t		ofs_start;		/* Where does the *header* for this file start */
+	pgoff_t		currpos;
 	char		header[512];
 	char	   *pathname;
 	size_t		pad_to_size;
@@ -799,7 +799,7 @@ tar_compression(void)
 	return tar_data->compression;
 }
 
-static off_t
+static pgoff_t
 tar_get_current_pos(Walfile f)
 {
 	Assert(f != NULL);
diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h
index 2ffad2093e..955ad13ba1 100644
--- a/src/bin/pg_basebackup/walmethods.h
+++ b/src/bin/pg_basebackup/walmethods.h
@@ -68,7 +68,7 @@ struct WalWriteMethod
 	ssize_t		(*write) (Walfile f, const void *buf, size_t count);
 
 	/* Return the current position in a file or -1 on error */
-	off_t		(*get_current_pos) (Walfile f);
+	pgoff_t		(*get_current_pos) (Walfile f);
 
 	/*
 	 * fsync the contents of the specified file. Returns 0 on success.
diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h
index c9042600f9..488dd8f92d 100644
--- a/src/bin/pg_basebackup/walmethods.h
+++ b/src/bin/pg_basebackup/walmethods.h
@@ -17,7 +17,7 @@ typedef struct WalWriteMethod WalWriteMethod;
 typedef struct
 {
 	WalWriteMethod *wwmethod;
-	off_t		currpos;
+	pgoff_t		currpos;
 	char	   *pathname;
 
 	/*
diff --git a/src/include/port.h b/src/include/port.h
index ba9ab0d34f..5535811005 100644
--- a/src/include/port.h
+++ b/src/include/port.h
@@ -306,6 +306,33 @@ extern bool rmtree(const char *path, bool rmtopdir);
 
 #if defined(WIN32) && !defined(__CYGWIN__)
 
+/*
+ * We want the 64-bit version of lseek().
+ *
+ * For Visual Studio, this must be after <io.h> to avoid messing up its
+ * lseek() and _lseeki64() function declarations.
+ *
+ * For MinGW there is already a macro, so we have to undefine it (depending on
+ * _FILE_OFFSET_BITS, it may point at its own lseek64, but we don't want to
+ * count on that being set).
+ */
+#undef lseek
+#define lseek _lseeki64
+
+/*
+ * We want the 64-bit version of chsize().
+ *
+ * Prevent MinGW from declaring functions, and undefine its macro before we
+ * define our own.
+ */
+#ifndef _MSC_VER
+#define FTRUNCATE_DEFINED
+#include <unistd.h>
+#undef ftruncate
+#endif
+
+#define ftruncate(a,b) ((errno = _chsize_s((a), (b))) == 0 ? 0 : -1)
+
 /*
  * open() and fopen() replacements to allow deletion of open files and
  * passing of other special options.
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index 7789e0431a..c03747393e 100644
--- a/src/include/port/win32_port.h
+++ b/src/include/port/win32_port.h
@@ -79,8 +79,6 @@
 /* Must be here to avoid conflicting with prototype in windows.h */
 #define mkdir(a,b)	mkdir(a)
 
-#define ftruncate(a,b)	chsize(a,b)
-
 /* Windows doesn't have fsync() as such, use _commit() */
 #define fsync(fd) _commit(fd)
 
diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c
index 602727f4d4..6204ba8aba 100644
--- a/src/bin/pg_basebackup/walmethods.c
+++ b/src/bin/pg_basebackup/walmethods.c
@@ -63,7 +63,7 @@ static DirectoryMethodData *dir_data = NULL;
 typedef struct DirectoryMethodFile
 {
 	int			fd;
-	off_t		currpos;
+	pgoff_t		currpos;
 	char	   *pathname;
 	char	   *fullpath;
 	char	   *temp_suffix;
@@ -370,7 +370,7 @@ dir_write(Walfile f, const void *buf, size_t count)
 	return r;
 }
 
-static off_t
+static pgoff_t
 dir_get_current_pos(Walfile f)
 {
 	Assert(f != NULL);
@@ -666,8 +666,8 @@ FreeWalDirectoryMethod(void)
 
 typedef struct TarMethodFile
 {
-	off_t		ofs_start;		/* Where does the *header* for this file start */
-	off_t		currpos;
+	pgoff_t		ofs_start;		/* Where does the *header* for this file start */
+	pgoff_t		currpos;
 	char		header[TAR_BLOCK_SIZE];
 	char	   *pathname;
 	size_t		pad_to_size;
@@ -1005,7 +1005,7 @@ tar_compression_algorithm(void)
 	return tar_data->compression_algorithm;
 }
 
-static off_t
+static pgoff_t
 tar_get_current_pos(Walfile f)
 {
 	Assert(f != NULL);
diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h
index 76530dc941..240e3f22fc 100644
--- a/src/bin/pg_basebackup/walmethods.h
+++ b/src/bin/pg_basebackup/walmethods.h
@@ -69,7 +69,7 @@ struct WalWriteMethod
 	ssize_t		(*write) (Walfile f, const void *buf, size_t count);
 
 	/* Return the current position in a file or -1 on error */
-	off_t		(*get_current_pos) (Walfile f);
+	pgoff_t		(*get_current_pos) (Walfile f);
 
 	/*
 	 * fsync the contents of the specified file. Returns 0 on success.

Reply via email to