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