Robert Haas <robertmh...@gmail.com> writes:
> On Wed, Nov 15, 2017 at 5:22 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
>> Thoughts?

> Sure, having a win32_port.h as a sub-include of port.h seems fine.

Here's a draft patch for this.  I'm not too certain about the interactions
with Cygwin; some of the stuff I moved out of port.h might have to go back
there so that a Cygwin build will see it.  There might also be some
declaration ordering dependencies that I failed to spot.

(Speaking of which, I'm wondering why the existing code monkeys around
with _WIN32_WINNT after it's already included a bunch of system headers.
Shouldn't that be set earlier --- in other words, shouldn't that code
move back to win32.h from win32_port.h?  But I've not touched that here.
I did remove an at-best-redundant definition from pg_ctl.c though.)

Anybody want to test this manually, or shall we just throw it into the
buildfarm and see what blows up?

                        regards, tom lane

diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 82de7df..e43e7b2 100644
*** a/src/bin/pg_ctl/pg_ctl.c
--- b/src/bin/pg_ctl/pg_ctl.c
***************
*** 9,22 ****
   *-------------------------------------------------------------------------
   */
  
- #ifdef WIN32
- /*
-  * Need this to get defines for restricted tokens and jobs. And it
-  * has to be set before any header from the Win32 API is loaded.
-  */
- #define _WIN32_WINNT 0x0501
- #endif
- 
  #include "postgres_fe.h"
  
  #include <fcntl.h>
--- 9,14 ----
diff --git a/src/include/c.h b/src/include/c.h
index c8c7be1..a614288 100644
*** a/src/include/c.h
--- b/src/include/c.h
***************
*** 52,83 ****
  
  #include "pg_config.h"
  #include "pg_config_manual.h"	/* must be after pg_config.h */
- 
- /*
-  * We always rely on the WIN32 macro being set by our build system,
-  * but _WIN32 is the compiler pre-defined macro. So make sure we define
-  * WIN32 whenever _WIN32 is set, to facilitate standalone building.
-  */
- #if defined(_WIN32) && !defined(WIN32)
- #define WIN32
- #endif
- 
- #if !defined(WIN32) && !defined(__CYGWIN__) /* win32 includes further down */
  #include "pg_config_os.h"		/* must be before any system header files */
- #endif
- 
- #if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H)
- #define errcode __msvc_errcode
- #include <crtdefs.h>
- #undef errcode
- #endif
- 
- /*
-  * We have to include stdlib.h here because it defines many of these macros
-  * on some platforms, and we only want our definitions used if stdlib.h doesn't
-  * have its own.  The same goes for stddef and stdarg if present.
-  */
  
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
--- 52,60 ----
  
  #include "pg_config.h"
  #include "pg_config_manual.h"	/* must be after pg_config.h */
  #include "pg_config_os.h"		/* must be before any system header files */
  
+ /* System header files that should be available everywhere in Postgres */
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
***************
*** 99,109 ****
  #include <libintl.h>
  #endif
  
- #if defined(WIN32) || defined(__CYGWIN__)
- /* We have to redefine some system functions after they are included above. */
- #include "pg_config_os.h"
- #endif
- 
  
  /* ----------------------------------------------------------------
   *				Section 1: compiler characteristics
--- 76,81 ----
diff --git a/src/include/port.h b/src/include/port.h
index 17a7710..3cf400c 100644
*** a/src/include/port.h
--- b/src/include/port.h
***************
*** 17,22 ****
--- 17,31 ----
  #include <netdb.h>
  #include <pwd.h>
  
+ /*
+  * Windows has enough specialized port stuff that we push most of it off
+  * into another file.
+  * Note: Some CYGWIN includes might #define WIN32.
+  */
+ #if defined(WIN32) && !defined(__CYGWIN__)
+ #include "port/win32_port.h"
+ #endif
+ 
  /* socket has a different definition on WIN32 */
  #ifndef WIN32
  typedef int pgsocket;
*************** extern int find_other_exec(const char *a
*** 101,111 ****
  /* Doesn't belong here, but this is used with find_other_exec(), so... */
  #define PG_BACKEND_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
  
- /* Windows security token manipulation (in exec.c) */
- #ifdef WIN32
- extern BOOL AddUserToTokenDacl(HANDLE hToken);
- #endif
- 
  
  #if defined(WIN32) || defined(__CYGWIN__)
  #define EXE ".exe"
--- 110,115 ----
*************** extern int	pg_printf(const char *fmt,...
*** 185,220 ****
  #endif
  #endif							/* USE_REPL_SNPRINTF */
  
- #if defined(WIN32)
- /*
-  * Versions of libintl >= 0.18? try to replace setlocale() with a macro
-  * to their own versions.  Remove the macro, if it exists, because it
-  * ends up calling the wrong version when the backend and libintl use
-  * different versions of msvcrt.
-  */
- #if defined(setlocale)
- #undef setlocale
- #endif
- 
- /*
-  * Define our own wrapper macro around setlocale() to work around bugs in
-  * Windows' native setlocale() function.
-  */
- extern char *pgwin32_setlocale(int category, const char *locale);
- 
- #define setlocale(a,b) pgwin32_setlocale(a,b)
- #endif							/* WIN32 */
- 
  /* Portable prompt handling */
  extern void simple_prompt(const char *prompt, char *destination, size_t destlen,
  			  bool echo);
  
- #ifdef WIN32
- #define PG_SIGNAL_COUNT 32
- #define kill(pid,sig)	pgkill(pid,sig)
- extern int	pgkill(int pid, int sig);
- #endif
- 
  extern int	pclose_check(FILE *stream);
  
  /* Global variable holding time zone information. */
--- 189,198 ----
*************** extern int	gettimeofday(struct timeval *
*** 353,359 ****
  extern char *crypt(const char *key, const char *setting);
  #endif
  
! /* WIN32 handled in port/win32.h */
  #ifndef WIN32
  #define pgoff_t off_t
  #ifdef __NetBSD__
--- 331,337 ----
  extern char *crypt(const char *key, const char *setting);
  #endif
  
! /* WIN32 handled in port/win32_port.h */
  #ifndef WIN32
  #define pgoff_t off_t
  #ifdef __NetBSD__
diff --git a/src/include/port/win32.h b/src/include/port/win32.h
index 23f8974..cf9cf30 100644
*** a/src/include/port/win32.h
--- b/src/include/port/win32.h
***************
*** 1,88 ****
  /* src/include/port/win32.h */
  
  /*
!  * Make sure _WIN32_WINNT has the minimum required value.
!  * Leave a higher value in place. When building with at least Visual
!  * Studio 2015 the minimum requirement is Windows Vista (0x0600) to
!  * get support for GetLocaleInfoEx() with locales. For everything else
!  * the minimum version is Windows XP (0x0501).
!  * Also for VS2015, add a define that stops compiler complaints about
!  * using the old Winsock API.
   */
! #if defined(_MSC_VER) && _MSC_VER >= 1900
! #define  _WINSOCK_DEPRECATED_NO_WARNINGS
! #define MIN_WINNT 0x0600
! #else
! #define MIN_WINNT 0x0501
! #endif
! 
! #if defined(_WIN32_WINNT) && _WIN32_WINNT < MIN_WINNT
! #undef _WIN32_WINNT
! #endif
! 
! #ifndef _WIN32_WINNT
! #define _WIN32_WINNT MIN_WINNT
  #endif
  
  /*
!  * Always build with SSPI support. Keep it as a #define in case
!  * we want a switch to disable it sometime in the future.
!  */
! #define ENABLE_SSPI 1
! 
! /* undefine and redefine after #include */
! #undef mkdir
! 
! #undef ERROR
! 
! /*
!  * The Mingw64 headers choke if this is already defined - they
!  * define it themselves.
   */
! #if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER)
! #define _WINSOCKAPI_
  #endif
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <windows.h>
- #undef small
- #include <process.h>
- #include <signal.h>
- #include <errno.h>
- #include <direct.h>
- #include <sys/utime.h>			/* for non-unicode version */
- #undef near
- 
- /* 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)
  
  /*
!  * For historical reasons, we allow setting wal_sync_method to
!  * fsync_writethrough on Windows, even though it's really identical to fsync
!  * (both code paths wind up at _commit()).
!  */
! #define HAVE_FSYNC_WRITETHROUGH
! #define FSYNC_WRITETHROUGH_IS_FSYNC
! 
! #define USES_WINSOCK
! 
! /* defines for dynamic linking on Win32 platform
!  *
   *	http://support.microsoft.com/kb/132044
   *	http://msdn.microsoft.com/en-us/library/8fskxacy(v=vs.80).aspx
   *	http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx
   */
  
- #if defined(WIN32) || defined(__CYGWIN__)
- 
  #ifdef BUILDING_DLL
  #define PGDLLIMPORT __declspec (dllexport)
! #else							/* not BUILDING_DLL */
  #define PGDLLIMPORT __declspec (dllimport)
  #endif
  
--- 1,35 ----
  /* src/include/port/win32.h */
  
  /*
!  * We always rely on the WIN32 macro being set by our build system,
!  * but _WIN32 is the compiler pre-defined macro. So make sure we define
!  * WIN32 whenever _WIN32 is set, to facilitate standalone building.
   */
! #if defined(_WIN32) && !defined(WIN32)
! #define WIN32
  #endif
  
  /*
!  * We need to prevent <crtdefs.h> from defining a symbol conflicting with
!  * our errcode() function.  Since it's likely to get included by standard
!  * system headers, pre-emptively include it now.
   */
! #if _MSC_VER >= 1400 || defined(HAVE_CRTDEFS_H)
! #define errcode __msvc_errcode
! #include <crtdefs.h>
! #undef errcode
  #endif
  
  /*
!  * defines for dynamic linking on Win32 platform
   *	http://support.microsoft.com/kb/132044
   *	http://msdn.microsoft.com/en-us/library/8fskxacy(v=vs.80).aspx
   *	http://msdn.microsoft.com/en-us/library/a90k134d(v=vs.80).aspx
   */
  
  #ifdef BUILDING_DLL
  #define PGDLLIMPORT __declspec (dllexport)
! #else
  #define PGDLLIMPORT __declspec (dllimport)
  #endif
  
***************
*** 91,455 ****
  #else
  #define PGDLLEXPORT
  #endif
- #else							/* not CYGWIN, not MSVC, not MingW */
- #define PGDLLIMPORT
- #define PGDLLEXPORT
- #endif
- 
- 
- /*
-  *	IPC defines
-  */
- #undef HAVE_UNION_SEMUN
- #define HAVE_UNION_SEMUN 1
- 
- #define IPC_RMID 256
- #define IPC_CREAT 512
- #define IPC_EXCL 1024
- #define IPC_PRIVATE 234564
- #define IPC_NOWAIT	2048
- #define IPC_STAT 4096
- 
- #define EACCESS 2048
- #ifndef EIDRM
- #define EIDRM 4096
- #endif
- 
- #define SETALL 8192
- #define GETNCNT 16384
- #define GETVAL 65536
- #define SETVAL 131072
- #define GETPID 262144
- 
- 
- /*
-  *	Signal stuff
-  *
-  *	For WIN32, there is no wait() call so there are no wait() macros
-  *	to interpret the return value of system().  Instead, system()
-  *	return values < 0x100 are used for exit() termination, and higher
-  *	values are used to indicated non-exit() termination, which is
-  *	similar to a unix-style signal exit (think SIGSEGV ==
-  *	STATUS_ACCESS_VIOLATION).  Return values are broken up into groups:
-  *
-  *	http://msdn2.microsoft.com/en-gb/library/aa489609.aspx
-  *
-  *		NT_SUCCESS			0 - 0x3FFFFFFF
-  *		NT_INFORMATION		0x40000000 - 0x7FFFFFFF
-  *		NT_WARNING			0x80000000 - 0xBFFFFFFF
-  *		NT_ERROR			0xC0000000 - 0xFFFFFFFF
-  *
-  *	Effectively, we don't care on the severity of the return value from
-  *	system(), we just need to know if it was because of exit() or generated
-  *	by the system, and it seems values >= 0x100 are system-generated.
-  *	See this URL for a list of WIN32 STATUS_* values:
-  *
-  *		Wine (URL used in our error messages) -
-  *			http://source.winehq.org/source/include/ntstatus.h
-  *		Descriptions - http://www.comp.nus.edu.sg/~wuyongzh/my_doc/ntstatus.txt
-  *		MS SDK - http://www.nologs.com/ntstatus.html
-  *
-  *	It seems the exception lists are in both ntstatus.h and winnt.h, but
-  *	ntstatus.h has a more comprehensive list, and it only contains
-  *	exception values, rather than winnt, which contains lots of other
-  *	things:
-  *
-  *		http://www.microsoft.com/msj/0197/exception/exception.aspx
-  *
-  *		The ExceptionCode parameter is the number that the operating system
-  *		assigned to the exception. You can see a list of various exception codes
-  *		in WINNT.H by searching for #defines that start with "STATUS_". For
-  *		example, the code for the all-too-familiar STATUS_ACCESS_VIOLATION is
-  *		0xC0000005. A more complete set of exception codes can be found in
-  *		NTSTATUS.H from the Windows NT DDK.
-  *
-  *	Some day we might want to print descriptions for the most common
-  *	exceptions, rather than printing an include file name.  We could use
-  *	RtlNtStatusToDosError() and pass to FormatMessage(), which can print
-  *	the text of error values, but MinGW does not support
-  *	RtlNtStatusToDosError().
-  */
- #define WIFEXITED(w)	(((w) & 0XFFFFFF00) == 0)
- #define WIFSIGNALED(w)	(!WIFEXITED(w))
- #define WEXITSTATUS(w)	(w)
- #define WTERMSIG(w)		(w)
- 
- #define sigmask(sig) ( 1 << ((sig)-1) )
- 
- /* Signal function return values */
- #undef SIG_DFL
- #undef SIG_ERR
- #undef SIG_IGN
- #define SIG_DFL ((pqsigfunc)0)
- #define SIG_ERR ((pqsigfunc)-1)
- #define SIG_IGN ((pqsigfunc)1)
- 
- /* Some extra signals */
- #define SIGHUP				1
- #define SIGQUIT				3
- #define SIGTRAP				5
- #define SIGABRT				22	/* Set to match W32 value -- not UNIX value */
- #define SIGKILL				9
- #define SIGPIPE				13
- #define SIGALRM				14
- #define SIGSTOP				17
- #define SIGTSTP				18
- #define SIGCONT				19
- #define SIGCHLD				20
- #define SIGTTIN				21
- #define SIGTTOU				22	/* Same as SIGABRT -- no problem, I hope */
- #define SIGWINCH			28
- #define SIGUSR1				30
- #define SIGUSR2				31
- 
- /*
-  * New versions of mingw have gettimeofday() and also declare
-  * struct timezone to support it.
-  */
- #ifndef HAVE_GETTIMEOFDAY
- struct timezone
- {
- 	int			tz_minuteswest; /* Minutes west of GMT.  */
- 	int			tz_dsttime;		/* Nonzero if DST is ever in effect.  */
- };
- #endif
- 
- /* for setitimer in backend/port/win32/timer.c */
- #define ITIMER_REAL 0
- struct itimerval
- {
- 	struct timeval it_interval;
- 	struct timeval it_value;
- };
- 
- int			setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
- 
- /*
-  * WIN32 does not provide 64-bit off_t, but does provide the functions operating
-  * with 64-bit offsets.
-  */
- #define pgoff_t __int64
- #ifdef _MSC_VER
- #define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin)
- #define ftello(stream) _ftelli64(stream)
- #else
- #ifndef fseeko
- #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin)
- #endif
- #ifndef ftello
- #define ftello(stream) ftello64(stream)
- #endif
- #endif
- 
- /*
-  * Supplement to <sys/types.h>.
-  *
-  * Perl already has typedefs for uid_t and gid_t.
-  */
- #ifndef PLPERL_HAVE_UID_GID
- typedef int uid_t;
- typedef int gid_t;
- #endif
- typedef long key_t;
- 
- #ifdef _MSC_VER
- typedef int pid_t;
- #endif
- 
- /*
-  * Supplement to <sys/stat.h>.
-  */
- #define lstat(path, sb) stat((path), (sb))
- 
- /*
-  * Supplement to <fcntl.h>.
-  * This is the same value as _O_NOINHERIT in the MS header file. This is
-  * to ensure that we don't collide with a future definition. It means
-  * we cannot use _O_NOINHERIT ourselves.
-  */
- #define O_DSYNC 0x0080
- 
- /*
-  * Supplement to <errno.h>.
-  *
-  * We redefine network-related Berkeley error symbols as the corresponding WSA
-  * constants.  This allows elog.c to recognize them as being in the Winsock
-  * error code range and pass them off to pgwin32_socket_strerror(), since
-  * Windows' version of plain strerror() won't cope.  Note that this will break
-  * if these names are used for anything else besides Windows Sockets errors.
-  * See TranslateSocketError() when changing this list.
-  */
- #undef EAGAIN
- #define EAGAIN WSAEWOULDBLOCK
- #undef EINTR
- #define EINTR WSAEINTR
- #undef EMSGSIZE
- #define EMSGSIZE WSAEMSGSIZE
- #undef EAFNOSUPPORT
- #define EAFNOSUPPORT WSAEAFNOSUPPORT
- #undef EWOULDBLOCK
- #define EWOULDBLOCK WSAEWOULDBLOCK
- #undef ECONNABORTED
- #define ECONNABORTED WSAECONNABORTED
- #undef ECONNRESET
- #define ECONNRESET WSAECONNRESET
- #undef EINPROGRESS
- #define EINPROGRESS WSAEINPROGRESS
- #undef EISCONN
- #define EISCONN WSAEISCONN
- #undef ENOBUFS
- #define ENOBUFS WSAENOBUFS
- #undef EPROTONOSUPPORT
- #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
- #undef ECONNREFUSED
- #define ECONNREFUSED WSAECONNREFUSED
- #undef ENOTSOCK
- #define ENOTSOCK WSAENOTSOCK
- #undef EOPNOTSUPP
- #define EOPNOTSUPP WSAEOPNOTSUPP
- #undef EADDRINUSE
- #define EADDRINUSE WSAEADDRINUSE
- #undef EADDRNOTAVAIL
- #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
- #undef EHOSTUNREACH
- #define EHOSTUNREACH WSAEHOSTUNREACH
- #undef ENOTCONN
- #define ENOTCONN WSAENOTCONN
- 
- /*
-  * Extended locale functions with gratuitous underscore prefixes.
-  * (These APIs are nevertheless fully documented by Microsoft.)
-  */
- #define locale_t _locale_t
- #define tolower_l _tolower_l
- #define toupper_l _toupper_l
- #define towlower_l _towlower_l
- #define towupper_l _towupper_l
- #define isdigit_l _isdigit_l
- #define iswdigit_l _iswdigit_l
- #define isalpha_l _isalpha_l
- #define iswalpha_l _iswalpha_l
- #define isalnum_l _isalnum_l
- #define iswalnum_l _iswalnum_l
- #define isupper_l _isupper_l
- #define iswupper_l _iswupper_l
- #define islower_l _islower_l
- #define iswlower_l _iswlower_l
- #define isgraph_l _isgraph_l
- #define iswgraph_l _iswgraph_l
- #define isprint_l _isprint_l
- #define iswprint_l _iswprint_l
- #define ispunct_l _ispunct_l
- #define iswpunct_l _iswpunct_l
- #define isspace_l _isspace_l
- #define iswspace_l _iswspace_l
- #define strcoll_l _strcoll_l
- #define strxfrm_l _strxfrm_l
- #define wcscoll_l _wcscoll_l
- #define wcstombs_l _wcstombs_l
- #define mbstowcs_l _mbstowcs_l
- 
- 
- /* In backend/port/win32/signal.c */
- extern PGDLLIMPORT volatile int pg_signal_queue;
- extern PGDLLIMPORT int pg_signal_mask;
- extern HANDLE pgwin32_signal_event;
- extern HANDLE pgwin32_initial_signal_pipe;
- 
- #define UNBLOCKED_SIGNAL_QUEUE()	(pg_signal_queue & ~pg_signal_mask)
- 
- 
- void		pgwin32_signal_initialize(void);
- HANDLE		pgwin32_create_signal_listener(pid_t pid);
- void		pgwin32_dispatch_queued_signals(void);
- void		pg_queue_signal(int signum);
- 
- /* In backend/port/win32/socket.c */
- #ifndef FRONTEND
- #define socket(af, type, protocol) pgwin32_socket(af, type, protocol)
- #define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen)
- #define listen(s, backlog) pgwin32_listen(s, backlog)
- #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen)
- #define connect(s, name, namelen) pgwin32_connect(s, name, namelen)
- #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
- #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags)
- #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags)
- 
- SOCKET		pgwin32_socket(int af, int type, int protocol);
- int			pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen);
- int			pgwin32_listen(SOCKET s, int backlog);
- SOCKET		pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
- int			pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen);
- int			pgwin32_select(int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
- int			pgwin32_recv(SOCKET s, char *buf, int len, int flags);
- int			pgwin32_send(SOCKET s, const void *buf, int len, int flags);
- 
- const char *pgwin32_socket_strerror(int err);
- int			pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
- 
- extern int	pgwin32_noblock;
- 
- #endif
- 
- /* in backend/port/win32_shmem.c */
- extern int	pgwin32_ReserveSharedMemoryRegion(HANDLE);
- 
- /* in backend/port/win32/crashdump.c */
- extern void pgwin32_install_crashdump_handler(void);
- 
- /* in port/win32error.c */
- extern void _dosmaperr(unsigned long);
- 
- /* in port/win32env.c */
- extern int	pgwin32_putenv(const char *);
- extern void pgwin32_unsetenv(const char *);
- 
- /* in port/win32security.c */
- extern int	pgwin32_is_service(void);
- extern int	pgwin32_is_admin(void);
- 
- #define putenv(x) pgwin32_putenv(x)
- #define unsetenv(x) pgwin32_unsetenv(x)
- 
- /* Things that exist in MingW headers, but need to be added to MSVC */
- #ifdef _MSC_VER
- 
- #ifndef _WIN64
- typedef long ssize_t;
- #else
- typedef __int64 ssize_t;
- #endif
- 
- typedef unsigned short mode_t;
- 
- #define S_IRUSR _S_IREAD
- #define S_IWUSR _S_IWRITE
- #define S_IXUSR _S_IEXEC
- #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
- /* see also S_IRGRP etc below */
- #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
- 
- #define F_OK 0
- #define W_OK 2
- #define R_OK 4
- 
- #if (_MSC_VER < 1800)
- #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) || (_fpclass(x) == _FPCLASS_NINF))
- #define isnan(x) _isnan(x)
- #endif
- 
- /* Pulled from Makefile.port in mingw */
- #define DLSUFFIX ".dll"
- 
- #endif							/* _MSC_VER */
- 
- /* These aren't provided by either MingW or MSVC */
- #define S_IRGRP 0
- #define S_IWGRP 0
- #define S_IXGRP 0
- #define S_IRWXG 0
- #define S_IROTH 0
- #define S_IWOTH 0
- #define S_IXOTH 0
- #define S_IRWXO 0
--- 38,40 ----
diff --git a/src/include/port/win32_port.h b/src/include/port/win32_port.h
index ...e77866a .
*** a/src/include/port/win32_port.h
--- b/src/include/port/win32_port.h
***************
*** 0 ****
--- 1,487 ----
+ /*-------------------------------------------------------------------------
+  *
+  * win32_port.h
+  *	  Windows-specific compatibility stuff.
+  *
+  * Note this is read in MinGW as well as native Windows builds,
+  * but not in Cygwin builds.
+  *
+  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
+  * Portions Copyright (c) 1994, Regents of the University of California
+  *
+  * src/include/port/win32_port.h
+  *
+  *-------------------------------------------------------------------------
+  */
+ #ifndef PG_WIN32_PORT_H
+ #define PG_WIN32_PORT_H
+ 
+ /*
+  * Make sure _WIN32_WINNT has the minimum required value.
+  * Leave a higher value in place. When building with at least Visual
+  * Studio 2015 the minimum requirement is Windows Vista (0x0600) to
+  * get support for GetLocaleInfoEx() with locales. For everything else
+  * the minimum version is Windows XP (0x0501).
+  * Also for VS2015, add a define that stops compiler complaints about
+  * using the old Winsock API.
+  */
+ #if defined(_MSC_VER) && _MSC_VER >= 1900
+ #define  _WINSOCK_DEPRECATED_NO_WARNINGS
+ #define MIN_WINNT 0x0600
+ #else
+ #define MIN_WINNT 0x0501
+ #endif
+ 
+ #if defined(_WIN32_WINNT) && _WIN32_WINNT < MIN_WINNT
+ #undef _WIN32_WINNT
+ #endif
+ 
+ #ifndef _WIN32_WINNT
+ #define _WIN32_WINNT MIN_WINNT
+ #endif
+ 
+ /*
+  * Always build with SSPI support. Keep it as a #define in case
+  * we want a switch to disable it sometime in the future.
+  */
+ #define ENABLE_SSPI 1
+ 
+ /* undefine and redefine after #include */
+ #undef mkdir
+ 
+ #undef ERROR
+ 
+ /*
+  * The MinGW64 headers choke if this is already defined - they
+  * define it themselves.
+  */
+ #if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER)
+ #define _WINSOCKAPI_
+ #endif
+ 
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #include <windows.h>
+ #undef small
+ #include <process.h>
+ #include <signal.h>
+ #include <direct.h>
+ #include <sys/utime.h>			/* for non-unicode version */
+ #undef near
+ 
+ /* 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)
+ 
+ /*
+  * For historical reasons, we allow setting wal_sync_method to
+  * fsync_writethrough on Windows, even though it's really identical to fsync
+  * (both code paths wind up at _commit()).
+  */
+ #define HAVE_FSYNC_WRITETHROUGH
+ #define FSYNC_WRITETHROUGH_IS_FSYNC
+ 
+ #define USES_WINSOCK
+ 
+ /*
+  *	IPC defines
+  */
+ #undef HAVE_UNION_SEMUN
+ #define HAVE_UNION_SEMUN 1
+ 
+ #define IPC_RMID 256
+ #define IPC_CREAT 512
+ #define IPC_EXCL 1024
+ #define IPC_PRIVATE 234564
+ #define IPC_NOWAIT	2048
+ #define IPC_STAT 4096
+ 
+ #define EACCESS 2048
+ #ifndef EIDRM
+ #define EIDRM 4096
+ #endif
+ 
+ #define SETALL 8192
+ #define GETNCNT 16384
+ #define GETVAL 65536
+ #define SETVAL 131072
+ #define GETPID 262144
+ 
+ 
+ /*
+  *	Signal stuff
+  *
+  *	For WIN32, there is no wait() call so there are no wait() macros
+  *	to interpret the return value of system().  Instead, system()
+  *	return values < 0x100 are used for exit() termination, and higher
+  *	values are used to indicated non-exit() termination, which is
+  *	similar to a unix-style signal exit (think SIGSEGV ==
+  *	STATUS_ACCESS_VIOLATION).  Return values are broken up into groups:
+  *
+  *	http://msdn2.microsoft.com/en-gb/library/aa489609.aspx
+  *
+  *		NT_SUCCESS			0 - 0x3FFFFFFF
+  *		NT_INFORMATION		0x40000000 - 0x7FFFFFFF
+  *		NT_WARNING			0x80000000 - 0xBFFFFFFF
+  *		NT_ERROR			0xC0000000 - 0xFFFFFFFF
+  *
+  *	Effectively, we don't care on the severity of the return value from
+  *	system(), we just need to know if it was because of exit() or generated
+  *	by the system, and it seems values >= 0x100 are system-generated.
+  *	See this URL for a list of WIN32 STATUS_* values:
+  *
+  *		Wine (URL used in our error messages) -
+  *			http://source.winehq.org/source/include/ntstatus.h
+  *		Descriptions - http://www.comp.nus.edu.sg/~wuyongzh/my_doc/ntstatus.txt
+  *		MS SDK - http://www.nologs.com/ntstatus.html
+  *
+  *	It seems the exception lists are in both ntstatus.h and winnt.h, but
+  *	ntstatus.h has a more comprehensive list, and it only contains
+  *	exception values, rather than winnt, which contains lots of other
+  *	things:
+  *
+  *		http://www.microsoft.com/msj/0197/exception/exception.aspx
+  *
+  *		The ExceptionCode parameter is the number that the operating system
+  *		assigned to the exception. You can see a list of various exception codes
+  *		in WINNT.H by searching for #defines that start with "STATUS_". For
+  *		example, the code for the all-too-familiar STATUS_ACCESS_VIOLATION is
+  *		0xC0000005. A more complete set of exception codes can be found in
+  *		NTSTATUS.H from the Windows NT DDK.
+  *
+  *	Some day we might want to print descriptions for the most common
+  *	exceptions, rather than printing an include file name.  We could use
+  *	RtlNtStatusToDosError() and pass to FormatMessage(), which can print
+  *	the text of error values, but MinGW does not support
+  *	RtlNtStatusToDosError().
+  */
+ #define WIFEXITED(w)	(((w) & 0XFFFFFF00) == 0)
+ #define WIFSIGNALED(w)	(!WIFEXITED(w))
+ #define WEXITSTATUS(w)	(w)
+ #define WTERMSIG(w)		(w)
+ 
+ #define sigmask(sig) ( 1 << ((sig)-1) )
+ 
+ /* Signal function return values */
+ #undef SIG_DFL
+ #undef SIG_ERR
+ #undef SIG_IGN
+ #define SIG_DFL ((pqsigfunc)0)
+ #define SIG_ERR ((pqsigfunc)-1)
+ #define SIG_IGN ((pqsigfunc)1)
+ 
+ /* Some extra signals */
+ #define SIGHUP				1
+ #define SIGQUIT				3
+ #define SIGTRAP				5
+ #define SIGABRT				22	/* Set to match W32 value -- not UNIX value */
+ #define SIGKILL				9
+ #define SIGPIPE				13
+ #define SIGALRM				14
+ #define SIGSTOP				17
+ #define SIGTSTP				18
+ #define SIGCONT				19
+ #define SIGCHLD				20
+ #define SIGTTIN				21
+ #define SIGTTOU				22	/* Same as SIGABRT -- no problem, I hope */
+ #define SIGWINCH			28
+ #define SIGUSR1				30
+ #define SIGUSR2				31
+ 
+ /*
+  * New versions of MinGW have gettimeofday() and also declare
+  * struct timezone to support it.
+  */
+ #ifndef HAVE_GETTIMEOFDAY
+ struct timezone
+ {
+ 	int			tz_minuteswest; /* Minutes west of GMT.  */
+ 	int			tz_dsttime;		/* Nonzero if DST is ever in effect.  */
+ };
+ #endif
+ 
+ /* for setitimer in backend/port/win32/timer.c */
+ #define ITIMER_REAL 0
+ struct itimerval
+ {
+ 	struct timeval it_interval;
+ 	struct timeval it_value;
+ };
+ 
+ int			setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
+ 
+ /*
+  * WIN32 does not provide 64-bit off_t, but does provide the functions operating
+  * with 64-bit offsets.
+  */
+ #define pgoff_t __int64
+ #ifdef _MSC_VER
+ #define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin)
+ #define ftello(stream) _ftelli64(stream)
+ #else
+ #ifndef fseeko
+ #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin)
+ #endif
+ #ifndef ftello
+ #define ftello(stream) ftello64(stream)
+ #endif
+ #endif
+ 
+ /*
+  *	Win32 also doesn't have symlinks, but we can emulate them with
+  *	junction points on newer Win32 versions.
+  *
+  *	Cygwin has its own symlinks which work on Win95/98/ME where
+  *	junction points don't, so use those instead.  We have no way of
+  *	knowing what type of system Cygwin binaries will be run on.
+  *		Note: Some CYGWIN includes might #define WIN32.
+  */
+ extern int	pgsymlink(const char *oldpath, const char *newpath);
+ extern int	pgreadlink(const char *path, char *buf, size_t size);
+ extern bool pgwin32_is_junction(const char *path);
+ 
+ #define symlink(oldpath, newpath)	pgsymlink(oldpath, newpath)
+ #define readlink(path, buf, size)	pgreadlink(path, buf, size)
+ 
+ /*
+  * Supplement to <sys/types.h>.
+  *
+  * Perl already has typedefs for uid_t and gid_t.
+  */
+ #ifndef PLPERL_HAVE_UID_GID
+ typedef int uid_t;
+ typedef int gid_t;
+ #endif
+ typedef long key_t;
+ 
+ #ifdef _MSC_VER
+ typedef int pid_t;
+ #endif
+ 
+ /*
+  * Supplement to <sys/stat.h>.
+  */
+ #define lstat(path, sb) stat((path), (sb))
+ 
+ /*
+  * Supplement to <fcntl.h>.
+  * This is the same value as _O_NOINHERIT in the MS header file. This is
+  * to ensure that we don't collide with a future definition. It means
+  * we cannot use _O_NOINHERIT ourselves.
+  */
+ #define O_DSYNC 0x0080
+ 
+ /*
+  * Supplement to <errno.h>.
+  *
+  * We redefine network-related Berkeley error symbols as the corresponding WSA
+  * constants.  This allows elog.c to recognize them as being in the Winsock
+  * error code range and pass them off to pgwin32_socket_strerror(), since
+  * Windows' version of plain strerror() won't cope.  Note that this will break
+  * if these names are used for anything else besides Windows Sockets errors.
+  * See TranslateSocketError() when changing this list.
+  */
+ #undef EAGAIN
+ #define EAGAIN WSAEWOULDBLOCK
+ #undef EINTR
+ #define EINTR WSAEINTR
+ #undef EMSGSIZE
+ #define EMSGSIZE WSAEMSGSIZE
+ #undef EAFNOSUPPORT
+ #define EAFNOSUPPORT WSAEAFNOSUPPORT
+ #undef EWOULDBLOCK
+ #define EWOULDBLOCK WSAEWOULDBLOCK
+ #undef ECONNABORTED
+ #define ECONNABORTED WSAECONNABORTED
+ #undef ECONNRESET
+ #define ECONNRESET WSAECONNRESET
+ #undef EINPROGRESS
+ #define EINPROGRESS WSAEINPROGRESS
+ #undef EISCONN
+ #define EISCONN WSAEISCONN
+ #undef ENOBUFS
+ #define ENOBUFS WSAENOBUFS
+ #undef EPROTONOSUPPORT
+ #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+ #undef ECONNREFUSED
+ #define ECONNREFUSED WSAECONNREFUSED
+ #undef ENOTSOCK
+ #define ENOTSOCK WSAENOTSOCK
+ #undef EOPNOTSUPP
+ #define EOPNOTSUPP WSAEOPNOTSUPP
+ #undef EADDRINUSE
+ #define EADDRINUSE WSAEADDRINUSE
+ #undef EADDRNOTAVAIL
+ #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+ #undef EHOSTUNREACH
+ #define EHOSTUNREACH WSAEHOSTUNREACH
+ #undef ENOTCONN
+ #define ENOTCONN WSAENOTCONN
+ 
+ /*
+  * Extended locale functions with gratuitous underscore prefixes.
+  * (These APIs are nevertheless fully documented by Microsoft.)
+  */
+ #define locale_t _locale_t
+ #define tolower_l _tolower_l
+ #define toupper_l _toupper_l
+ #define towlower_l _towlower_l
+ #define towupper_l _towupper_l
+ #define isdigit_l _isdigit_l
+ #define iswdigit_l _iswdigit_l
+ #define isalpha_l _isalpha_l
+ #define iswalpha_l _iswalpha_l
+ #define isalnum_l _isalnum_l
+ #define iswalnum_l _iswalnum_l
+ #define isupper_l _isupper_l
+ #define iswupper_l _iswupper_l
+ #define islower_l _islower_l
+ #define iswlower_l _iswlower_l
+ #define isgraph_l _isgraph_l
+ #define iswgraph_l _iswgraph_l
+ #define isprint_l _isprint_l
+ #define iswprint_l _iswprint_l
+ #define ispunct_l _ispunct_l
+ #define iswpunct_l _iswpunct_l
+ #define isspace_l _isspace_l
+ #define iswspace_l _iswspace_l
+ #define strcoll_l _strcoll_l
+ #define strxfrm_l _strxfrm_l
+ #define wcscoll_l _wcscoll_l
+ #define wcstombs_l _wcstombs_l
+ #define mbstowcs_l _mbstowcs_l
+ 
+ /*
+  * Versions of libintl >= 0.18? try to replace setlocale() with a macro
+  * to their own versions.  Remove the macro, if it exists, because it
+  * ends up calling the wrong version when the backend and libintl use
+  * different versions of msvcrt.
+  */
+ #if defined(setlocale)
+ #undef setlocale
+ #endif
+ 
+ /*
+  * Define our own wrapper macro around setlocale() to work around bugs in
+  * Windows' native setlocale() function.
+  */
+ extern char *pgwin32_setlocale(int category, const char *locale);
+ 
+ #define setlocale(a,b) pgwin32_setlocale(a,b)
+ 
+ /* In backend/port/win32/signal.c */
+ extern PGDLLIMPORT volatile int pg_signal_queue;
+ extern PGDLLIMPORT int pg_signal_mask;
+ extern HANDLE pgwin32_signal_event;
+ extern HANDLE pgwin32_initial_signal_pipe;
+ 
+ #define UNBLOCKED_SIGNAL_QUEUE()	(pg_signal_queue & ~pg_signal_mask)
+ 
+ #define PG_SIGNAL_COUNT 32
+ #define kill(pid,sig)	pgkill(pid,sig)
+ /* in src/port/kill.c */
+ extern int	pgkill(int pid, int sig);
+ 
+ void		pgwin32_signal_initialize(void);
+ HANDLE		pgwin32_create_signal_listener(pid_t pid);
+ void		pgwin32_dispatch_queued_signals(void);
+ void		pg_queue_signal(int signum);
+ 
+ /* In backend/port/win32/socket.c */
+ #ifndef FRONTEND
+ #define socket(af, type, protocol) pgwin32_socket(af, type, protocol)
+ #define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen)
+ #define listen(s, backlog) pgwin32_listen(s, backlog)
+ #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen)
+ #define connect(s, name, namelen) pgwin32_connect(s, name, namelen)
+ #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
+ #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags)
+ #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags)
+ 
+ SOCKET		pgwin32_socket(int af, int type, int protocol);
+ int			pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen);
+ int			pgwin32_listen(SOCKET s, int backlog);
+ SOCKET		pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
+ int			pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen);
+ int			pgwin32_select(int nfds, fd_set *readfs, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
+ int			pgwin32_recv(SOCKET s, char *buf, int len, int flags);
+ int			pgwin32_send(SOCKET s, const void *buf, int len, int flags);
+ 
+ const char *pgwin32_socket_strerror(int err);
+ int			pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
+ 
+ extern int	pgwin32_noblock;
+ 
+ #endif
+ 
+ /* in backend/port/win32_shmem.c */
+ extern int	pgwin32_ReserveSharedMemoryRegion(HANDLE);
+ 
+ /* in backend/port/win32/crashdump.c */
+ extern void pgwin32_install_crashdump_handler(void);
+ 
+ /* in port/win32error.c */
+ extern void _dosmaperr(unsigned long);
+ 
+ /* in port/win32env.c */
+ extern int	pgwin32_putenv(const char *);
+ extern void pgwin32_unsetenv(const char *);
+ 
+ /* in port/win32security.c */
+ extern int	pgwin32_is_service(void);
+ extern int	pgwin32_is_admin(void);
+ 
+ /* Windows security token manipulation (in src/common/exec.c) */
+ extern BOOL AddUserToTokenDacl(HANDLE hToken);
+ 
+ #define putenv(x) pgwin32_putenv(x)
+ #define unsetenv(x) pgwin32_unsetenv(x)
+ 
+ /* Things that exist in MinGW headers, but need to be added to MSVC */
+ #ifdef _MSC_VER
+ 
+ #ifndef _WIN64
+ typedef long ssize_t;
+ #else
+ typedef __int64 ssize_t;
+ #endif
+ 
+ typedef unsigned short mode_t;
+ 
+ #define S_IRUSR _S_IREAD
+ #define S_IWUSR _S_IWRITE
+ #define S_IXUSR _S_IEXEC
+ #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+ /* see also S_IRGRP etc below */
+ #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+ #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+ 
+ #define F_OK 0
+ #define W_OK 2
+ #define R_OK 4
+ 
+ #if (_MSC_VER < 1800)
+ #define isinf(x) ((_fpclass(x) == _FPCLASS_PINF) || (_fpclass(x) == _FPCLASS_NINF))
+ #define isnan(x) _isnan(x)
+ #endif
+ 
+ /* Pulled from Makefile.port in MinGW */
+ #define DLSUFFIX ".dll"
+ 
+ #endif							/* _MSC_VER */
+ 
+ /* These aren't provided by either MinGW or MSVC */
+ #define S_IRGRP 0
+ #define S_IWGRP 0
+ #define S_IXGRP 0
+ #define S_IRWXG 0
+ #define S_IROTH 0
+ #define S_IWOTH 0
+ #define S_IXOTH 0
+ #define S_IRWXO 0
+ 
+ #endif							/* PG_WIN32_PORT_H */

Reply via email to