123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559 |
- /*-------------------------------------------------------------------------
- *
- * 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-2022, 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
- /*
- * 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
- /*
- * VS2013 and later issue warnings about using the old Winsock API,
- * which we don't really want to hear about.
- */
- #ifdef _MSC_VER
- #define _WINSOCK_DEPRECATED_NO_WARNINGS
- #endif
- /*
- * The MinGW64 headers choke if this is already defined - they
- * define it themselves.
- */
- #if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER)
- #define _WINSOCKAPI_
- #endif
- /*
- * windows.h includes a lot of other headers, slowing down compilation
- * significantly. WIN32_LEAN_AND_MEAN reduces that a bit. It'd be better to
- * remove the include of windows.h (as well as indirect inclusions of it) from
- * such a central place, but until then...
- */
- #define WIN32_LEAN_AND_MEAN
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <windows.h>
- #undef small
- #include <process.h>
- #include <signal.h>
- #include <direct.h>
- #undef near
- /* needed before sys/stat hacking below: */
- #define fstat microsoft_native_fstat
- #define stat microsoft_native_stat
- #include <sys/stat.h>
- #undef fstat
- #undef stat
- /* 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 indicate non-exit() termination, which is
- * similar to a unix-style signal exit (think SIGSEGV ==
- * STATUS_ACCESS_VIOLATION). Return values are broken up into groups:
- *
- * https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
- *
- * 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 -
- * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
- *
- * The comprehensive exception list is included in ntstatus.h from the
- * Windows Driver Kit (WDK). A subset of the list is also included in
- * winnt.h from the Windows SDK. Defining WIN32_NO_STATUS before including
- * windows.h helps to avoid any conflicts.
- *
- * 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 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);
- /* Convenience wrapper for GetFileType() */
- extern DWORD pgwin32_get_file_type(HANDLE hFile);
- /*
- * WIN32 does not provide 64-bit off_t, but does provide the functions operating
- * with 64-bit offsets. Also, fseek() might not give an error for unseekable
- * streams, so harden that function with our version.
- */
- #define pgoff_t __int64
- #ifdef _MSC_VER
- extern int _pgfseeko64(FILE *stream, pgoff_t offset, int origin);
- extern pgoff_t _pgftello64(FILE *stream);
- #define fseeko(stream, offset, origin) _pgfseeko64(stream, offset, origin)
- #define ftello(stream) _pgftello64(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>.
- *
- * We must pull in sys/stat.h before this part, else our overrides lose.
- *
- * stat() is not guaranteed to set the st_size field on win32, so we
- * redefine it to our own implementation. See src/port/win32stat.c.
- *
- * The struct stat is 32 bit in MSVC, so we redefine it as a copy of
- * struct __stat64. This also fixes the struct size for MINGW builds.
- */
- struct stat /* This should match struct __stat64 */
- {
- _dev_t st_dev;
- _ino_t st_ino;
- unsigned short st_mode;
- short st_nlink;
- short st_uid;
- short st_gid;
- _dev_t st_rdev;
- __int64 st_size;
- __time64_t st_atime;
- __time64_t st_mtime;
- __time64_t st_ctime;
- };
- extern int _pgfstat64(int fileno, struct stat *buf);
- extern int _pgstat64(const char *name, struct stat *buf);
- #define fstat(fileno, sb) _pgfstat64(fileno, sb)
- #define stat(path, sb) _pgstat64(path, sb)
- #define lstat(path, sb) _pgstat64(path, sb)
- /* These macros are not provided by older MinGW, nor by MSVC */
- #ifndef S_IRUSR
- #define S_IRUSR _S_IREAD
- #endif
- #ifndef S_IWUSR
- #define S_IWUSR _S_IWRITE
- #endif
- #ifndef S_IXUSR
- #define S_IXUSR _S_IEXEC
- #endif
- #ifndef S_IRWXU
- #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
- #endif
- #ifndef S_IRGRP
- #define S_IRGRP 0
- #endif
- #ifndef S_IWGRP
- #define S_IWGRP 0
- #endif
- #ifndef S_IXGRP
- #define S_IXGRP 0
- #endif
- #ifndef S_IRWXG
- #define S_IRWXG 0
- #endif
- #ifndef S_IROTH
- #define S_IROTH 0
- #endif
- #ifndef S_IWOTH
- #define S_IWOTH 0
- #endif
- #ifndef S_IXOTH
- #define S_IXOTH 0
- #endif
- #ifndef S_IRWXO
- #define S_IRWXO 0
- #endif
- #ifndef S_ISDIR
- #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
- #endif
- #ifndef S_ISREG
- #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
- #endif
- /*
- * 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 strerror.c to recognize them as being in the Winsock
- * error code range and pass them off to win32_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 EHOSTDOWN
- #define EHOSTDOWN WSAEHOSTDOWN
- #undef EHOSTUNREACH
- #define EHOSTUNREACH WSAEHOSTUNREACH
- #undef ENETDOWN
- #define ENETDOWN WSAENETDOWN
- #undef ENETRESET
- #define ENETRESET WSAENETRESET
- #undef ENETUNREACH
- #define ENETUNREACH WSAENETUNREACH
- #undef ENOTCONN
- #define ENOTCONN WSAENOTCONN
- #undef ETIMEDOUT
- #define ETIMEDOUT WSAETIMEDOUT
- /*
- * Locale stuff.
- *
- * 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 PGDLLIMPORT HANDLE pgwin32_signal_event;
- extern PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe;
- #define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask)
- #define PG_SIGNAL_COUNT 32
- extern void pgwin32_signal_initialize(void);
- extern HANDLE pgwin32_create_signal_listener(pid_t pid);
- extern void pgwin32_dispatch_queued_signals(void);
- extern void pg_queue_signal(int signum);
- /* In src/port/kill.c */
- #define kill(pid,sig) pgkill(pid,sig)
- extern int pgkill(int pid, int sig);
- /* 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)
- extern SOCKET pgwin32_socket(int af, int type, int protocol);
- extern int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen);
- extern int pgwin32_listen(SOCKET s, int backlog);
- extern SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen);
- extern int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen);
- extern int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout);
- extern int pgwin32_recv(SOCKET s, char *buf, int len, int flags);
- extern int pgwin32_send(SOCKET s, const void *buf, int len, int flags);
- extern int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout);
- extern PGDLLIMPORT int pgwin32_noblock;
- #endif /* FRONTEND */
- /* 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 int pgwin32_setenv(const char *name, const char *value, int overwrite);
- extern int pgwin32_unsetenv(const char *name);
- #define putenv(x) pgwin32_putenv(x)
- #define setenv(x,y,z) pgwin32_setenv(x,y,z)
- #define unsetenv(x) pgwin32_unsetenv(x)
- /* 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);
- /* 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 F_OK 0
- #define W_OK 2
- #define R_OK 4
- #endif /* _MSC_VER */
- #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || \
- defined(__MINGW32__) || defined(__MINGW64__)
- /*
- * VS2013 has a strtof() that seems to give correct answers for valid input,
- * even on the rounding edge cases, but which doesn't handle out-of-range
- * input correctly. Work around that.
- *
- * Mingw claims to have a strtof, and my reading of its source code suggests
- * that it ought to work (and not need this hack), but the regression test
- * results disagree with me; whether this is a version issue or not is not
- * clear. However, using our wrapper (and the misrounded-input variant file,
- * already required for supporting ancient systems) can't make things any
- * worse, except for a tiny performance loss when reading zeros.
- *
- * See also cygwin.h for another instance of this.
- */
- #define HAVE_BUGGY_STRTOF 1
- #endif
- #endif /* PG_WIN32_PORT_H */
|