1 /*------------------------------------------------------------------------- 2 * 3 * win32_port.h 4 * Windows-specific compatibility stuff. 5 * 6 * Note this is read in MinGW as well as native Windows builds, 7 * but not in Cygwin builds. 8 * 9 * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group 10 * Portions Copyright (c) 1994, Regents of the University of California 11 * 12 * src/include/port/win32_port.h 13 * 14 *------------------------------------------------------------------------- 15 */ 16 #ifndef PG_WIN32_PORT_H 17 #define PG_WIN32_PORT_H 18 19 /* 20 * Always build with SSPI support. Keep it as a #define in case 21 * we want a switch to disable it sometime in the future. 22 */ 23 #define ENABLE_SSPI 1 24 25 /* undefine and redefine after #include */ 26 #undef mkdir 27 28 #undef ERROR 29 30 /* 31 * VS2013 and later issue warnings about using the old Winsock API, 32 * which we don't really want to hear about. 33 */ 34 #ifdef _MSC_VER 35 #define _WINSOCK_DEPRECATED_NO_WARNINGS 36 #endif 37 38 /* 39 * The MinGW64 headers choke if this is already defined - they 40 * define it themselves. 41 */ 42 #if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER) 43 #define _WINSOCKAPI_ 44 #endif 45 46 #include <winsock2.h> 47 #include <ws2tcpip.h> 48 #include <windows.h> 49 #undef small 50 #include <process.h> 51 #include <signal.h> 52 #include <direct.h> 53 #undef near 54 #include <sys/stat.h> /* needed before sys/stat hacking below */ 55 56 /* Must be here to avoid conflicting with prototype in windows.h */ 57 #define mkdir(a,b) mkdir(a) 58 59 #define ftruncate(a,b) chsize(a,b) 60 61 /* Windows doesn't have fsync() as such, use _commit() */ 62 #define fsync(fd) _commit(fd) 63 64 /* 65 * For historical reasons, we allow setting wal_sync_method to 66 * fsync_writethrough on Windows, even though it's really identical to fsync 67 * (both code paths wind up at _commit()). 68 */ 69 #define HAVE_FSYNC_WRITETHROUGH 70 #define FSYNC_WRITETHROUGH_IS_FSYNC 71 72 #define USES_WINSOCK 73 74 /* 75 * IPC defines 76 */ 77 #undef HAVE_UNION_SEMUN 78 #define HAVE_UNION_SEMUN 1 79 80 #define IPC_RMID 256 81 #define IPC_CREAT 512 82 #define IPC_EXCL 1024 83 #define IPC_PRIVATE 234564 84 #define IPC_NOWAIT 2048 85 #define IPC_STAT 4096 86 87 #define EACCESS 2048 88 #ifndef EIDRM 89 #define EIDRM 4096 90 #endif 91 92 #define SETALL 8192 93 #define GETNCNT 16384 94 #define GETVAL 65536 95 #define SETVAL 131072 96 #define GETPID 262144 97 98 99 /* 100 * Signal stuff 101 * 102 * For WIN32, there is no wait() call so there are no wait() macros 103 * to interpret the return value of system(). Instead, system() 104 * return values < 0x100 are used for exit() termination, and higher 105 * values are used to indicate non-exit() termination, which is 106 * similar to a unix-style signal exit (think SIGSEGV == 107 * STATUS_ACCESS_VIOLATION). Return values are broken up into groups: 108 * 109 * https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values 110 * 111 * NT_SUCCESS 0 - 0x3FFFFFFF 112 * NT_INFORMATION 0x40000000 - 0x7FFFFFFF 113 * NT_WARNING 0x80000000 - 0xBFFFFFFF 114 * NT_ERROR 0xC0000000 - 0xFFFFFFFF 115 * 116 * Effectively, we don't care on the severity of the return value from 117 * system(), we just need to know if it was because of exit() or generated 118 * by the system, and it seems values >= 0x100 are system-generated. 119 * See this URL for a list of WIN32 STATUS_* values: 120 * 121 * Wine (URL used in our error messages) - 122 * http://source.winehq.org/source/include/ntstatus.h 123 * Descriptions - 124 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55 125 * 126 * The comprehensive exception list is included in ntstatus.h from the 127 * Windows Driver Kit (WDK). A subset of the list is also included in 128 * winnt.h from the Windows SDK. Defining WIN32_NO_STATUS before including 129 * windows.h helps to avoid any conflicts. 130 * 131 * Some day we might want to print descriptions for the most common 132 * exceptions, rather than printing an include file name. We could use 133 * RtlNtStatusToDosError() and pass to FormatMessage(), which can print 134 * the text of error values, but MinGW does not support 135 * RtlNtStatusToDosError(). 136 */ 137 #define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0) 138 #define WIFSIGNALED(w) (!WIFEXITED(w)) 139 #define WEXITSTATUS(w) (w) 140 #define WTERMSIG(w) (w) 141 142 #define sigmask(sig) ( 1 << ((sig)-1) ) 143 144 /* Signal function return values */ 145 #undef SIG_DFL 146 #undef SIG_ERR 147 #undef SIG_IGN 148 #define SIG_DFL ((pqsigfunc)0) 149 #define SIG_ERR ((pqsigfunc)-1) 150 #define SIG_IGN ((pqsigfunc)1) 151 152 /* Some extra signals */ 153 #define SIGHUP 1 154 #define SIGQUIT 3 155 #define SIGTRAP 5 156 #define SIGABRT 22 /* Set to match W32 value -- not UNIX value */ 157 #define SIGKILL 9 158 #define SIGPIPE 13 159 #define SIGALRM 14 160 #define SIGSTOP 17 161 #define SIGTSTP 18 162 #define SIGCONT 19 163 #define SIGCHLD 20 164 #define SIGWINCH 28 165 #define SIGUSR1 30 166 #define SIGUSR2 31 167 168 /* 169 * New versions of MinGW have gettimeofday() and also declare 170 * struct timezone to support it. 171 */ 172 #ifndef HAVE_GETTIMEOFDAY 173 struct timezone 174 { 175 int tz_minuteswest; /* Minutes west of GMT. */ 176 int tz_dsttime; /* Nonzero if DST is ever in effect. */ 177 }; 178 #endif 179 180 /* for setitimer in backend/port/win32/timer.c */ 181 #define ITIMER_REAL 0 182 struct itimerval 183 { 184 struct timeval it_interval; 185 struct timeval it_value; 186 }; 187 188 int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue); 189 190 /* 191 * WIN32 does not provide 64-bit off_t, but does provide the functions operating 192 * with 64-bit offsets. 193 */ 194 #define pgoff_t __int64 195 196 #ifdef _MSC_VER 197 #define fseeko(stream, offset, origin) _fseeki64(stream, offset, origin) 198 #define ftello(stream) _ftelli64(stream) 199 #else 200 #ifndef fseeko 201 #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin) 202 #endif 203 #ifndef ftello 204 #define ftello(stream) ftello64(stream) 205 #endif 206 #endif 207 208 /* 209 * Win32 also doesn't have symlinks, but we can emulate them with 210 * junction points on newer Win32 versions. 211 * 212 * Cygwin has its own symlinks which work on Win95/98/ME where 213 * junction points don't, so use those instead. We have no way of 214 * knowing what type of system Cygwin binaries will be run on. 215 * Note: Some CYGWIN includes might #define WIN32. 216 */ 217 extern int pgsymlink(const char *oldpath, const char *newpath); 218 extern int pgreadlink(const char *path, char *buf, size_t size); 219 extern bool pgwin32_is_junction(const char *path); 220 221 #define symlink(oldpath, newpath) pgsymlink(oldpath, newpath) 222 #define readlink(path, buf, size) pgreadlink(path, buf, size) 223 224 /* 225 * Supplement to <sys/types.h>. 226 * 227 * Perl already has typedefs for uid_t and gid_t. 228 */ 229 #ifndef PLPERL_HAVE_UID_GID 230 typedef int uid_t; 231 typedef int gid_t; 232 #endif 233 typedef long key_t; 234 235 #ifdef _MSC_VER 236 typedef int pid_t; 237 #endif 238 239 /* 240 * Supplement to <sys/stat.h>. 241 * 242 * We must pull in sys/stat.h before this part, else our overrides lose. 243 */ 244 #define lstat(path, sb) stat(path, sb) 245 246 /* 247 * stat() is not guaranteed to set the st_size field on win32, so we 248 * redefine it to our own implementation that is. 249 * 250 * Some frontends don't need the size from stat, so if UNSAFE_STAT_OK 251 * is defined we don't bother with this. 252 */ 253 #ifndef UNSAFE_STAT_OK 254 extern int pgwin32_safestat(const char *path, struct stat *buf); 255 #define stat(a,b) pgwin32_safestat(a,b) 256 #endif 257 258 /* These macros are not provided by older MinGW, nor by MSVC */ 259 #ifndef S_IRUSR 260 #define S_IRUSR _S_IREAD 261 #endif 262 #ifndef S_IWUSR 263 #define S_IWUSR _S_IWRITE 264 #endif 265 #ifndef S_IXUSR 266 #define S_IXUSR _S_IEXEC 267 #endif 268 #ifndef S_IRWXU 269 #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) 270 #endif 271 #ifndef S_IRGRP 272 #define S_IRGRP 0 273 #endif 274 #ifndef S_IWGRP 275 #define S_IWGRP 0 276 #endif 277 #ifndef S_IXGRP 278 #define S_IXGRP 0 279 #endif 280 #ifndef S_IRWXG 281 #define S_IRWXG 0 282 #endif 283 #ifndef S_IROTH 284 #define S_IROTH 0 285 #endif 286 #ifndef S_IWOTH 287 #define S_IWOTH 0 288 #endif 289 #ifndef S_IXOTH 290 #define S_IXOTH 0 291 #endif 292 #ifndef S_IRWXO 293 #define S_IRWXO 0 294 #endif 295 #ifndef S_ISDIR 296 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) 297 #endif 298 #ifndef S_ISREG 299 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) 300 #endif 301 302 /* 303 * Supplement to <fcntl.h>. 304 * This is the same value as _O_NOINHERIT in the MS header file. This is 305 * to ensure that we don't collide with a future definition. It means 306 * we cannot use _O_NOINHERIT ourselves. 307 */ 308 #define O_DSYNC 0x0080 309 310 /* 311 * Supplement to <errno.h>. 312 * 313 * We redefine network-related Berkeley error symbols as the corresponding WSA 314 * constants. This allows strerror.c to recognize them as being in the Winsock 315 * error code range and pass them off to win32_socket_strerror(), since 316 * Windows' version of plain strerror() won't cope. Note that this will break 317 * if these names are used for anything else besides Windows Sockets errors. 318 * See TranslateSocketError() when changing this list. 319 */ 320 #undef EAGAIN 321 #define EAGAIN WSAEWOULDBLOCK 322 #undef EINTR 323 #define EINTR WSAEINTR 324 #undef EMSGSIZE 325 #define EMSGSIZE WSAEMSGSIZE 326 #undef EAFNOSUPPORT 327 #define EAFNOSUPPORT WSAEAFNOSUPPORT 328 #undef EWOULDBLOCK 329 #define EWOULDBLOCK WSAEWOULDBLOCK 330 #undef ECONNABORTED 331 #define ECONNABORTED WSAECONNABORTED 332 #undef ECONNRESET 333 #define ECONNRESET WSAECONNRESET 334 #undef EINPROGRESS 335 #define EINPROGRESS WSAEINPROGRESS 336 #undef EISCONN 337 #define EISCONN WSAEISCONN 338 #undef ENOBUFS 339 #define ENOBUFS WSAENOBUFS 340 #undef EPROTONOSUPPORT 341 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT 342 #undef ECONNREFUSED 343 #define ECONNREFUSED WSAECONNREFUSED 344 #undef ENOTSOCK 345 #define ENOTSOCK WSAENOTSOCK 346 #undef EOPNOTSUPP 347 #define EOPNOTSUPP WSAEOPNOTSUPP 348 #undef EADDRINUSE 349 #define EADDRINUSE WSAEADDRINUSE 350 #undef EADDRNOTAVAIL 351 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL 352 #undef EHOSTUNREACH 353 #define EHOSTUNREACH WSAEHOSTUNREACH 354 #undef ENOTCONN 355 #define ENOTCONN WSAENOTCONN 356 357 /* 358 * Locale stuff. 359 * 360 * Extended locale functions with gratuitous underscore prefixes. 361 * (These APIs are nevertheless fully documented by Microsoft.) 362 */ 363 #define locale_t _locale_t 364 #define tolower_l _tolower_l 365 #define toupper_l _toupper_l 366 #define towlower_l _towlower_l 367 #define towupper_l _towupper_l 368 #define isdigit_l _isdigit_l 369 #define iswdigit_l _iswdigit_l 370 #define isalpha_l _isalpha_l 371 #define iswalpha_l _iswalpha_l 372 #define isalnum_l _isalnum_l 373 #define iswalnum_l _iswalnum_l 374 #define isupper_l _isupper_l 375 #define iswupper_l _iswupper_l 376 #define islower_l _islower_l 377 #define iswlower_l _iswlower_l 378 #define isgraph_l _isgraph_l 379 #define iswgraph_l _iswgraph_l 380 #define isprint_l _isprint_l 381 #define iswprint_l _iswprint_l 382 #define ispunct_l _ispunct_l 383 #define iswpunct_l _iswpunct_l 384 #define isspace_l _isspace_l 385 #define iswspace_l _iswspace_l 386 #define strcoll_l _strcoll_l 387 #define strxfrm_l _strxfrm_l 388 #define wcscoll_l _wcscoll_l 389 #define wcstombs_l _wcstombs_l 390 #define mbstowcs_l _mbstowcs_l 391 392 /* 393 * Versions of libintl >= 0.18? try to replace setlocale() with a macro 394 * to their own versions. Remove the macro, if it exists, because it 395 * ends up calling the wrong version when the backend and libintl use 396 * different versions of msvcrt. 397 */ 398 #if defined(setlocale) 399 #undef setlocale 400 #endif 401 402 /* 403 * Define our own wrapper macro around setlocale() to work around bugs in 404 * Windows' native setlocale() function. 405 */ 406 extern char *pgwin32_setlocale(int category, const char *locale); 407 408 #define setlocale(a,b) pgwin32_setlocale(a,b) 409 410 411 /* In backend/port/win32/signal.c */ 412 extern PGDLLIMPORT volatile int pg_signal_queue; 413 extern PGDLLIMPORT int pg_signal_mask; 414 extern HANDLE pgwin32_signal_event; 415 extern HANDLE pgwin32_initial_signal_pipe; 416 417 #define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask) 418 #define PG_SIGNAL_COUNT 32 419 420 void pgwin32_signal_initialize(void); 421 HANDLE pgwin32_create_signal_listener(pid_t pid); 422 void pgwin32_dispatch_queued_signals(void); 423 void pg_queue_signal(int signum); 424 425 /* In src/port/kill.c */ 426 #define kill(pid,sig) pgkill(pid,sig) 427 extern int pgkill(int pid, int sig); 428 429 /* In backend/port/win32/socket.c */ 430 #ifndef FRONTEND 431 #define socket(af, type, protocol) pgwin32_socket(af, type, protocol) 432 #define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen) 433 #define listen(s, backlog) pgwin32_listen(s, backlog) 434 #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen) 435 #define connect(s, name, namelen) pgwin32_connect(s, name, namelen) 436 #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout) 437 #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags) 438 #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags) 439 440 SOCKET pgwin32_socket(int af, int type, int protocol); 441 int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen); 442 int pgwin32_listen(SOCKET s, int backlog); 443 SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen); 444 int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen); 445 int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout); 446 int pgwin32_recv(SOCKET s, char *buf, int len, int flags); 447 int pgwin32_send(SOCKET s, const void *buf, int len, int flags); 448 int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout); 449 450 extern int pgwin32_noblock; 451 452 #endif /* FRONTEND */ 453 454 /* in backend/port/win32_shmem.c */ 455 extern int pgwin32_ReserveSharedMemoryRegion(HANDLE); 456 457 /* in backend/port/win32/crashdump.c */ 458 extern void pgwin32_install_crashdump_handler(void); 459 460 /* in port/win32error.c */ 461 extern void _dosmaperr(unsigned long); 462 463 /* in port/win32env.c */ 464 extern int pgwin32_putenv(const char *); 465 extern void pgwin32_unsetenv(const char *); 466 467 /* in port/win32security.c */ 468 extern int pgwin32_is_service(void); 469 extern int pgwin32_is_admin(void); 470 471 /* Windows security token manipulation (in src/common/exec.c) */ 472 extern BOOL AddUserToTokenDacl(HANDLE hToken); 473 474 #define putenv(x) pgwin32_putenv(x) 475 #define unsetenv(x) pgwin32_unsetenv(x) 476 477 /* Things that exist in MinGW headers, but need to be added to MSVC */ 478 #ifdef _MSC_VER 479 480 #ifndef _WIN64 481 typedef long ssize_t; 482 #else 483 typedef __int64 ssize_t; 484 #endif 485 486 typedef unsigned short mode_t; 487 488 #define F_OK 0 489 #define W_OK 2 490 #define R_OK 4 491 492 /* Pulled from Makefile.port in MinGW */ 493 #define DLSUFFIX ".dll" 494 495 #endif /* _MSC_VER */ 496 497 #if (defined(_MSC_VER) && (_MSC_VER < 1900)) || \ 498 defined(__MINGW32__) || defined(__MINGW64__) 499 /* 500 * VS2013 has a strtof() that seems to give correct answers for valid input, 501 * even on the rounding edge cases, but which doesn't handle out-of-range 502 * input correctly. Work around that. 503 * 504 * Mingw claims to have a strtof, and my reading of its source code suggests 505 * that it ought to work (and not need this hack), but the regression test 506 * results disagree with me; whether this is a version issue or not is not 507 * clear. However, using our wrapper (and the misrounded-input variant file, 508 * already required for supporting ancient systems) can't make things any 509 * worse, except for a tiny performance loss when reading zeros. 510 * 511 * See also cygwin.h for another instance of this. 512 */ 513 #define HAVE_BUGGY_STRTOF 1 514 #endif 515 516 #endif /* PG_WIN32_PORT_H */ 517