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