From d4aec2448af0f40cc8afd75a8fd7a8a4bafe43be Mon Sep 17 00:00:00 2001 From: Thomas Munro 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