From d4aec2448af0f40cc8afd75a8fd7a8a4bafe43be Mon Sep 17 00:00:00 2001
From: Thomas Munro <thomas.munro@gmail.com>
Date: Thu, 13 Feb 2020 13:56:33 +1300
Subject: [PATCH 1/4] Introduce pg_file_size() to get the file size for an fd.

We'll use this in a couple of places to replace lseek(SEEK_END)
for the same result without the side-effect of moving the file
position.  We'll use Unix fstat() or Windows GetFileSizeEx(), and
return an int64 rather than off_t since the latter is too narrow
on Windows.
---
 src/backend/storage/file/fd.c | 32 ++++++++++++++++++++++++++++++++
 src/include/storage/fd.h      |  1 +
 2 files changed, 33 insertions(+)

diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index b5f4df6a48..aea5adefc0 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -322,6 +322,38 @@ static void unlink_if_exists_fname(const char *fname, bool isdir, int elevel);
 static int	fsync_parent_path(const char *fname, int elevel);
 
 
+/*
+ * pg_file_size --- return the size of a file
+ */
+int64
+pg_file_size(int fd)
+{
+#ifdef WIN32
+	LARGE_INTEGER result;
+	HANDLE		handle;
+
+	handle = (HANDLE) _get_osfhandle(fd);
+	if (handle == INVALID_HANDLE_VALUE)
+	{
+		errno = EBADF;
+		return -1;
+	}
+
+	if (GetFileSizeEx(handle, &result))
+		return result.QuadPart;
+
+	_dosmaperr(GetLastError());
+	return -1;
+#else
+	struct stat st;
+
+	if (fstat(fd, &st) == 0)
+		return st.st_size;
+
+	return -1;
+#endif
+}
+
 /*
  * pg_fsync --- do fsync with or without writethrough
  */
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 51e2ece3c9..392347191b 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -139,6 +139,7 @@ extern void RemovePgTempFilesInDir(const char *tmpdirname, bool missing_ok,
 								   bool unlink_all);
 extern bool looks_like_temp_rel_name(const char *name);
 
+extern int64 pg_file_size(int fd);
 extern int	pg_fsync(int fd);
 extern int	pg_fsync_no_writethrough(int fd);
 extern int	pg_fsync_writethrough(int fd);
-- 
2.23.0

