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