From bbe406e14f75eb198f7cb581513bfd3c4a02481a Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Sat, 3 Nov 2018 23:11:29 +1300 Subject: [PATCH 2/3] Supply pread()/pwrite() implementations for Windows. Emulate POSIX pread()/pwrite() with the OVERLAPPED interface. The emulation is not perfect, as the file position is changed, but that is OK for our purposes. We don't plan to mix read() and pread() calls on the same fd. Author: Thomas Munro Reviewed-by: Discussion: --- src/backend/port/win32/Makefile | 2 +- src/backend/port/win32/pread.c | 69 +++++++++++++++++++++++++++++++++ src/include/pg_config.h.win32 | 6 +++ src/include/port/win32_port.h | 4 ++ 4 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/backend/port/win32/pread.c diff --git a/src/backend/port/win32/Makefile b/src/backend/port/win32/Makefile index a6ace93e261..9539bd22673 100644 --- a/src/backend/port/win32/Makefile +++ b/src/backend/port/win32/Makefile @@ -12,7 +12,7 @@ subdir = src/backend/port/win32 top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = timer.o socket.o signal.o mingwcompat.o +OBJS = pread.o timer.o socket.o signal.o mingwcompat.o ifeq ($(have_win32_dbghelp), yes) OBJS += crashdump.o endif diff --git a/src/backend/port/win32/pread.c b/src/backend/port/win32/pread.c new file mode 100644 index 00000000000..7984a1f5a4c --- /dev/null +++ b/src/backend/port/win32/pread.c @@ -0,0 +1,69 @@ +/*------------------------------------------------------------------------- + * + * pread.c + * Microsoft Windows Win32 pread() and pwrite() implementations. + * + * Portions Copyright (c) 1996-2018, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/backend/port/win32/pread.c + * + * Note that these implementations change the current file position, unlike + * the POSIX functions, so should not be mixed with regular read() and + * write() calls. + * + *------------------------------------------------------------------------- + */ + +#ifdef WIN32 + +#include "postgres.h" +#include + +ssize_t +pread(int fd, void *buf, size_t size, off_t offset) +{ + OVERLAPPED overlapped = {0}; + HANDLE handle; + DWORD result; + + handle = (HANDLE) _get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + overlapped.Offset = (uint32) offset; + if (!ReadFile(handle, buf, size, &result, &overlapped)) + { + _dosmaperr(GetLastError()); + return -1; + } + return result; +} + +ssize_t +pwrite(int fd, void *buf, size_t size, off_t offset) +{ + OVERLAPPED overlapped = {0}; + HANDLE handle; + DWORD result; + + handle = (HANDLE) _get_osfhandle(fd); + if (handle == INVALID_HANDLE_VALUE) + { + errno = EBADF; + return -1; + } + + overlapped.Offset = (uint32) offset; + if (!WriteFile(handle, buf, size, &result, &overlapped)) + { + _dosmaperr(GetLastError()); + return -1; + } + return result; +} + +#endif diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index f7a051d1127..2172102aa7c 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -322,12 +322,18 @@ /* Define to 1 if you have the `ppoll' function. */ /* #undef HAVE_PPOLL */ +/* Define to 1 if you have the `pread' function. */ +#define HAVE_PREAD 1 + /* Define to 1 if you have the `pstat' function. */ /* #undef HAVE_PSTAT */ /* Define to 1 if the PS_STRINGS thing exists. */ /* #undef HAVE_PS_STRINGS */ +/* Define to 1 if you have the `pwrite' function. */ +#define HAVE_PWRITE 1 + /* Define to 1 if you have the `random' function. */ /* #undef HAVE_RANDOM */ diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h index 360dbdf3a75..dd76cb16811 100644 --- a/src/include/port/win32_port.h +++ b/src/include/port/win32_port.h @@ -512,6 +512,10 @@ typedef unsigned short mode_t; #define isnan(x) _isnan(x) #endif +/* in backend/port/win32/pread.c */ +extern ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset); +extern ssize_t pwrite(int fd, void *buf, size_t nbyte, off_t offset); + /* Pulled from Makefile.port in MinGW */ #define DLSUFFIX ".dll" -- 2.19.1