]> git.ipfire.org Git - thirdparty/squid.git/blame - compat/os/mswindows.h
SourceFormat Enforcement
[thirdparty/squid.git] / compat / os / mswindows.h
CommitLineData
37be9888 1/*
bde978a6 2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
37be9888
AJ
3 *
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
7 */
8
f04e1182 9/*
f04e1182
AJ
10 * AUTHOR: Andrey Shorin <tolsty@tushino.com>
11 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
f04e1182 12 */
37be9888 13
c164de6e
AJ
14#ifndef SQUID_OS_MSWINDOWS_H
15#define SQUID_OS_MSWINDOWS_H
f04e1182 16
be266cb2 17#if _SQUID_WINDOWS_
f04e1182 18
37be9888
AJ
19/****************************************************************************
20 *--------------------------------------------------------------------------*
21 * DO *NOT* MAKE ANY CHANGES below here unless you know what you're doing...*
22 *--------------------------------------------------------------------------*
23 ****************************************************************************/
24
3f5727dc
AJ
25/* we target Windows XP and later - some API are missing otherwise */
26#if _SQUID_MINGW_
27#if WINVER < 0x0501
28#undef WINVER
29#define WINVER 0x0501
30#undef _WIN32_WINNT
31#define _WIN32_WINNT WINVER
32#endif
33#endif /* _SQUID_MINGW_ */
34
89c03bd3
AJ
35#include "compat/initgroups.h"
36
ee4d4e85
AJ
37#if HAVE_DIRECT_H
38#include <direct.h>
39#endif
3f5727dc
AJ
40#if HAVE_FCNTL_H
41#include <fcntl.h>
42#endif /* HAVE_FCNTL_H */
43#if HAVE_STRING_H
44#include <string.h>
45#endif /* HAVE_FCNTL_H */
46#if HAVE_SYS_STAT_H
47#include <sys/stat.h>
48#endif /* HAVE_SYS_STAT_H */
49
f04e1182
AJ
50#define ACL WindowsACL
51#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
52#if _MSC_VER == 1400
53#define _CRT_SECURE_NO_DEPRECATE
54#pragma warning( disable : 4290 )
55#pragma warning( disable : 4996 )
56#endif
57#endif
58
f3f3e961
GS
59/* Some MinGW version defines min() and max() as macros
60 causing the fail of the build process. The following
61 #define will disable that definition
62 */
3f5727dc 63#if defined(__GNUC__) && !NOMINMAX
f3f3e961
GS
64#define NOMINMAX
65#endif
66
7ae66f7b
AJ
67/// some builds of MinGW do not define IPV6_V6ONLY socket option
68#if !defined(IPV6_V6ONLY)
69#define IPV6_V6ONLY 27
70#endif
71
3f5727dc 72#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64
f53969cc 73# define __USE_FILE_OFFSET64 1
f04e1182
AJ
74#endif
75
76#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
77
3f5727dc 78#if defined(__USE_FILE_OFFSET64)
f04e1182 79typedef uint64_t ino_t;
f04e1182 80#else
f04e1182 81typedef unsigned long ino_t;
f04e1182
AJ
82#endif
83
84#define INT64_MAX _I64_MAX
85#define INT64_MIN _I64_MIN
86
87#include "default_config_file.h"
88/* Some tricks for MS Compilers */
89#define __STDC__ 1
90#define THREADLOCAL __declspec(thread)
91
92#elif defined(__GNUC__) /* gcc environment */
93
94#define THREADLOCAL __attribute__((section(".tls")))
95
3f5727dc 96#endif /* _MSC_VER */
f04e1182 97
3f5727dc
AJ
98/* ONLY Microsoft C Compiler needs these: */
99#if defined(_MSC_VER)
f04e1182 100#define alloca _alloca
f04e1182
AJ
101#define fileno _fileno
102#define fstat _fstati64
3f5727dc
AJ
103#define lseek _lseeki64
104#define memccpy _memccpy
3f5727dc
AJ
105#define mktemp _mktemp
106#define snprintf _snprintf
107#define stat _stati64
108#define strcasecmp _stricmp
3f5727dc
AJ
109#define strlwr _strlwr
110#define strncasecmp _strnicmp
111#define tempnam _tempnam
112#define vsnprintf _vsnprintf
f04e1182 113#endif
3f5727dc 114
3f5727dc
AJ
115/* Microsoft C Compiler and CygWin need these. MinGW does not */
116#if defined(_MSC_VER) || _SQUID_CYGWIN_
3bfe9ee7 117SQUIDCEXTERN int WIN32_ftruncate(int fd, off_t size);
f04e1182 118#define ftruncate WIN32_ftruncate
3bfe9ee7
AJ
119SQUIDCEXTERN int WIN32_truncate(const char *pathname, off_t length);
120#define truncate WIN32_truncate
ee4d4e85 121#define chdir _chdir
3bfe9ee7 122#endif
3f5727dc
AJ
123
124/* All three compiler systems need these: */
3f5727dc
AJ
125#define dup _dup
126#define dup2 _dup2
127#define fdopen _fdopen
f04e1182
AJ
128#define getcwd _getcwd
129#define getpid _getpid
ee4d4e85 130#define mkdir(p,F) mkdir((p))
f04e1182 131#define pclose _pclose
f04e1182
AJ
132#define popen _popen
133#define putenv _putenv
134#define setmode _setmode
135#define sleep(t) Sleep((t)*1000)
f04e1182
AJ
136#define umask _umask
137#define unlink _unlink
f04e1182 138
f59055a6 139#ifndef O_RDONLY
f04e1182 140#define O_RDONLY _O_RDONLY
f59055a6
AJ
141#endif
142#ifndef O_WRONLY
f04e1182 143#define O_WRONLY _O_WRONLY
f59055a6
AJ
144#endif
145#ifndef O_RDWR
f04e1182 146#define O_RDWR _O_RDWR
f59055a6
AJ
147#endif
148#ifndef O_APPEND
f04e1182 149#define O_APPEND _O_APPEND
f59055a6
AJ
150#endif
151#ifndef O_CREAT
f04e1182 152#define O_CREAT _O_CREAT
f59055a6
AJ
153#endif
154#ifndef O_TRUNC
f04e1182 155#define O_TRUNC _O_TRUNC
f59055a6
AJ
156#endif
157#ifndef O_EXCL
f04e1182 158#define O_EXCL _O_EXCL
f59055a6
AJ
159#endif
160#ifndef O_TEXT
f04e1182 161#define O_TEXT _O_TEXT
f59055a6
AJ
162#endif
163#ifndef O_BINARY
f04e1182 164#define O_BINARY _O_BINARY
f59055a6
AJ
165#endif
166#ifndef O_RAW
f04e1182 167#define O_RAW _O_BINARY
f59055a6
AJ
168#endif
169#ifndef O_TEMPORARY
f04e1182 170#define O_TEMPORARY _O_TEMPORARY
f59055a6
AJ
171#endif
172#ifndef O_NOINHERIT
f04e1182 173#define O_NOINHERIT _O_NOINHERIT
f59055a6
AJ
174#endif
175#ifndef O_SEQUENTIAL
f04e1182 176#define O_SEQUENTIAL _O_SEQUENTIAL
f59055a6
AJ
177#endif
178#ifndef O_RANDOM
f04e1182 179#define O_RANDOM _O_RANDOM
f59055a6
AJ
180#endif
181#ifndef O_NDELAY
f53969cc 182#define O_NDELAY 0
f59055a6 183#endif
f04e1182 184
f59055a6 185#ifndef S_IFMT
f04e1182 186#define S_IFMT _S_IFMT
f59055a6
AJ
187#endif
188#ifndef S_IFDIR
f04e1182 189#define S_IFDIR _S_IFDIR
f59055a6
AJ
190#endif
191#ifndef S_IFCHR
f04e1182 192#define S_IFCHR _S_IFCHR
f59055a6
AJ
193#endif
194#ifndef S_IFREG
f04e1182 195#define S_IFREG _S_IFREG
f59055a6
AJ
196#endif
197#ifndef S_IREAD
f04e1182 198#define S_IREAD _S_IREAD
f59055a6
AJ
199#endif
200#ifndef S_IWRITE
f04e1182 201#define S_IWRITE _S_IWRITE
f59055a6
AJ
202#endif
203#ifndef S_IEXEC
f04e1182 204#define S_IEXEC _S_IEXEC
f59055a6
AJ
205#endif
206#ifndef S_IRWXO
f04e1182 207#define S_IRWXO 007
f59055a6 208#endif
3f5727dc 209
89c03bd3
AJ
210/* There are no group protection bits like these in Windows.
211 * The values are used by umask() to remove permissions so
212 * mapping to user permission bits will break file accesses.
213 * Map group permissions to harmless zero instead.
214 */
215#ifndef S_IXGRP
216#define S_IXGRP 0
217#endif
218#ifndef S_IWGRP
219#define S_IWGRP 0
220#endif
221#ifndef S_IWOTH
222#define S_IWOTH 0
223#endif
224#ifndef S_IXOTH
225#define S_IXOTH 0
226#endif
227
3f5727dc 228#if defined(_MSC_VER)
f53969cc 229#define S_ISDIR(m) (((m) & _S_IFDIR) == _S_IFDIR)
f04e1182
AJ
230#endif
231
f53969cc
SM
232#define SIGHUP 1 /* hangup */
233#define SIGKILL 9 /* kill (cannot be caught or ignored) */
234#define SIGBUS 10 /* bus error */
235#define SIGPIPE 13 /* write on a pipe with no one to read it */
236#define SIGCHLD 20 /* to parent on child stop or exit */
237#define SIGUSR1 30 /* user defined signal 1 */
238#define SIGUSR2 31 /* user defined signal 2 */
f04e1182 239
3f5727dc
AJ
240#if _SQUID_MINGW_
241typedef unsigned char boolean;
242typedef unsigned char u_char;
243typedef unsigned int u_int;
244#endif
245
246#if defined(_MSC_VER)
f04e1182
AJ
247typedef int uid_t;
248typedef int gid_t;
a61c4143 249#endif
f04e1182
AJ
250
251struct passwd {
252 char *pw_name; /* user name */
253 char *pw_passwd; /* user password */
254 uid_t pw_uid; /* user id */
255 gid_t pw_gid; /* group id */
256 char *pw_gecos; /* real name */
257 char *pw_dir; /* home directory */
258 char *pw_shell; /* shell program */
259};
260
261struct group {
262 char *gr_name; /* group name */
263 char *gr_passwd; /* group password */
264 gid_t gr_gid; /* group id */
265 char **gr_mem; /* group members */
266};
267
32d002cb 268#if !HAVE_GETTIMEOFDAY
f04e1182 269struct timezone {
f53969cc
SM
270 int tz_minuteswest; /* minutes west of Greenwich */
271 int tz_dsttime; /* type of dst correction */
f04e1182
AJ
272};
273#endif
274
275#define CHANGE_FD_SETSIZE 1
276#if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE
277#define FD_SETSIZE SQUID_MAXFD
278#endif
279
f04e1182
AJ
280#include <process.h>
281#include <errno.h>
3f5727dc 282#if HAVE_WINSOCK2_H
f04e1182 283#include <winsock2.h>
3f5727dc
AJ
284#elif HAVE_WINSOCK_H
285#include <winsock.h>
f04e1182 286#endif
3f5727dc
AJ
287
288#if !_SQUID_CYGWIN_
289#undef IN_ADDR
f04e1182 290#include <ws2tcpip.h>
3f5727dc
AJ
291#endif
292
f04e1182
AJ
293#if (EAI_NODATA == EAI_NONAME)
294#undef EAI_NODATA
295#define EAI_NODATA WSANO_DATA
296#endif
3f5727dc
AJ
297
298#if defined(_MSC_VER)
f04e1182
AJ
299/* Hack to suppress compiler warnings on FD_SET() & FD_CLR() */
300#pragma warning (push)
301#pragma warning (disable:4142)
302#endif
3f5727dc 303
f04e1182
AJ
304/* prevent inclusion of wingdi.h */
305#define NOGDI
306#include <ws2spi.h>
3f5727dc
AJ
307
308#if defined(_MSC_VER)
f04e1182
AJ
309#pragma warning (pop)
310#endif
3f5727dc 311
f04e1182 312#include <io.h>
f04e1182
AJ
313
314typedef char * caddr_t;
315
25f98340
AJ
316#ifndef _PATH_DEVNULL
317#define _PATH_DEVNULL "NUL"
318#endif
319
f04e1182
AJ
320#undef FD_CLOSE
321#undef FD_OPEN
322#undef FD_READ
323#undef FD_WRITE
a61c4143
AJ
324
325#ifndef EISCONN
f04e1182 326#define EISCONN WSAEISCONN
a61c4143
AJ
327#endif
328#ifndef EINPROGRESS
f04e1182 329#define EINPROGRESS WSAEINPROGRESS
a61c4143
AJ
330#endif
331#ifndef EWOULDBLOCK
f04e1182 332#define EWOULDBLOCK WSAEWOULDBLOCK
a61c4143
AJ
333#endif
334#ifndef EALREADY
f04e1182 335#define EALREADY WSAEALREADY
a61c4143
AJ
336#endif
337#ifndef ETIMEDOUT
f04e1182 338#define ETIMEDOUT WSAETIMEDOUT
a61c4143
AJ
339#endif
340#ifndef ECONNREFUSED
f04e1182 341#define ECONNREFUSED WSAECONNREFUSED
a61c4143
AJ
342#endif
343#ifndef ECONNRESET
f04e1182 344#define ECONNRESET WSAECONNRESET
a61c4143
AJ
345#endif
346#ifndef ENOTCONN
f04e1182 347#define ENOTCONN WSAENOTCONN
a61c4143
AJ
348#endif
349#ifndef ERESTART
f04e1182 350#define ERESTART WSATRY_AGAIN
a61c4143
AJ
351#endif
352#ifndef EAFNOSUPPORT
f04e1182 353#define EAFNOSUPPORT WSAEAFNOSUPPORT
a61c4143 354#endif
a13c93d1
C
355#ifndef ENETUNREACH
356#define ENETUNREACH WSAENETUNREACH
357#endif
3f5727dc
AJ
358#ifndef ENOTSUP
359#define ENOTSUP WSAEOPNOTSUPP
360#endif
f04e1182
AJ
361
362#undef h_errno
363#define h_errno errno /* we'll set it ourselves */
364
365#undef FD_CLR
366#define FD_CLR(fd, set) do { \
367 u_int __i; \
368 SOCKET __sock = _get_osfhandle(fd); \
369 for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \
370 if (((fd_set FAR *)(set))->fd_array[__i] == __sock) { \
371 while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
372 ((fd_set FAR *)(set))->fd_array[__i] = \
373 ((fd_set FAR *)(set))->fd_array[__i+1]; \
374 __i++; \
375 } \
376 ((fd_set FAR *)(set))->fd_count--; \
377 break; \
378 } \
379 } \
380} while(0)
381
382#undef FD_SET
383#define FD_SET(fd, set) do { \
384 u_int __i; \
385 SOCKET __sock = _get_osfhandle(fd); \
386 for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
387 if (((fd_set FAR *)(set))->fd_array[__i] == (__sock)) { \
388 break; \
389 } \
390 } \
391 if (__i == ((fd_set FAR *)(set))->fd_count) { \
392 if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
393 ((fd_set FAR *)(set))->fd_array[__i] = (__sock); \
394 ((fd_set FAR *)(set))->fd_count++; \
395 } \
396 } \
397} while(0)
398
399#undef FD_ISSET
400#define FD_ISSET(fd, set) Win32__WSAFDIsSet(fd, (fd_set FAR *)(set))
401
402/* internal to Microsoft CRTLIB */
403typedef struct {
404 long osfhnd; /* underlying OS file HANDLE */
405 char osfile; /* attributes of file (e.g., open in text mode?) */
406 char pipech; /* one char buffer for handles opened on pipes */
407#ifdef _MT
408 int lockinitflag;
409 CRITICAL_SECTION lock;
410#endif /* _MT */
411} ioinfo;
412#define IOINFO_L2E 5
413#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
414#define _pioinfo(i) ( __pioinfo[(i) >> IOINFO_L2E] + ((i) & (IOINFO_ARRAY_ELTS - 1)) )
415#define _osfile(i) ( _pioinfo(i)->osfile )
416#define _osfhnd(i) ( _pioinfo(i)->osfhnd )
9facd91c 417#if !defined(FOPEN)
f04e1182 418#define FOPEN 0x01 /* file handle open */
9facd91c 419#endif
f04e1182 420
3f5727dc 421#if defined(_MSC_VER)
f04e1182
AJ
422SQUIDCEXTERN _CRTIMP ioinfo * __pioinfo[];
423SQUIDCEXTERN int __cdecl _free_osfhnd(int);
3f5727dc 424#endif
f04e1182 425
3f5727dc 426#if _SQUID_MINGW_
f04e1182
AJ
427__MINGW_IMPORT ioinfo * __pioinfo[];
428SQUIDCEXTERN int _free_osfhnd(int);
f04e1182
AJ
429#endif
430
431SQUIDCEXTERN THREADLOCAL int ws32_result;
432
26799597 433#if defined(__cplusplus)
f04e1182 434
3f5727dc
AJ
435inline int
436close(int fd)
f04e1182
AJ
437{
438 char l_so_type[sizeof(int)];
439 int l_so_type_siz = sizeof(l_so_type);
440 SOCKET sock = _get_osfhandle(fd);
441
442 if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0) {
443 int result = 0;
444 if (closesocket(sock) == SOCKET_ERROR) {
445 errno = WSAGetLastError();
446 result = 1;
447 }
448 _free_osfhnd(fd);
449 _osfile(fd) = 0;
450 return result;
451 } else
452 return _close(fd);
453}
454
455#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */
456
457#ifndef _S_IREAD
458#define _S_IREAD 0x0100
459#endif
460
461#ifndef _S_IWRITE
462#define _S_IWRITE 0x0080
463#endif
464
3f5727dc
AJ
465inline int
466open(const char *filename, int oflag, int pmode = 0)
f04e1182
AJ
467{
468 return _open(filename, oflag, pmode & (_S_IREAD | _S_IWRITE));
469}
470#endif
471
3f5727dc
AJ
472inline int
473read(int fd, void * buf, size_t siz)
f04e1182
AJ
474{
475 char l_so_type[sizeof(int)];
476 int l_so_type_siz = sizeof(l_so_type);
477 SOCKET sock = _get_osfhandle(fd);
478
479 if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0)
480 return ::recv(sock, (char FAR *) buf, (int)siz, 0);
481 else
482 return _read(fd, buf, (unsigned int)siz);
483}
484
3f5727dc
AJ
485inline int
486write(int fd, const void * buf, size_t siz)
f04e1182
AJ
487{
488 char l_so_type[sizeof(int)];
489 int l_so_type_siz = sizeof(l_so_type);
490 SOCKET sock = _get_osfhandle(fd);
491
492 if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0)
493 return ::send(sock, (char FAR *) buf, siz, 0);
494 else
495 return _write(fd, buf, siz);
496}
497
3f5727dc
AJ
498inline char *
499index(const char *s, int c)
f04e1182
AJ
500{
501 return (char *)strchr(s,c);
502}
503
a27592a2
AJ
504// stdlib <functional> definitions are required before std API redefinitions.
505#include <functional>
506
f04e1182
AJ
507/** \cond AUTODOCS-IGNORE */
508namespace Squid
509{
510/** \endcond */
511
6538a478
AJ
512/*
513 * Each of these functions is defined in the Squid namespace so as not to
514 * clash with the winsock.h and winsock2.h definitions.
515 * It is then paired with a #define to cause these wrappers to be used by
516 * the main code instead of those system definitions.
517 *
518 * We do this wrapper in order to:
519 * - cast the parameter types in only one place, and
520 * - record errors in POSIX errno variable, and
521 * - map the FD value used by Squid to the socket handes used by Windows.
522 */
523
3f5727dc
AJ
524inline int
525accept(int s, struct sockaddr * a, socklen_t * l)
f04e1182
AJ
526{
527 SOCKET result;
3f5727dc 528 if ((result = ::accept(_get_osfhandle(s), a, l)) == INVALID_SOCKET) {
f04e1182
AJ
529 if (WSAEMFILE == (errno = WSAGetLastError()))
530 errno = EMFILE;
531 return -1;
532 } else
533 return _open_osfhandle(result, 0);
534}
e7df1761 535#define accept(s,a,l) Squid::accept(s,a,reinterpret_cast<socklen_t*>(l))
f04e1182 536
3f5727dc
AJ
537inline int
538bind(int s, const struct sockaddr * n, socklen_t l)
f04e1182
AJ
539{
540 if (::bind(_get_osfhandle(s),n,l) == SOCKET_ERROR) {
541 errno = WSAGetLastError();
542 return -1;
543 } else
544 return 0;
545}
31f146ed 546#define bind(s,n,l) Squid::bind(s,n,l)
f04e1182 547
3f5727dc
AJ
548inline int
549connect(int s, const struct sockaddr * n, socklen_t l)
f04e1182
AJ
550{
551 if (::connect(_get_osfhandle(s),n,l) == SOCKET_ERROR) {
552 if (WSAEMFILE == (errno = WSAGetLastError()))
553 errno = EMFILE;
554 return -1;
555 } else
556 return 0;
557}
31f146ed 558#define connect(s,n,l) Squid::connect(s,n,l)
f04e1182 559
3f5727dc 560inline struct hostent *
8f6ae1a5 561gethostbyname(const char *n) {
f04e1182
AJ
562 HOSTENT FAR * result;
563 if ((result = ::gethostbyname(n)) == NULL)
564 errno = WSAGetLastError();
565 return result;
566}
567#define gethostbyname(n) Squid::gethostbyname(n)
568
3f5727dc
AJ
569inline SERVENT FAR *
570getservbyname(const char * n, const char * p)
f04e1182
AJ
571{
572 SERVENT FAR * result;
573 if ((result = ::getservbyname(n, p)) == NULL)
574 errno = WSAGetLastError();
575 return result;
576}
577#define getservbyname(n,p) Squid::getservbyname(n,p)
578
3f5727dc
AJ
579inline HOSTENT FAR *
580gethostbyaddr(const void * a, size_t l, int t)
f04e1182
AJ
581{
582 HOSTENT FAR * result;
3f5727dc 583 if ((result = ::gethostbyaddr((const char*)a, l, t)) == NULL)
f04e1182
AJ
584 errno = WSAGetLastError();
585 return result;
586}
31f146ed 587#define gethostbyaddr(a,l,t) Squid::gethostbyaddr(a,l,t)
f04e1182 588
3f5727dc 589inline int
31f146ed 590getsockname(int s, struct sockaddr * n, socklen_t * l)
f04e1182 591{
3f5727dc
AJ
592 int i=*l;
593 if (::getsockname(_get_osfhandle(s), n, &i) == SOCKET_ERROR) {
f04e1182
AJ
594 errno = WSAGetLastError();
595 return -1;
596 } else
597 return 0;
598}
e7df1761 599#define getsockname(s,a,l) Squid::getsockname(s,a,reinterpret_cast<socklen_t*>(l))
f04e1182 600
3f5727dc
AJ
601inline int
602gethostname(char * n, size_t l)
f04e1182
AJ
603{
604 if ((::gethostname(n, l)) == SOCKET_ERROR) {
605 errno = WSAGetLastError();
606 return -1;
607 } else
608 return 0;
609}
31f146ed 610#define gethostname(n,l) Squid::gethostname(n,l)
f04e1182 611
3f5727dc
AJ
612inline int
613getsockopt(int s, int l, int o, void * v, socklen_t * n)
f04e1182
AJ
614{
615 Sleep(1);
616 if ((::getsockopt(_get_osfhandle(s), l, o,(char *) v, n)) == SOCKET_ERROR) {
617 errno = WSAGetLastError();
618 return -1;
619 } else
620 return 0;
621}
31f146ed 622#define getsockopt(s,l,o,v,n) Squid::getsockopt(s,l,o,v,n)
f04e1182 623
55d7d5e9
AJ
624inline char *
625inet_ntop(int af, const void *src, char *dst, size_t size)
626{
dfb96b6b 627#if HAVE_DECL_INETNTOPA
55d7d5e9 628 return (char*)InetNtopA(af, const_cast<void*>(src), dst, size);
dfb96b6b 629#else
73e755f4 630 return ::inet_ntop(af, src, dst, size);
dfb96b6b 631#endif
55d7d5e9
AJ
632}
633#define inet_ntop(a,s,d,l) Squid::inet_ntop(a,s,d,l)
634
dfb96b6b
AJ
635inline char *
636inet_pton(int af, const void *src, char *dst)
637{
638#if HAVE_DECL_INETPTONA
639 return (char*)InetPtonA(af, const_cast<void*>(src), dst);
640#else
73e755f4 641 return ::inet_pton(af, src, dst);
dfb96b6b
AJ
642#endif
643}
644#define inet_pton(a,s,d) Squid::inet_pton(a,s,d)
645
f04e1182 646/* Simple ioctl() emulation */
3f5727dc
AJ
647inline int
648ioctl(int s, int c, void * a)
f04e1182
AJ
649{
650 if ((::ioctlsocket(_get_osfhandle(s), c, (u_long FAR *)a)) == SOCKET_ERROR) {
651 errno = WSAGetLastError();
652 return -1;
653 } else
654 return 0;
655}
31f146ed 656#define ioctl(s,c,a) Squid::ioctl(s,c,a)
f04e1182 657
3f5727dc
AJ
658inline int
659ioctlsocket(int s, long c, u_long FAR * a)
f04e1182
AJ
660{
661 if ((::ioctlsocket(_get_osfhandle(s), c, a)) == SOCKET_ERROR) {
662 errno = WSAGetLastError();
663 return -1;
664 } else
665 return 0;
666}
31f146ed 667#define ioctlsocket(s,c,a) Squid::ioctlsocket(s,c,a)
f04e1182 668
3f5727dc
AJ
669inline int
670listen(int s, int b)
f04e1182
AJ
671{
672 if (::listen(_get_osfhandle(s), b) == SOCKET_ERROR) {
673 if (WSAEMFILE == (errno = WSAGetLastError()))
674 errno = EMFILE;
675 return -1;
676 } else
677 return 0;
678}
31f146ed 679#define listen(s,b) Squid::listen(s,b)
f04e1182 680
3f5727dc
AJ
681inline ssize_t
682recv(int s, void * b, size_t l, int f)
f04e1182 683{
3f5727dc 684 ssize_t result;
f04e1182
AJ
685 if ((result = ::recv(_get_osfhandle(s), (char *)b, l, f)) == SOCKET_ERROR) {
686 errno = WSAGetLastError();
687 return -1;
688 } else
689 return result;
690}
3f5727dc 691#define recv(s,b,l,f) Squid::recv(s,b,l,f)
f04e1182 692
3f5727dc 693inline ssize_t
31f146ed 694recvfrom(int s, void * b, size_t l, int f, struct sockaddr * fr, socklen_t * fl)
f04e1182 695{
3f5727dc
AJ
696 ssize_t result;
697 int ifl=*fl;
698 if ((result = ::recvfrom(_get_osfhandle(s), (char *)b, l, f, fr, &ifl)) == SOCKET_ERROR) {
f04e1182
AJ
699 errno = WSAGetLastError();
700 return -1;
701 } else
702 return result;
703}
e7df1761 704#define recvfrom(s,b,l,f,r,n) Squid::recvfrom(s,b,l,f,r,reinterpret_cast<socklen_t*>(n))
f04e1182 705
3f5727dc
AJ
706inline int
707select(int n, fd_set * r, fd_set * w, fd_set * e, struct timeval * t)
f04e1182
AJ
708{
709 int result;
710 if ((result = ::select(n,r,w,e,t)) == SOCKET_ERROR) {
711 errno = WSAGetLastError();
712 return -1;
713 } else
714 return result;
715}
716#define select(n,r,w,e,t) Squid::select(n,r,w,e,t)
717
3f5727dc
AJ
718inline ssize_t
719send(int s, const char * b, size_t l, int f)
f04e1182 720{
3f5727dc
AJ
721 ssize_t result;
722 if ((result = ::send(_get_osfhandle(s), b, l, f)) == SOCKET_ERROR) {
f04e1182
AJ
723 errno = WSAGetLastError();
724 return -1;
725 } else
726 return result;
727}
e7df1761 728#define send(s,b,l,f) Squid::send(s,reinterpret_cast<const char*>(b),l,f)
f04e1182 729
3f5727dc
AJ
730inline ssize_t
731sendto(int s, const void * b, size_t l, int f, const struct sockaddr * t, socklen_t tl)
f04e1182 732{
3f5727dc 733 ssize_t result;
f04e1182
AJ
734 if ((result = ::sendto(_get_osfhandle(s), (char *)b, l, f, t, tl)) == SOCKET_ERROR) {
735 errno = WSAGetLastError();
736 return -1;
737 } else
738 return result;
739}
31f146ed 740#define sendto(a,b,l,f,t,n) Squid::sendto(a,b,l,f,t,n)
f04e1182 741
3f5727dc
AJ
742inline int
743setsockopt(SOCKET s, int l, int o, const void * v, socklen_t n)
f04e1182
AJ
744{
745 SOCKET socket;
746
747 socket = ((s == INVALID_SOCKET) ? s : (SOCKET)_get_osfhandle((int)s));
748
3f5727dc 749 if (::setsockopt(socket, l, o, (const char *)v, n) == SOCKET_ERROR) {
f04e1182
AJ
750 errno = WSAGetLastError();
751 return -1;
752 } else
753 return 0;
754}
755#define setsockopt(s,l,o,v,n) Squid::setsockopt(s,l,o,v,n)
756
3f5727dc
AJ
757inline int
758shutdown(int s, int h)
f04e1182
AJ
759{
760 if (::shutdown(_get_osfhandle(s),h) == SOCKET_ERROR) {
761 errno = WSAGetLastError();
762 return -1;
763 } else
764 return 0;
765}
31f146ed 766#define shutdown(s,h) Squid::shutdown(s,h)
f04e1182 767
3f5727dc
AJ
768inline int
769socket(int f, int t, int p)
f04e1182
AJ
770{
771 SOCKET result;
772 if ((result = ::socket(f, t, p)) == INVALID_SOCKET) {
773 if (WSAEMFILE == (errno = WSAGetLastError()))
774 errno = EMFILE;
775 return -1;
776 } else
777 return _open_osfhandle(result, 0);
778}
779#define socket(f,t,p) Squid::socket(f,t,p)
780
5def7931
AJ
781inline int
782pipe(int pipefd[2])
783{
784 return _pipe(pipefd,4096,_O_BINARY);
785}
31f146ed 786#define pipe(a) Squid::pipe(a)
5def7931 787
3f5727dc
AJ
788inline int
789WSAAsyncSelect(int s, HWND h, unsigned int w, long e)
f04e1182
AJ
790{
791 if (::WSAAsyncSelect(_get_osfhandle(s), h, w, e) == SOCKET_ERROR) {
792 errno = WSAGetLastError();
793 return -1;
794 } else
795 return 0;
796}
6538a478 797#define WSAAsyncSelect(s,h,w,e) Squid::WSAAsyncSelect(s,h,w,e)
f04e1182
AJ
798
799#undef WSADuplicateSocket
3f5727dc
AJ
800inline int
801WSADuplicateSocket(int s, DWORD n, LPWSAPROTOCOL_INFO l)
f04e1182
AJ
802{
803#ifdef UNICODE
804 if (::WSADuplicateSocketW(_get_osfhandle(s), n, l) == SOCKET_ERROR) {
805#else
806 if (::WSADuplicateSocketA(_get_osfhandle(s), n, l) == SOCKET_ERROR) {
807#endif
808 errno = WSAGetLastError();
809 return -1;
810 } else
811 return 0;
812}
6538a478 813#define WSADuplicateSocket(s,n,l) Squid::WSADuplicateSocket(s,n,l)
f04e1182
AJ
814
815#undef WSASocket
3f5727dc
AJ
816inline int
817WSASocket(int a, int t, int p, LPWSAPROTOCOL_INFO i, GROUP g, DWORD f)
33380a2d 818{
f04e1182
AJ
819 SOCKET result;
820#ifdef UNICODE
821 if ((result = ::WSASocketW(a, t, p, i, g, f)) == INVALID_SOCKET) {
822#else
823 if ((result = ::WSASocketA(a, t, p, i, g, f)) == INVALID_SOCKET) {
824#endif
825 if (WSAEMFILE == (errno = WSAGetLastError()))
826 errno = EMFILE;
827 return -1;
828 } else
829 return _open_osfhandle(result, 0);
830}
6538a478 831#define WSASocket(a,t,p,i,g,f) Squid::WSASocket(a,t,p,i,g,f)
f04e1182
AJ
832
833} /* namespace Squid */
834
835#else /* #ifdef __cplusplus */
836#define connect(s,n,l) \
f53969cc
SM
837 (SOCKET_ERROR == connect(_get_osfhandle(s),n,l) ? \
838 (WSAEMFILE == (errno = WSAGetLastError()) ? errno = EMFILE : -1, -1) : 0)
f04e1182 839#define gethostbyname(n) \
f53969cc
SM
840 (NULL == ((HOSTENT FAR*)(ws32_result = (int)gethostbyname(n))) ? \
841 (errno = WSAGetLastError()), (HOSTENT FAR*)NULL : (HOSTENT FAR*)ws32_result)
f04e1182 842#define gethostname(n,l) \
f53969cc
SM
843 (SOCKET_ERROR == gethostname(n,l) ? \
844 (errno = WSAGetLastError()), -1 : 0)
f04e1182 845#define recv(s,b,l,f) \
f53969cc
SM
846 (SOCKET_ERROR == (ws32_result = recv(_get_osfhandle(s),b,l,f)) ? \
847 (errno = WSAGetLastError()), -1 : ws32_result)
f04e1182 848#define sendto(s,b,l,f,t,tl) \
f53969cc
SM
849 (SOCKET_ERROR == (ws32_result = sendto(_get_osfhandle(s),b,l,f,t,tl)) ? \
850 (errno = WSAGetLastError()), -1 : ws32_result)
f04e1182 851#define select(n,r,w,e,t) \
f53969cc
SM
852 (SOCKET_ERROR == (ws32_result = select(n,r,w,e,t)) ? \
853 (errno = WSAGetLastError()), -1 : ws32_result)
f04e1182 854#define socket(f,t,p) \
f53969cc
SM
855 (INVALID_SOCKET == ((SOCKET)(ws32_result = (int)socket(f,t,p))) ? \
856 ((WSAEMFILE == (errno = WSAGetLastError()) ? errno = EMFILE : -1), -1) : \
857 (SOCKET)_open_osfhandle(ws32_result,0))
f04e1182
AJ
858#define write _write /* Needed in util.c */
859#define open _open /* Needed in win32lib.c */
860#endif /* #ifdef __cplusplus */
861
33101725
AJ
862/* provide missing definitions from resoruce.h */
863/* NP: sys/resource.h and sys/time.h are apparently order-dependant. */
864#if HAVE_SYS_TIME_H
e9b472bc 865#include <sys/time.h>
33101725 866#endif
a61c4143
AJ
867#if HAVE_SYS_RESOURCE_H
868#include <sys/resource.h>
869#else
f53969cc
SM
870#define RUSAGE_SELF 0 /* calling process */
871#define RUSAGE_CHILDREN -1 /* terminated child processes */
f04e1182
AJ
872
873struct rusage {
f53969cc
SM
874 struct timeval ru_utime; /* user time used */
875 struct timeval ru_stime; /* system time used */
876 long ru_maxrss; /* integral max resident set size */
877 long ru_ixrss; /* integral shared text memory size */
878 long ru_idrss; /* integral unshared data size */
879 long ru_isrss; /* integral unshared stack size */
880 long ru_minflt; /* page reclaims */
881 long ru_majflt; /* page faults */
882 long ru_nswap; /* swaps */
883 long ru_inblock; /* block input operations */
884 long ru_oublock; /* block output operations */
885 long ru_msgsnd; /* messages sent */
886 long ru_msgrcv; /* messages received */
887 long ru_nsignals; /* signals received */
888 long ru_nvcsw; /* voluntary context switches */
889 long ru_nivcsw; /* involuntary context switches */
f04e1182 890};
a61c4143 891#endif /* HAVE_SYS_RESOURCE_H */
f04e1182
AJ
892
893#undef ACL
894
3f5727dc
AJ
895SQUIDCEXTERN int chroot(const char *dirname);
896SQUIDCEXTERN int kill(pid_t, int);
3f5727dc
AJ
897SQUIDCEXTERN struct passwd * getpwnam(char *unused);
898SQUIDCEXTERN struct group * getgrnam(char *unused);
899
900static inline uid_t
901geteuid(void)
902{
ec6d36d2 903 return 100;
3f5727dc
AJ
904}
905static inline int
906seteuid (uid_t euid)
907{
ec6d36d2 908 return 0;
3f5727dc
AJ
909}
910static inline uid_t
911getuid(void)
912{
ec6d36d2 913 return 100;
3f5727dc
AJ
914}
915static inline int
916setuid (uid_t uid)
917{
ec6d36d2 918 return 0;
3f5727dc
AJ
919}
920static inline gid_t
921getegid(void)
922{
ec6d36d2 923 return 100;
3f5727dc
AJ
924}
925static inline int
926setegid (gid_t egid)
927{
ec6d36d2 928 return 0;
3f5727dc
AJ
929}
930static inline int
931getgid(void)
932{
ec6d36d2 933 return 100;
3f5727dc
AJ
934}
935static inline int
936setgid (gid_t gid)
937{
ec6d36d2 938 return 0;
3f5727dc
AJ
939}
940
941/* for some reason autoconf misdetects getpagesize.. */
942#if HAVE_GETPAGESIZE && _SQUID_MINGW_
943#undef HAVE_GETPAGESIZE
944#endif
945
946#if !HAVE_GETPAGESIZE
947/* And now we define a compatibility layer */
948size_t getpagesize();
949#define HAVE_GETPAGESIZE 2
dc47f531
AJ
950#endif
951
3f5727dc
AJ
952SQUIDCEXTERN void WIN32_ExceptionHandlerInit(void);
953SQUIDCEXTERN int Win32__WSAFDIsSet(int fd, fd_set* set);
954SQUIDCEXTERN DWORD WIN32_IpAddrChangeMonitorInit();
955
41d00cd3
AJ
956/* gcc doesn't recognize the Windows native 64 bit formatting tags causing
957 * the compile fail, so we must disable the check on native Windows.
958 */
959#if __GNUC__
960#define PRINTF_FORMAT_ARG1
961#define PRINTF_FORMAT_ARG2
962#define PRINTF_FORMAT_ARG3
963#endif
964
c164de6e
AJ
965/* XXX: the logic around this is a bit warped:
966 * we #define ACL unconditionally at the top of this file,
967 * then #undef ACL unconditionally hafway down,
968 * then here re-define ACL to the same value as at the top,
969 * then include windows.h and #undef ACL again.
970 */
971#ifndef ACL
972#define ACL WindowsACL
973#define _MSWIN_ACL_WAS_NOT_DEFINED 1
974#endif
975#include <windows.h>
976#if _MSWIN_ACL_WAS_NOT_DEFINED
977#undef ACL
978#undef _MSWIN_ACL_WAS_NOT_DEFINED
979#endif
980
3f5727dc
AJ
981#if !HAVE_SYSLOG
982/* syslog compatibility layer derives from git */
983#define LOG_PID 0x01
984#define LOG_EMERG 0
985#define LOG_ALERT 1
986#define LOG_CRIT 2
987#define LOG_ERR 3
988#define LOG_WARNING 4
989#define LOG_NOTICE 5
990#define LOG_INFO 6
991#define LOG_DEBUG 7
992#define LOG_DAEMON (3<<3)
993
994void openlog(const char *ident, int logopt, int facility);
995void syslog(int priority, const char *fmt, ...);
996#endif
997
998#if _SQUID_MINGW_
999/* MinGW missing bits from sys/wait.h */
1000/* A status looks like:
1001 * <2 bytes info> <2 bytes code>
1002 *
1003 * <code> == 0, child has exited, info is the exit value
1004 * <code> == 1..7e, child has exited, info is the signal number.
1005 * <code> == 7f, child has stopped, info was the signal number.
1006 * <code> == 80, there was a core dump.
1007 */
1008#define WIFEXITED(w) (((w) & 0xff) == 0)
1009#define WIFSIGNALED(w) (((w) & 0x7f) > 0 && (((w) & 0x7f) < 0x7f))
1010#define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
1011#define WEXITSTATUS(w) (((w) >> 8) & 0xff)
1012#define WTERMSIG(w) ((w) & 0x7f)
1013#define WSTOPSIG WEXITSTATUS
1014#endif
1015
1016/* prototypes */
1017void WIN32_maperror(unsigned long WIN32_oserrno);
1018
be266cb2 1019#endif /* _SQUID_WINDOWS_ */
c164de6e 1020#endif /* SQUID_OS_MSWINDOWS_H */
f53969cc 1021