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