1/*-------------------------------------------------------------------------
4 * Windows-specific compatibility stuff.
6 * Note this is read in MinGW as well as native Windows builds,
7 * but not in Cygwin builds.
9 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
10 * Portions Copyright (c) 1994, Regents of the University of California
12 * src/include/port/win32_port.h
14 *-------------------------------------------------------------------------
16#ifndef PG_WIN32_PORT_H
17#define PG_WIN32_PORT_H
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.
25/* undefine and redefine after #include */
31 * VS2013 and later issue warnings about using the old Winsock API,
32 * which we don't really want to hear about.
35#define _WINSOCK_DEPRECATED_NO_WARNINGS
39 * The MinGW64 headers choke if this is already defined - they
40 * define it themselves.
42#if !defined(__MINGW64_VERSION_MAJOR) || defined(_MSC_VER)
47 * windows.h includes a lot of other headers, slowing down compilation
48 * significantly. WIN32_LEAN_AND_MEAN reduces that a bit. It'd be better to
49 * remove the include of windows.h (as well as indirect inclusions of it) from
50 * such a central place, but until then...
52 * To be able to include ntstatus.h tell windows.h to not declare NTSTATUS by
53 * temporarily defining UMDF_USING_NTSTATUS, otherwise we'll get warning about
54 * macro redefinitions, as windows.h also defines NTSTATUS (yuck). That in
55 * turn requires including ntstatus.h, winternl.h to get common symbols.
57 #define WIN32_LEAN_AND_MEAN
58 #define UMDF_USING_NTSTATUS
72/* needed before sys/stat hacking below: */
73#define fstat microsoft_native_fstat
74#define stat microsoft_native_stat
79/* Must be here to avoid conflicting with prototype in windows.h */
80 #define mkdir(a,b) mkdir(a)
82/* Windows doesn't have fsync() as such, use _commit() */
83 #define fsync(fd) _commit(fd)
90#undef HAVE_UNION_SEMUN
91 #define HAVE_UNION_SEMUN 1
96 #define IPC_PRIVATE 234564
97 #define IPC_NOWAIT 2048
106 #define GETNCNT 16384
108 #define SETVAL 131072
109 #define GETPID 262144
115 * For WIN32, there is no wait() call so there are no wait() macros
116 * to interpret the return value of system(). Instead, system()
117 * return values < 0x100 are used for exit() termination, and higher
118 * values are used to indicate non-exit() termination, which is
119 * similar to a unix-style signal exit (think SIGSEGV ==
120 * STATUS_ACCESS_VIOLATION). Return values are broken up into groups:
122 * https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/using-ntstatus-values
124 * NT_SUCCESS 0 - 0x3FFFFFFF
125 * NT_INFORMATION 0x40000000 - 0x7FFFFFFF
126 * NT_WARNING 0x80000000 - 0xBFFFFFFF
127 * NT_ERROR 0xC0000000 - 0xFFFFFFFF
129 * Effectively, we don't care on the severity of the return value from
130 * system(), we just need to know if it was because of exit() or generated
131 * by the system, and it seems values >= 0x100 are system-generated.
132 * See this URL for a list of WIN32 STATUS_* values:
134 * Wine (URL used in our error messages) -
135 * http://source.winehq.org/source/include/ntstatus.h
137 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55
139 * The comprehensive exception list is included in ntstatus.h from the
140 * Windows Driver Kit (WDK). A subset of the list is also included in
141 * winnt.h from the Windows SDK. Defining WIN32_NO_STATUS before including
142 * windows.h helps to avoid any conflicts.
144 * Some day we might want to print descriptions for the most common
145 * exceptions, rather than printing an include file name. We could use
146 * RtlNtStatusToDosError() and pass to FormatMessage(), which can print
147 * the text of error values, but MinGW does not support
148 * RtlNtStatusToDosError().
150 #define WIFEXITED(w) (((w) & 0XFFFFFF00) == 0)
151 #define WIFSIGNALED(w) (!WIFEXITED(w))
152 #define WEXITSTATUS(w) (w)
153 #define WTERMSIG(w) (w)
155 #define sigmask(sig) ( 1 << ((sig)-1) )
157/* Some extra signals */
161 #define SIGABRT 22 /* Set to match W32 value -- not UNIX value */
173/* MinGW has gettimeofday(), but MSVC doesn't */
175/* Last parameter not used */
179/* for setitimer in backend/port/win32/timer.c */
180 #define ITIMER_REAL 0
189/* Convenience wrapper for GetFileType() */
193 * WIN32 does not provide 64-bit off_t, but does provide the functions operating
194 * with 64-bit offsets. Also, fseek() might not give an error for unseekable
195 * streams, so harden that function with our version.
197 #define pgoff_t __int64
200extern int _pgfseeko64(FILE *stream,
pgoff_t offset,
int origin);
201extern pgoff_t _pgftello64(FILE *stream);
202#define fseeko(stream, offset, origin) _pgfseeko64(stream, offset, origin)
203#define ftello(stream) _pgftello64(stream)
206 #define fseeko(stream, offset, origin) fseeko64(stream, offset, origin)
209 #define ftello(stream) ftello64(stream)
214 * Win32 also doesn't have symlinks, but we can emulate them with
215 * junction points on newer Win32 versions.
217 * Cygwin has its own symlinks which work on Win95/98/ME where
218 * junction points don't, so use those instead. We have no way of
219 * knowing what type of system Cygwin binaries will be run on.
220 * Note: Some CYGWIN includes might #define WIN32.
222 extern int pgsymlink(
const char *oldpath,
const char *newpath);
225 #define symlink(oldpath, newpath) pgsymlink(oldpath, newpath)
226 #define readlink(path, buf, size) pgreadlink(path, buf, size)
229 * Supplement to <sys/types.h>.
231 * Perl already has typedefs for uid_t and gid_t.
233#ifndef PLPERL_HAVE_UID_GID
244 * Supplement to <sys/stat.h>.
246 * We must pull in sys/stat.h before this part, else our overrides lose.
248 * stat() is not guaranteed to set the st_size field on win32, so we
249 * redefine it to our own implementation. See src/port/win32stat.c.
251 * The struct stat is 32 bit in MSVC, so we redefine it as a copy of
252 * struct __stat64. This also fixes the struct size for MINGW builds.
254 struct stat /* This should match struct __stat64 */
273 #define fstat(fileno, sb) _pgfstat64(fileno, sb)
274 #define stat(path, sb) _pgstat64(path, sb)
275 #define lstat(path, sb) _pglstat64(path, sb)
277/* These macros are not provided by older MinGW, nor by MSVC */
279 #define S_IRUSR _S_IREAD
282 #define S_IWUSR _S_IWRITE
285 #define S_IXUSR _S_IEXEC
288 #define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
315 #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
318 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
322 * In order for lstat() to be able to report junction points as symlinks, we
323 * need to hijack a bit in st_mode, since neither MSVC nor MinGW provides
324 * S_ISLNK and there aren't any spare bits. We'll steal the one for character
325 * devices, because we don't otherwise make use of those.
328#error "S_ISLNK is already defined"
331#error "S_IFLNK is already defined"
333 #define S_IFLNK S_IFCHR
334 #define S_ISLNK(m) (((m) & S_IFLNK) == S_IFLNK)
337 * Supplement to <fcntl.h>.
338 * This is the same value as _O_NOINHERIT in the MS header file. This is
339 * to ensure that we don't collide with a future definition. It means
340 * we cannot use _O_NOINHERIT ourselves.
342 #define O_DSYNC 0x0080
345 * Our open() replacement does not create inheritable handles, so it is safe to
346 * ignore O_CLOEXEC. (If we were using Windows' own open(), it might be
347 * necessary to convert this to _O_NOINHERIT.)
352 * Supplement to <errno.h>.
354 * We redefine network-related Berkeley error symbols as the corresponding WSA
355 * constants. This allows strerror.c to recognize them as being in the Winsock
356 * error code range and pass them off to win32_socket_strerror(), since
357 * Windows' version of plain strerror() won't cope. Note that this will break
358 * if these names are used for anything else besides Windows Sockets errors.
359 * See TranslateSocketError() when changing this list.
362 #define EAGAIN WSAEWOULDBLOCK
364 #define EINTR WSAEINTR
366 #define EMSGSIZE WSAEMSGSIZE
368 #define EAFNOSUPPORT WSAEAFNOSUPPORT
370 #define EWOULDBLOCK WSAEWOULDBLOCK
372 #define ECONNABORTED WSAECONNABORTED
374 #define ECONNRESET WSAECONNRESET
376 #define EINPROGRESS WSAEINPROGRESS
378 #define EISCONN WSAEISCONN
380 #define ENOBUFS WSAENOBUFS
381#undef EPROTONOSUPPORT
382 #define EPROTONOSUPPORT WSAEPROTONOSUPPORT
384 #define ECONNREFUSED WSAECONNREFUSED
386 #define ENOTSOCK WSAENOTSOCK
388 #define EOPNOTSUPP WSAEOPNOTSUPP
390 #define EADDRINUSE WSAEADDRINUSE
392 #define EADDRNOTAVAIL WSAEADDRNOTAVAIL
394 #define EHOSTDOWN WSAEHOSTDOWN
396 #define EHOSTUNREACH WSAEHOSTUNREACH
398 #define ENETDOWN WSAENETDOWN
400 #define ENETRESET WSAENETRESET
402 #define ENETUNREACH WSAENETUNREACH
404 #define ENOTCONN WSAENOTCONN
406 #define ETIMEDOUT WSAETIMEDOUT
409 * Supplement to <string.h>.
411 #define strtok_r strtok_s
414 * Supplement to <time.h>.
418 * MinGW has these functions if _POSIX_C_SOURCE is defined. Third-party
419 * libraries might do that, so to avoid clashes we get ahead of it and define
420 * it ourselves and use the system functions provided by MinGW.
422#define gmtime_r(clock, result) (gmtime_s(result, clock) ? NULL : (result))
423#define localtime_r(clock, result) (localtime_s(result, clock) ? NULL : (result))
429 * Extended locale functions with gratuitous underscore prefixes.
430 * (These APIs are nevertheless fully documented by Microsoft.)
432 #define locale_t _locale_t
433 #define tolower_l _tolower_l
434 #define toupper_l _toupper_l
435 #define towlower_l _towlower_l
436 #define towupper_l _towupper_l
437 #define isdigit_l _isdigit_l
438 #define iswdigit_l _iswdigit_l
439 #define isalpha_l _isalpha_l
440 #define iswalpha_l _iswalpha_l
441 #define isalnum_l _isalnum_l
442 #define iswalnum_l _iswalnum_l
443 #define isupper_l _isupper_l
444 #define iswupper_l _iswupper_l
445 #define islower_l _islower_l
446 #define iswlower_l _iswlower_l
447 #define isgraph_l _isgraph_l
448 #define iswgraph_l _iswgraph_l
449 #define isprint_l _isprint_l
450 #define iswprint_l _iswprint_l
451 #define ispunct_l _ispunct_l
452 #define iswpunct_l _iswpunct_l
453 #define isspace_l _isspace_l
454 #define iswspace_l _iswspace_l
455 #define strcoll_l _strcoll_l
456 #define strxfrm_l _strxfrm_l
457 #define wcscoll_l _wcscoll_l
460 * Versions of libintl >= 0.18? try to replace setlocale() with a macro
461 * to their own versions. Remove the macro, if it exists, because it
462 * ends up calling the wrong version when the backend and libintl use
463 * different versions of msvcrt.
465#if defined(setlocale)
470 * Define our own wrapper macro around setlocale() to work around bugs in
471 * Windows' native setlocale() function.
475 #define setlocale(a,b) pgwin32_setlocale(a,b)
478/* In backend/port/win32/signal.c */
484 #define UNBLOCKED_SIGNAL_QUEUE() (pg_signal_queue & ~pg_signal_mask)
485 #define PG_SIGNAL_COUNT 32
492/* In src/port/kill.c */
493 #define kill(pid,sig) pgkill(pid,sig)
496/* In backend/port/win32/socket.c */
498 #define socket(af, type, protocol) pgwin32_socket(af, type, protocol)
499 #define bind(s, addr, addrlen) pgwin32_bind(s, addr, addrlen)
500 #define listen(s, backlog) pgwin32_listen(s, backlog)
501 #define accept(s, addr, addrlen) pgwin32_accept(s, addr, addrlen)
502 #define connect(s, name, namelen) pgwin32_connect(s, name, namelen)
503 #define select(n, r, w, e, timeout) pgwin32_select(n, r, w, e, timeout)
504 #define recv(s, buf, len, flags) pgwin32_recv(s, buf, len, flags)
505 #define send(s, buf, len, flags) pgwin32_send(s, buf, len, flags)
508extern int pgwin32_bind(SOCKET s,
struct sockaddr *addr,
int addrlen);
510extern SOCKET
pgwin32_accept(SOCKET s,
struct sockaddr *addr,
int *addrlen);
512extern int pgwin32_select(
int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
const struct timeval *timeout);
521/* in backend/port/win32_shmem.c */
524/* in backend/port/win32/crashdump.c */
527/* in port/win32dlopen.c */
528extern void *
dlopen(
const char *file,
int mode);
529extern void *
dlsym(
void *handle,
const char *
symbol);
530extern int dlclose(
void *handle);
534 #define RTLD_GLOBAL 0
536/* in port/win32error.c */
539/* in port/win32env.c */
544 #define putenv(x) pgwin32_putenv(x)
545 #define setenv(x,y,z) pgwin32_setenv(x,y,z)
546 #define unsetenv(x) pgwin32_unsetenv(x)
548/* in port/win32security.c */
552/* Windows security token manipulation (in src/common/exec.c) */
555/* Things that exist in MinGW headers, but need to be added to MSVC */
561typedef __int64 ssize_t;
564typedef unsigned short mode_t;
572#if defined(__MINGW32__) || defined(__MINGW64__)
574 * Mingw claims to have a strtof, and my reading of its source code suggests
575 * that it ought to work (and not need this hack), but the regression test
576 * results disagree with me; whether this is a version issue or not is not
577 * clear. However, using our wrapper (and the misrounded-input variant file,
578 * already required for supporting ancient systems) can't make things any
579 * worse, except for a tiny performance loss when reading zeros.
581 * See also cygwin.h for another instance of this.
583#define HAVE_BUGGY_STRTOF 1
586/* in port/win32pread.c */
587extern ssize_t
pg_pread(
int fd,
void *
buf,
size_t nbyte, off_t offset);
589/* in port/win32pwrite.c */
590extern ssize_t
pg_pwrite(
int fd,
const void *
buf,
size_t nbyte, off_t offset);
592#endif /* PG_WIN32_PORT_H */
static PgChecksumMode mode
static int fd(const char *x, int i)
struct timeval it_interval
static void overwrite(PGconn *conn, Oid lobjId, int start, int len)
HANDLE pgwin32_create_signal_listener(pid_t pid)
void * dlopen(const char *file, int mode)
int pgwin32_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, const struct timeval *timeout)
void pg_queue_signal(int signum)
int pgwin32_send(SOCKET s, const void *buf, int len, int flags)
PGDLLIMPORT int pgwin32_noblock
int pgwin32_waitforsinglesocket(SOCKET s, int what, int timeout)
SOCKET pgwin32_socket(int af, int type, int protocol)
int _pgfstat64(int fileno, struct stat *buf)
int pgwin32_connect(SOCKET s, const struct sockaddr *name, int namelen)
void * dlsym(void *handle, const char *symbol)
int pgwin32_recv(SOCKET s, char *buf, int len, int flags)
void pgwin32_dispatch_queued_signals(void)
void pgwin32_install_crashdump_handler(void)
BOOL AddUserToTokenDacl(HANDLE hToken)
int _pgstat64(const char *name, struct stat *buf)
int pgwin32_unsetenv(const char *name)
SOCKET pgwin32_accept(SOCKET s, struct sockaddr *addr, int *addrlen)
PGDLLIMPORT volatile int pg_signal_queue
ssize_t pg_pwrite(int fd, const void *buf, size_t nbyte, off_t offset)
void _dosmaperr(unsigned long)
int pgreadlink(const char *path, char *buf, size_t size)
DWORD pgwin32_get_file_type(HANDLE hFile)
PGDLLIMPORT HANDLE pgwin32_initial_signal_pipe
int pgwin32_bind(SOCKET s, struct sockaddr *addr, int addrlen)
ssize_t pg_pread(int fd, void *buf, size_t nbyte, off_t offset)
PGDLLIMPORT int pg_signal_mask
int pgwin32_putenv(const char *)
int pgwin32_is_service(void)
int pgwin32_ReserveSharedMemoryRegion(HANDLE)
int pgsymlink(const char *oldpath, const char *newpath)
int _pglstat64(const char *name, struct stat *buf)
PGDLLIMPORT HANDLE pgwin32_signal_event
void pgwin32_signal_initialize(void)
int pgwin32_is_admin(void)
int pgwin32_setenv(const char *name, const char *value, int overwrite)
int pgkill(int pid, int sig)
char * pgwin32_setlocale(int category, const char *locale)
int dlclose(void *handle)
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue)
int pgwin32_listen(SOCKET s, int backlog)
int gettimeofday(struct timeval *tp, void *tzp)