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