From 97fe111552790541eb99307048b8d2e8960905be Mon Sep 17 00:00:00 2001
From: Jakub Wartak <jakub.wartak@enterprisedb.com>
Date: Fri, 22 Nov 2024 10:45:25 +0100
Subject: [PATCH v1] Bugfix Windows pg_basebackup ability to create >2GB
 pg_wal.tar tarballs.

Previously on WIN32 pg_basebackup was reporting "could not close file: 
Invalid argument" when creating pg_wal.tar with sizes above ~2^31 bytes 
due to off_t being 32-bit on Win32. Fix via introducing pgoff_t and 
_lseeki64()

---
 src/bin/pg_basebackup/walmethods.c | 20 ++++++++++----------
 src/bin/pg_basebackup/walmethods.h |  2 +-
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c
index 602727f4d4..6b2d2e8ec8 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;
@@ -225,7 +225,7 @@ dir_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
 			}
 		}
 
-		if (lseek(fd, 0, SEEK_SET) != 0)
+		if (_lseeki64(fd, 0, SEEK_SET) != 0)
 		{
 			dir_data->lasterrno = errno;
 			close(fd);
@@ -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;
@@ -913,7 +913,7 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
 	}
 #endif
 
-	tar_data->currentfile->ofs_start = lseek(tar_data->fd, 0, SEEK_CUR);
+	tar_data->currentfile->ofs_start = _lseeki64(tar_data->fd, 0, SEEK_CUR);
 	if (tar_data->currentfile->ofs_start == -1)
 	{
 		tar_data->lasterrno = errno;
@@ -974,7 +974,7 @@ tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_
 			if (!tar_write_padding_data(tar_data->currentfile, pad_to_size))
 				return NULL;
 			/* Seek back to start */
-			if (lseek(tar_data->fd,
+			if (_lseeki64(tar_data->fd,
 					  tar_data->currentfile->ofs_start + TAR_BLOCK_SIZE,
 					  SEEK_SET) != tar_data->currentfile->ofs_start + TAR_BLOCK_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);
@@ -1146,7 +1146,7 @@ tar_close(Walfile f, WalCloseMethod method)
 		strlcpy(&(tf->header[0]), tf->pathname, 100);
 
 	print_tar_number(&(tf->header[148]), 8, tarChecksum(((TarMethodFile *) f)->header));
-	if (lseek(tar_data->fd, tf->ofs_start, SEEK_SET) != ((TarMethodFile *) f)->ofs_start)
+	if (_lseeki64(tar_data->fd, tf->ofs_start, SEEK_SET) != ((TarMethodFile *) f)->ofs_start)
 	{
 		tar_data->lasterrno = errno;
 		return -1;
@@ -1192,7 +1192,7 @@ tar_close(Walfile f, WalCloseMethod method)
 	}
 
 	/* Move file pointer back down to end, so we can write the next file */
-	if (lseek(tar_data->fd, 0, SEEK_END) < 0)
+	if (_lseeki64(tar_data->fd, 0, SEEK_END) < 0)
 	{
 		tar_data->lasterrno = errno;
 		return -1;
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.
-- 
2.39.2

