2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * Inspired by previous work by Romeo Anghelache & Eric Stern. */
14 // The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port.
15 // Compiles only on MS Visual C++ or MinGW
16 // CygWin appears not to need any of these
17 #if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
19 #define sys_nerr _sys_nerr
25 #include <sys/timeb.h>
33 THREADLOCAL
int ws32_result
;
34 LPCRITICAL_SECTION dbg_mutex
= NULL
;
36 void GetProcessName(pid_t
, char *);
38 #if HAVE_GETPAGESIZE > 1
42 static DWORD system_pagesize
= 0;
43 if (!system_pagesize
) {
44 SYSTEM_INFO system_info
;
45 GetSystemInfo(&system_info
);
46 system_pagesize
= system_info
.dwPageSize
;
48 return system_pagesize
;
50 #endif /* HAVE_GETPAGESIZE > 1 */
53 chroot(const char *dirname
)
55 if (SetCurrentDirectory(dirname
))
58 return GetLastError();
62 GetProcessName(pid_t pid
, char *ProcessName
)
64 strcpy(ProcessName
, "unknown");
66 /* Get a handle to the process. */
67 HANDLE hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
);
68 /* Get the process name. */
69 if (NULL
!= hProcess
) {
73 if (EnumProcessModules(hProcess
, &hMod
, sizeof(hMod
), &cbNeeded
))
74 GetModuleBaseName(hProcess
, hMod
, ProcessName
, sizeof(ProcessName
));
76 CloseHandle(hProcess
);
81 CloseHandle(hProcess
);
82 #endif /* HAVE_WIN32_PSAPI */
86 kill(pid_t pid
, int sig
)
89 char MyProcessName
[MAX_PATH
];
90 char ProcessNameToCheck
[MAX_PATH
];
93 if ((hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
|
98 CloseHandle(hProcess
);
99 GetProcessName(getpid(), MyProcessName
);
100 GetProcessName(pid
, ProcessNameToCheck
);
101 if (strcmp(MyProcessName
, ProcessNameToCheck
) == 0)
109 #if !HAVE_GETTIMEOFDAY
111 gettimeofday(struct timeval
*pcur_time
, void *tzp
)
113 struct _timeb current
;
114 struct timezone
*tz
= (struct timezone
*) tzp
;
118 pcur_time
->tv_sec
= current
.time
;
119 pcur_time
->tv_usec
= current
.millitm
* 1000L;
121 tz
->tz_minuteswest
= current
.timezone
; /* minutes west of Greenwich */
122 tz
->tz_dsttime
= current
.dstflag
; /* type of dst correction */
126 #endif /* !HAVE_GETTIMEOFDAY */
130 WIN32_ftruncate(int fd
, off_t size
)
138 hfile
= (HANDLE
) _get_osfhandle(fd
);
139 curpos
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
140 if (curpos
== 0xFFFFFFFF
141 || SetFilePointer(hfile
, size
, NULL
, FILE_BEGIN
) == 0xFFFFFFFF
142 || !SetEndOfFile(hfile
)) {
143 int error
= GetLastError();
146 case ERROR_INVALID_HANDLE
:
160 WIN32_truncate(const char *pathname
, off_t length
)
165 fd
= open(pathname
, O_RDWR
);
170 res
= WIN32_ftruncate(fd
, length
);
176 #endif /* !_SQUID_MINGW_ */
179 getpwnam(char *unused
) {
180 static struct passwd pwd
= {NULL
, NULL
, 100, 100, NULL
, NULL
, NULL
};
185 getgrnam(char *unused
) {
186 static struct group grp
= {NULL
, NULL
, 100, NULL
};
192 _free_osfhnd(int filehandle
)
194 if (((unsigned) filehandle
< SQUID_MAXFD
) &&
195 (_osfile(filehandle
) & FOPEN
) &&
196 (_osfhnd(filehandle
) != (long) INVALID_HANDLE_VALUE
)) {
197 switch (filehandle
) {
199 SetStdHandle(STD_INPUT_HANDLE
, NULL
);
202 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
205 SetStdHandle(STD_ERROR_HANDLE
, NULL
);
208 _osfhnd(filehandle
) = (long) INVALID_HANDLE_VALUE
;
211 errno
= EBADF
; /* bad handle */
212 _doserrno
= 0L; /* not an OS error */
216 #endif /* _SQUID_MINGW_ */
219 unsigned long WIN32_code
;
223 static struct errorentry errortable
[] = {
224 {ERROR_INVALID_FUNCTION
, EINVAL
},
225 {ERROR_FILE_NOT_FOUND
, ENOENT
},
226 {ERROR_PATH_NOT_FOUND
, ENOENT
},
227 {ERROR_TOO_MANY_OPEN_FILES
, EMFILE
},
228 {ERROR_ACCESS_DENIED
, EACCES
},
229 {ERROR_INVALID_HANDLE
, EBADF
},
230 {ERROR_ARENA_TRASHED
, ENOMEM
},
231 {ERROR_NOT_ENOUGH_MEMORY
, ENOMEM
},
232 {ERROR_INVALID_BLOCK
, ENOMEM
},
233 {ERROR_BAD_ENVIRONMENT
, E2BIG
},
234 {ERROR_BAD_FORMAT
, ENOEXEC
},
235 {ERROR_INVALID_ACCESS
, EINVAL
},
236 {ERROR_INVALID_DATA
, EINVAL
},
237 {ERROR_INVALID_DRIVE
, ENOENT
},
238 {ERROR_CURRENT_DIRECTORY
, EACCES
},
239 {ERROR_NOT_SAME_DEVICE
, EXDEV
},
240 {ERROR_NO_MORE_FILES
, ENOENT
},
241 {ERROR_LOCK_VIOLATION
, EACCES
},
242 {ERROR_BAD_NETPATH
, ENOENT
},
243 {ERROR_NETWORK_ACCESS_DENIED
, EACCES
},
244 {ERROR_BAD_NET_NAME
, ENOENT
},
245 {ERROR_FILE_EXISTS
, EEXIST
},
246 {ERROR_CANNOT_MAKE
, EACCES
},
247 {ERROR_FAIL_I24
, EACCES
},
248 {ERROR_INVALID_PARAMETER
, EINVAL
},
249 {ERROR_NO_PROC_SLOTS
, EAGAIN
},
250 {ERROR_DRIVE_LOCKED
, EACCES
},
251 {ERROR_BROKEN_PIPE
, EPIPE
},
252 {ERROR_DISK_FULL
, ENOSPC
},
253 {ERROR_INVALID_TARGET_HANDLE
, EBADF
},
254 {ERROR_INVALID_HANDLE
, EINVAL
},
255 {ERROR_WAIT_NO_CHILDREN
, ECHILD
},
256 {ERROR_CHILD_NOT_COMPLETE
, ECHILD
},
257 {ERROR_DIRECT_ACCESS_HANDLE
, EBADF
},
258 {ERROR_NEGATIVE_SEEK
, EINVAL
},
259 {ERROR_SEEK_ON_DEVICE
, EACCES
},
260 {ERROR_DIR_NOT_EMPTY
, ENOTEMPTY
},
261 {ERROR_NOT_LOCKED
, EACCES
},
262 {ERROR_BAD_PATHNAME
, ENOENT
},
263 {ERROR_MAX_THRDS_REACHED
, EAGAIN
},
264 {ERROR_LOCK_FAILED
, EACCES
},
265 {ERROR_ALREADY_EXISTS
, EEXIST
},
266 {ERROR_FILENAME_EXCED_RANGE
, ENOENT
},
267 {ERROR_NESTING_NOT_ALLOWED
, EAGAIN
},
268 {ERROR_NOT_ENOUGH_QUOTA
, ENOMEM
}
271 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
272 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
274 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
275 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
278 WIN32_maperror(unsigned long WIN32_oserrno
)
280 _doserrno
= WIN32_oserrno
;
281 for (size_t i
= 0; i
< (sizeof(errortable
) / sizeof(struct errorentry
)); ++i
) {
282 if (WIN32_oserrno
== errortable
[i
].WIN32_code
) {
283 errno
= errortable
[i
].POSIX_errno
;
287 if (WIN32_oserrno
>= MIN_EACCES_RANGE
&& WIN32_oserrno
<= MAX_EACCES_RANGE
)
289 else if (WIN32_oserrno
>= MIN_EXEC_ERROR
&& WIN32_oserrno
<= MAX_EXEC_ERROR
)
295 /* syslog emulation layer derived from git */
296 static HANDLE ms_eventlog
;
299 openlog(const char *ident
, int logopt
, int facility
)
304 ms_eventlog
= RegisterEventSourceA(NULL
, ident
);
306 // note: RegisterEventAtSourceA may fail and return NULL.
307 // in that case we'll just retry at the next message or not log
309 #define SYSLOG_MAX_MSG_SIZE 1024
312 syslog(int priority
, const char *fmt
, ...)
315 char *str
=static_cast<char *>(xmalloc(SYSLOG_MAX_MSG_SIZE
));
323 str_len
= vsnprintf(str
, SYSLOG_MAX_MSG_SIZE
-1, fmt
, ap
);
327 /* vsnprintf failed */
336 logtype
= EVENTLOG_ERROR_TYPE
;
340 logtype
= EVENTLOG_WARNING_TYPE
;
347 logtype
= EVENTLOG_INFORMATION_TYPE
;
351 //Windows API suck. They are overengineered
352 ReportEventA(ms_eventlog
, logtype
, 0, 0, NULL
, 1, 0,
353 const_cast<const char **>(&str
), NULL
);
356 /* note: this is all MSWindows-specific code; all of it should be conditional */
357 #endif /* _SQUID_WINDOWS_ */