3 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
4 * inspired by previous work by Romeo Anghelache & Eric Stern.
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
36 // The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port.
37 // Compiles only on MS Visual C++ or MinGW
38 // CygWin appears not to need any of these
39 #if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
41 #define sys_nerr _sys_nerr
48 #include <sys/timeb.h>
56 THREADLOCAL
int ws32_result
;
57 LPCRITICAL_SECTION dbg_mutex
= NULL
;
59 void GetProcessName(pid_t
, char *);
61 #if HAVE_GETPAGESIZE > 1
65 static DWORD system_pagesize
= 0;
66 if (!system_pagesize
) {
67 SYSTEM_INFO system_info
;
68 GetSystemInfo(&system_info
);
69 system_pagesize
= system_info
.dwPageSize
;
71 return system_pagesize
;
73 #endif /* HAVE_GETPAGESIZE > 1 */
76 chroot(const char *dirname
)
78 if (SetCurrentDirectory(dirname
))
81 return GetLastError();
85 GetProcessName(pid_t pid
, char *ProcessName
)
87 strcpy(ProcessName
, "unknown");
89 /* Get a handle to the process. */
90 HANDLE hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
);
91 /* Get the process name. */
92 if (NULL
!= hProcess
) {
96 if (EnumProcessModules(hProcess
, &hMod
, sizeof(hMod
), &cbNeeded
))
97 GetModuleBaseName(hProcess
, hMod
, ProcessName
, sizeof(ProcessName
));
99 CloseHandle(hProcess
);
104 CloseHandle(hProcess
);
105 #endif /* HAVE_WIN32_PSAPI */
109 kill(pid_t pid
, int sig
)
112 char MyProcessName
[MAX_PATH
];
113 char ProcessNameToCheck
[MAX_PATH
];
116 if ((hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
|
118 FALSE
, pid
)) == NULL
)
121 CloseHandle(hProcess
);
122 GetProcessName(getpid(), MyProcessName
);
123 GetProcessName(pid
, ProcessNameToCheck
);
124 if (strcmp(MyProcessName
, ProcessNameToCheck
) == 0)
132 #if !HAVE_GETTIMEOFDAY
134 gettimeofday(struct timeval
*pcur_time
, void *tzp
)
136 struct _timeb current
;
137 struct timezone
*tz
= (struct timezone
*) tzp
;
141 pcur_time
->tv_sec
= current
.time
;
142 pcur_time
->tv_usec
= current
.millitm
* 1000L;
144 tz
->tz_minuteswest
= current
.timezone
; /* minutes west of Greenwich */
145 tz
->tz_dsttime
= current
.dstflag
; /* type of dst correction */
149 #endif /* !HAVE_GETTIMEOFDAY */
153 statfs(const char *path
, struct statfs
*sfs
)
156 DWORD spc
, bps
, freec
, totalc
;
157 DWORD vsn
, maxlen
, flags
;
163 strncpy(drive
, path
, 2);
167 if (!GetDiskFreeSpace(drive
, &spc
, &bps
, &freec
, &totalc
)) {
171 if (!GetVolumeInformation(drive
, NULL
, 0, &vsn
, &maxlen
, &flags
, NULL
, 0)) {
176 sfs
->f_bsize
= spc
* bps
;
177 sfs
->f_blocks
= totalc
;
178 sfs
->f_bfree
= sfs
->f_bavail
= freec
;
182 sfs
->f_namelen
= maxlen
;
189 WIN32_ftruncate(int fd
, off_t size
)
197 hfile
= (HANDLE
) _get_osfhandle(fd
);
198 curpos
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
199 if (curpos
== 0xFFFFFFFF
200 || SetFilePointer(hfile
, size
, NULL
, FILE_BEGIN
) == 0xFFFFFFFF
201 || !SetEndOfFile(hfile
)) {
202 int error
= GetLastError();
205 case ERROR_INVALID_HANDLE
:
219 WIN32_truncate(const char *pathname
, off_t length
)
224 fd
= open(pathname
, O_RDWR
);
229 res
= WIN32_ftruncate(fd
, length
);
235 #endif /* !_SQUID_MINGW_ */
238 getpwnam(char *unused
) {
239 static struct passwd pwd
= {NULL
, NULL
, 100, 100, NULL
, NULL
, NULL
};
244 getgrnam(char *unused
) {
245 static struct group grp
= {NULL
, NULL
, 100, NULL
};
251 _free_osfhnd(int filehandle
)
253 if (((unsigned) filehandle
< SQUID_MAXFD
) &&
254 (_osfile(filehandle
) & FOPEN
) &&
255 (_osfhnd(filehandle
) != (long) INVALID_HANDLE_VALUE
)) {
256 switch (filehandle
) {
258 SetStdHandle(STD_INPUT_HANDLE
, NULL
);
261 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
264 SetStdHandle(STD_ERROR_HANDLE
, NULL
);
267 _osfhnd(filehandle
) = (long) INVALID_HANDLE_VALUE
;
270 errno
= EBADF
; /* bad handle */
271 _doserrno
= 0L; /* not an OS error */
275 #endif /* _SQUID_MINGW_ */
278 unsigned long WIN32_code
;
282 static struct errorentry errortable
[] = {
283 {ERROR_INVALID_FUNCTION
, EINVAL
},
284 {ERROR_FILE_NOT_FOUND
, ENOENT
},
285 {ERROR_PATH_NOT_FOUND
, ENOENT
},
286 {ERROR_TOO_MANY_OPEN_FILES
, EMFILE
},
287 {ERROR_ACCESS_DENIED
, EACCES
},
288 {ERROR_INVALID_HANDLE
, EBADF
},
289 {ERROR_ARENA_TRASHED
, ENOMEM
},
290 {ERROR_NOT_ENOUGH_MEMORY
, ENOMEM
},
291 {ERROR_INVALID_BLOCK
, ENOMEM
},
292 {ERROR_BAD_ENVIRONMENT
, E2BIG
},
293 {ERROR_BAD_FORMAT
, ENOEXEC
},
294 {ERROR_INVALID_ACCESS
, EINVAL
},
295 {ERROR_INVALID_DATA
, EINVAL
},
296 {ERROR_INVALID_DRIVE
, ENOENT
},
297 {ERROR_CURRENT_DIRECTORY
, EACCES
},
298 {ERROR_NOT_SAME_DEVICE
, EXDEV
},
299 {ERROR_NO_MORE_FILES
, ENOENT
},
300 {ERROR_LOCK_VIOLATION
, EACCES
},
301 {ERROR_BAD_NETPATH
, ENOENT
},
302 {ERROR_NETWORK_ACCESS_DENIED
, EACCES
},
303 {ERROR_BAD_NET_NAME
, ENOENT
},
304 {ERROR_FILE_EXISTS
, EEXIST
},
305 {ERROR_CANNOT_MAKE
, EACCES
},
306 {ERROR_FAIL_I24
, EACCES
},
307 {ERROR_INVALID_PARAMETER
, EINVAL
},
308 {ERROR_NO_PROC_SLOTS
, EAGAIN
},
309 {ERROR_DRIVE_LOCKED
, EACCES
},
310 {ERROR_BROKEN_PIPE
, EPIPE
},
311 {ERROR_DISK_FULL
, ENOSPC
},
312 {ERROR_INVALID_TARGET_HANDLE
, EBADF
},
313 {ERROR_INVALID_HANDLE
, EINVAL
},
314 {ERROR_WAIT_NO_CHILDREN
, ECHILD
},
315 {ERROR_CHILD_NOT_COMPLETE
, ECHILD
},
316 {ERROR_DIRECT_ACCESS_HANDLE
, EBADF
},
317 {ERROR_NEGATIVE_SEEK
, EINVAL
},
318 {ERROR_SEEK_ON_DEVICE
, EACCES
},
319 {ERROR_DIR_NOT_EMPTY
, ENOTEMPTY
},
320 {ERROR_NOT_LOCKED
, EACCES
},
321 {ERROR_BAD_PATHNAME
, ENOENT
},
322 {ERROR_MAX_THRDS_REACHED
, EAGAIN
},
323 {ERROR_LOCK_FAILED
, EACCES
},
324 {ERROR_ALREADY_EXISTS
, EEXIST
},
325 {ERROR_FILENAME_EXCED_RANGE
, ENOENT
},
326 {ERROR_NESTING_NOT_ALLOWED
, EAGAIN
},
327 {ERROR_NOT_ENOUGH_QUOTA
, ENOMEM
}
330 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
331 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
333 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
334 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
337 WIN32_maperror(unsigned long WIN32_oserrno
)
339 _doserrno
= WIN32_oserrno
;
340 for (size_t i
= 0; i
< (sizeof(errortable
) / sizeof(struct errorentry
)); ++i
) {
341 if (WIN32_oserrno
== errortable
[i
].WIN32_code
) {
342 errno
= errortable
[i
].POSIX_errno
;
346 if (WIN32_oserrno
>= MIN_EACCES_RANGE
&& WIN32_oserrno
<= MAX_EACCES_RANGE
)
348 else if (WIN32_oserrno
>= MIN_EXEC_ERROR
&& WIN32_oserrno
<= MAX_EXEC_ERROR
)
354 /* syslog emulation layer derived from git */
355 static HANDLE ms_eventlog
;
358 openlog(const char *ident
, int logopt
, int facility
)
363 ms_eventlog
= RegisterEventSourceA(NULL
, ident
);
365 // note: RegisterEventAtSourceA may fail and return NULL.
366 // in that case we'll just retry at the next message or not log
368 #define SYSLOG_MAX_MSG_SIZE 1024
371 syslog(int priority
, const char *fmt
, ...)
374 char *str
=static_cast<char *>(xmalloc(SYSLOG_MAX_MSG_SIZE
));
382 str_len
= vsnprintf(str
, SYSLOG_MAX_MSG_SIZE
-1, fmt
, ap
);
386 /* vsnprintf failed */
395 logtype
= EVENTLOG_ERROR_TYPE
;
399 logtype
= EVENTLOG_WARNING_TYPE
;
406 logtype
= EVENTLOG_INFORMATION_TYPE
;
410 //Windows API suck. They are overengineered
411 ReportEventA(ms_eventlog
, logtype
, 0, 0, NULL
, 1, 0,
412 const_cast<const char **>(&str
), NULL
);
415 /* note: this is all MSWindows-specific code; all of it should be conditional */
416 #endif /* _SQUID_WINDOWS_ */