]>
Commit | Line | Data |
---|---|---|
3b1797bd | 1 | /* |
09c3d7cf | 2 | * $Id: win32.cc,v 1.27 2008/01/20 17:13:22 serassio Exp $ |
3b1797bd | 3 | * |
1b52df9a | 4 | * Windows support |
5 | * AUTHOR: Guido Serassio <serassio@squid-cache.org> | |
6 | * inspired by previous work by Romeo Anghelache & Eric Stern. | |
376f7892 | 7 | * |
8 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
9 | * ---------------------------------------------------------- | |
10 | * | |
11 | * Squid is the result of efforts by numerous individuals from | |
12 | * the Internet community; see the CONTRIBUTORS file for full | |
13 | * details. Many organizations have provided support for Squid's | |
14 | * development; see the SPONSORS file for full details. Squid is | |
15 | * Copyrighted (C) 2001 by the Regents of the University of | |
16 | * California; see the COPYRIGHT file for full details. Squid | |
17 | * incorporates software developed and/or copyrighted by other | |
18 | * sources; see the CREDITS file for full details. | |
19 | * | |
20 | * This program is free software; you can redistribute it and/or modify | |
21 | * it under the terms of the GNU General Public License as published by | |
22 | * the Free Software Foundation; either version 2 of the License, or | |
23 | * (at your option) any later version. | |
3b1797bd | 24 | * |
376f7892 | 25 | * This program is distributed in the hope that it will be useful, |
26 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
27 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
28 | * GNU General Public License for more details. | |
1b52df9a | 29 | * |
376f7892 | 30 | * You should have received a copy of the GNU General Public License |
31 | * along with this program; if not, write to the Free Software | |
32 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
3b1797bd | 33 | * |
34 | */ | |
35 | ||
36 | #include "squid.h" | |
376f7892 | 37 | #include "squid_windows.h" |
3b1797bd | 38 | |
06648839 | 39 | #ifdef _SQUID_MSWIN_ |
485a0d3f | 40 | #if HAVE_WIN32_PSAPI |
41 | #include <psapi.h> | |
42 | #endif | |
11871e3c | 43 | #ifndef _MSWSOCK_ |
44 | #include <mswsock.h> | |
45 | #endif | |
485a0d3f | 46 | #include <fde.h> |
06648839 | 47 | |
1bc874d7 | 48 | SQUIDCEXTERN LPCRITICAL_SECTION dbg_mutex; |
06648839 | 49 | void WIN32_ExceptionHandlerCleanup(void); |
50 | static LPTOP_LEVEL_EXCEPTION_FILTER Win32_Old_ExceptionHandler = NULL; | |
62e76326 | 51 | |
3ac433c1 | 52 | |
485a0d3f | 53 | int WIN32_pipe(int handles[2]) |
54 | { | |
55 | int new_socket; | |
56 | fde *F = NULL; | |
57 | ||
cc192b50 | 58 | IPAddress localhost; |
59 | IPAddress handle0; | |
60 | IPAddress handle1; | |
61 | struct addrinfo *AI = NULL; | |
485a0d3f | 62 | |
09c3d7cf | 63 | localhost.SetLocalhost(); |
485a0d3f | 64 | |
cc192b50 | 65 | #if !IPV6_SPECIAL_LOCALHOST |
66 | /* INET6: back-compatible: localhost pipes default to IPv4 unless set otherwise. | |
67 | * it is blocked by untested helpers on many admins configs | |
68 | * if this proves to be wrong it can die easily. | |
69 | */ | |
70 | localhost.SetIPv4(); | |
71 | #endif | |
485a0d3f | 72 | |
cc192b50 | 73 | handles[0] = handles[1] = -1; |
485a0d3f | 74 | |
cc192b50 | 75 | statCounter.syscalls.sock.sockets++; |
485a0d3f | 76 | |
cc192b50 | 77 | handle0 = localhost; |
78 | handle0.SetPort(0); | |
79 | handle0.GetAddrInfo(AI); | |
485a0d3f | 80 | |
cc192b50 | 81 | if ((new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0) |
82 | return -1; | |
485a0d3f | 83 | |
cc192b50 | 84 | if (bind(new_socket, AI->ai_addr, AI->ai_addrlen) < 0 || |
85 | listen(new_socket, 1) < 0 || getsockname(new_socket, AI->ai_addr, &(AI->ai_addrlen) ) < 0 || | |
86 | (handles[1] = socket(AI->ai_family, AI->ai_socktype, 0)) < 0) { | |
485a0d3f | 87 | closesocket(new_socket); |
88 | return -1; | |
89 | } | |
90 | ||
cc192b50 | 91 | handle0 = *AI; // retrieve the new details returned by connect() |
92 | ||
93 | handle1.SetPort(handle1.GetPort()); | |
94 | handle1.GetAddrInfo(AI); | |
485a0d3f | 95 | |
cc192b50 | 96 | if (connect(handles[1], AI->ai_addr, AI->ai_addrlen) < 0 || |
97 | (handles[0] = accept(new_socket, AI->ai_addr, &(AI->ai_addrlen)) ) < 0) { | |
485a0d3f | 98 | closesocket(handles[1]); |
99 | handles[1] = -1; | |
100 | closesocket(new_socket); | |
101 | return -1; | |
102 | } | |
103 | ||
104 | closesocket(new_socket); | |
105 | ||
106 | F = &fd_table[handles[0]]; | |
cc192b50 | 107 | F->local_addr = handle0; |
485a0d3f | 108 | |
109 | F = &fd_table[handles[1]]; | |
cc192b50 | 110 | F->local_addr = localhost; |
111 | handle1.NtoA(F->ipaddr, MAX_IPSTRLEN); | |
112 | F->remote_port = handle1.GetPort(); | |
485a0d3f | 113 | |
114 | return 0; | |
115 | } | |
116 | ||
117 | int WIN32_getrusage(int who, struct rusage *usage) | |
118 | { | |
119 | #if HAVE_WIN32_PSAPI | |
120 | ||
121 | if ((WIN32_OS_version == _WIN_OS_WINNT) || (WIN32_OS_version == _WIN_OS_WIN2K) | |
122 | || (WIN32_OS_version == _WIN_OS_WINXP) || (WIN32_OS_version == _WIN_OS_WINNET)) | |
123 | { | |
124 | /* On Windows NT/2000 call PSAPI.DLL for process Memory */ | |
125 | /* informations -- Guido Serassio */ | |
126 | HANDLE hProcess; | |
127 | PROCESS_MEMORY_COUNTERS pmc; | |
128 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | | |
129 | PROCESS_VM_READ, | |
130 | FALSE, GetCurrentProcessId()); | |
131 | { | |
132 | /* Microsoft CRT doesn't have getrusage function, */ | |
133 | /* so we get process CPU time information from PSAPI.DLL. */ | |
134 | FILETIME ftCreate, ftExit, ftKernel, ftUser; | |
135 | ||
136 | if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) { | |
07468826 HN |
137 | int64_t *ptUser = (int64_t *)&ftUser; |
138 | int64_t tUser64 = *ptUser / 10; | |
139 | int64_t *ptKernel = (int64_t *)&ftKernel; | |
140 | int64_t tKernel64 = *ptKernel / 10; | |
485a0d3f | 141 | usage->ru_utime.tv_sec =(long)(tUser64 / 1000000); |
142 | usage->ru_stime.tv_sec =(long)(tKernel64 / 1000000); | |
143 | usage->ru_utime.tv_usec =(long)(tUser64 % 1000000); | |
144 | usage->ru_stime.tv_usec =(long)(tKernel64 % 1000000); | |
145 | } else { | |
146 | CloseHandle( hProcess ); | |
147 | return -1; | |
148 | } | |
149 | } | |
150 | ||
151 | if (GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc))) { | |
152 | usage->ru_maxrss=(DWORD)(pmc.WorkingSetSize / getpagesize()); | |
153 | usage->ru_majflt=pmc.PageFaultCount; | |
154 | } else { | |
155 | CloseHandle( hProcess ); | |
156 | return -1; | |
157 | } | |
158 | ||
159 | CloseHandle( hProcess ); | |
160 | } | |
161 | ||
162 | #endif | |
163 | return 0; | |
164 | } | |
165 | ||
11871e3c | 166 | |
485a0d3f | 167 | int Win32__WSAFDIsSet(int fd, fd_set FAR * set |
168 | ) | |
169 | { | |
170 | fde *F = &fd_table[fd]; | |
171 | SOCKET s = F->win32.handle; | |
172 | ||
cc192b50 | 173 | return __WSAFDIsSet(s, set); |
485a0d3f | 174 | } |
175 | ||
06648839 | 176 | LONG CALLBACK WIN32_ExceptionHandler(EXCEPTION_POINTERS* ep) |
177 | { | |
178 | EXCEPTION_RECORD* er; | |
179 | ||
180 | er = ep->ExceptionRecord; | |
181 | ||
182 | switch (er->ExceptionCode) { | |
183 | ||
184 | case EXCEPTION_ACCESS_VIOLATION: | |
185 | raise(SIGSEGV); | |
186 | break; | |
187 | ||
188 | case EXCEPTION_DATATYPE_MISALIGNMENT: | |
189 | ||
190 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | |
191 | ||
192 | case EXCEPTION_IN_PAGE_ERROR: | |
193 | death(SIGBUS); | |
194 | break; | |
195 | ||
196 | default: | |
197 | break; | |
198 | } | |
199 | ||
200 | return EXCEPTION_CONTINUE_SEARCH; | |
201 | } | |
202 | ||
203 | ||
204 | void WIN32_ExceptionHandlerInit() | |
205 | { | |
206 | #if !defined(_DEBUG) | |
207 | ||
208 | if (Win32_Old_ExceptionHandler == NULL) | |
209 | Win32_Old_ExceptionHandler = SetUnhandledExceptionFilter(WIN32_ExceptionHandler); | |
210 | ||
211 | #endif | |
212 | } | |
213 | ||
214 | void WIN32_ExceptionHandlerCleanup() | |
215 | { | |
216 | if (Win32_Old_ExceptionHandler != NULL) | |
217 | SetUnhandledExceptionFilter(Win32_Old_ExceptionHandler); | |
218 | } | |
219 | ||
228bb3a9 | 220 | #endif /* SQUID_MSWIN_ */ |