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