]>
Commit | Line | Data |
---|---|---|
3b1797bd | 1 | /* |
262a0e14 | 2 | * $Id$ |
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. | |
26ac0430 | 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. | |
26ac0430 | 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 | ||
ad61a2b4 AJ |
58 | IpAddress localhost; |
59 | IpAddress handle0; | |
60 | IpAddress handle1; | |
cc192b50 | 61 | struct addrinfo *AI = NULL; |
485a0d3f | 62 | |
09c3d7cf | 63 | localhost.SetLocalhost(); |
485a0d3f | 64 | |
cc192b50 | 65 | /* INET6: back-compatible: localhost pipes default to IPv4 unless set otherwise. |
66 | * it is blocked by untested helpers on many admins configs | |
67 | * if this proves to be wrong it can die easily. | |
68 | */ | |
69 | localhost.SetIPv4(); | |
485a0d3f | 70 | |
cc192b50 | 71 | handles[0] = handles[1] = -1; |
485a0d3f | 72 | |
cc192b50 | 73 | statCounter.syscalls.sock.sockets++; |
485a0d3f | 74 | |
cc192b50 | 75 | handle0 = localhost; |
76 | handle0.SetPort(0); | |
77 | handle0.GetAddrInfo(AI); | |
485a0d3f | 78 | |
cc192b50 | 79 | if ((new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0) |
80 | return -1; | |
485a0d3f | 81 | |
cc192b50 | 82 | if (bind(new_socket, AI->ai_addr, AI->ai_addrlen) < 0 || |
83 | listen(new_socket, 1) < 0 || getsockname(new_socket, AI->ai_addr, &(AI->ai_addrlen) ) < 0 || | |
84 | (handles[1] = socket(AI->ai_family, AI->ai_socktype, 0)) < 0) { | |
485a0d3f | 85 | closesocket(new_socket); |
86 | return -1; | |
87 | } | |
88 | ||
cc192b50 | 89 | handle0 = *AI; // retrieve the new details returned by connect() |
90 | ||
91 | handle1.SetPort(handle1.GetPort()); | |
92 | handle1.GetAddrInfo(AI); | |
485a0d3f | 93 | |
cc192b50 | 94 | if (connect(handles[1], AI->ai_addr, AI->ai_addrlen) < 0 || |
95 | (handles[0] = accept(new_socket, AI->ai_addr, &(AI->ai_addrlen)) ) < 0) { | |
485a0d3f | 96 | closesocket(handles[1]); |
97 | handles[1] = -1; | |
98 | closesocket(new_socket); | |
99 | return -1; | |
100 | } | |
101 | ||
102 | closesocket(new_socket); | |
103 | ||
104 | F = &fd_table[handles[0]]; | |
cc192b50 | 105 | F->local_addr = handle0; |
485a0d3f | 106 | |
107 | F = &fd_table[handles[1]]; | |
cc192b50 | 108 | F->local_addr = localhost; |
109 | handle1.NtoA(F->ipaddr, MAX_IPSTRLEN); | |
110 | F->remote_port = handle1.GetPort(); | |
485a0d3f | 111 | |
112 | return 0; | |
113 | } | |
114 | ||
115 | int WIN32_getrusage(int who, struct rusage *usage) | |
116 | { | |
117 | #if HAVE_WIN32_PSAPI | |
118 | ||
119 | if ((WIN32_OS_version == _WIN_OS_WINNT) || (WIN32_OS_version == _WIN_OS_WIN2K) | |
26ac0430 | 120 | || (WIN32_OS_version == _WIN_OS_WINXP) || (WIN32_OS_version == _WIN_OS_WINNET)) { |
485a0d3f | 121 | /* On Windows NT/2000 call PSAPI.DLL for process Memory */ |
122 | /* informations -- Guido Serassio */ | |
123 | HANDLE hProcess; | |
124 | PROCESS_MEMORY_COUNTERS pmc; | |
125 | hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | | |
126 | PROCESS_VM_READ, | |
127 | FALSE, GetCurrentProcessId()); | |
128 | { | |
129 | /* Microsoft CRT doesn't have getrusage function, */ | |
130 | /* so we get process CPU time information from PSAPI.DLL. */ | |
131 | FILETIME ftCreate, ftExit, ftKernel, ftUser; | |
132 | ||
133 | if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) { | |
26ac0430 | 134 | int64_t *ptUser = (int64_t *)&ftUser; |
07468826 | 135 | int64_t tUser64 = *ptUser / 10; |
26ac0430 | 136 | int64_t *ptKernel = (int64_t *)&ftKernel; |
07468826 | 137 | int64_t tKernel64 = *ptKernel / 10; |
485a0d3f | 138 | usage->ru_utime.tv_sec =(long)(tUser64 / 1000000); |
139 | usage->ru_stime.tv_sec =(long)(tKernel64 / 1000000); | |
140 | usage->ru_utime.tv_usec =(long)(tUser64 % 1000000); | |
141 | usage->ru_stime.tv_usec =(long)(tKernel64 % 1000000); | |
142 | } else { | |
143 | CloseHandle( hProcess ); | |
144 | return -1; | |
145 | } | |
146 | } | |
147 | ||
148 | if (GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc))) { | |
149 | usage->ru_maxrss=(DWORD)(pmc.WorkingSetSize / getpagesize()); | |
150 | usage->ru_majflt=pmc.PageFaultCount; | |
151 | } else { | |
152 | CloseHandle( hProcess ); | |
153 | return -1; | |
154 | } | |
155 | ||
156 | CloseHandle( hProcess ); | |
157 | } | |
158 | ||
159 | #endif | |
160 | return 0; | |
161 | } | |
162 | ||
11871e3c | 163 | |
485a0d3f | 164 | int Win32__WSAFDIsSet(int fd, fd_set FAR * set |
26ac0430 | 165 | ) |
485a0d3f | 166 | { |
167 | fde *F = &fd_table[fd]; | |
168 | SOCKET s = F->win32.handle; | |
169 | ||
cc192b50 | 170 | return __WSAFDIsSet(s, set); |
485a0d3f | 171 | } |
172 | ||
06648839 | 173 | LONG CALLBACK WIN32_ExceptionHandler(EXCEPTION_POINTERS* ep) |
174 | { | |
175 | EXCEPTION_RECORD* er; | |
176 | ||
177 | er = ep->ExceptionRecord; | |
178 | ||
179 | switch (er->ExceptionCode) { | |
180 | ||
181 | case EXCEPTION_ACCESS_VIOLATION: | |
182 | raise(SIGSEGV); | |
183 | break; | |
184 | ||
185 | case EXCEPTION_DATATYPE_MISALIGNMENT: | |
186 | ||
187 | case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: | |
188 | ||
189 | case EXCEPTION_IN_PAGE_ERROR: | |
190 | death(SIGBUS); | |
191 | break; | |
192 | ||
193 | default: | |
194 | break; | |
195 | } | |
196 | ||
197 | return EXCEPTION_CONTINUE_SEARCH; | |
198 | } | |
199 | ||
200 | ||
201 | void WIN32_ExceptionHandlerInit() | |
202 | { | |
203 | #if !defined(_DEBUG) | |
204 | ||
205 | if (Win32_Old_ExceptionHandler == NULL) | |
206 | Win32_Old_ExceptionHandler = SetUnhandledExceptionFilter(WIN32_ExceptionHandler); | |
207 | ||
208 | #endif | |
209 | } | |
210 | ||
211 | void WIN32_ExceptionHandlerCleanup() | |
212 | { | |
213 | if (Win32_Old_ExceptionHandler != NULL) | |
214 | SetUnhandledExceptionFilter(Win32_Old_ExceptionHandler); | |
215 | } | |
216 | ||
228bb3a9 | 217 | #endif /* SQUID_MSWIN_ */ |