Robert Haas <[email protected]> writes:
> On Wed, Nov 15, 2017 at 5:22 PM, Tom Lane <[email protected]> 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 */