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