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