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 * AUTHOR: Guido Serassio <serassio@squid-cache.org>
11 * Inspired by previous work by Romeo Anghelache & Eric Stern. */
15 // The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port.
16 // Compiles only on MS Visual C++ or MinGW
17 // CygWin appears not to need any of these
18 #if _SQUID_WINDOWS_ && !_SQUID_CYGWIN_
20 #define sys_nerr _sys_nerr
26 #include <sys/timeb.h>
34 THREADLOCAL
int ws32_result
;
35 LPCRITICAL_SECTION dbg_mutex
= NULL
;
37 void GetProcessName(pid_t
, char *);
39 #if HAVE_GETPAGESIZE > 1
43 static DWORD system_pagesize
= 0;
44 if (!system_pagesize
) {
45 SYSTEM_INFO system_info
;
46 GetSystemInfo(&system_info
);
47 system_pagesize
= system_info
.dwPageSize
;
49 return system_pagesize
;
51 #endif /* HAVE_GETPAGESIZE > 1 */
54 chroot(const char *dirname
)
56 if (SetCurrentDirectory(dirname
))
59 return GetLastError();
63 GetProcessName(pid_t pid
, char *ProcessName
)
65 strcpy(ProcessName
, "unknown");
67 /* Get a handle to the process. */
68 HANDLE hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
| PROCESS_VM_READ
, FALSE
, pid
);
69 /* Get the process name. */
70 if (NULL
!= hProcess
) {
74 if (EnumProcessModules(hProcess
, &hMod
, sizeof(hMod
), &cbNeeded
))
75 GetModuleBaseName(hProcess
, hMod
, ProcessName
, sizeof(ProcessName
));
77 CloseHandle(hProcess
);
82 CloseHandle(hProcess
);
83 #endif /* HAVE_WIN32_PSAPI */
87 kill(pid_t pid
, int sig
)
90 char MyProcessName
[MAX_PATH
];
91 char ProcessNameToCheck
[MAX_PATH
];
94 if ((hProcess
= OpenProcess(PROCESS_QUERY_INFORMATION
|
99 CloseHandle(hProcess
);
100 GetProcessName(getpid(), MyProcessName
);
101 GetProcessName(pid
, ProcessNameToCheck
);
102 if (strcmp(MyProcessName
, ProcessNameToCheck
) == 0)
110 #if !HAVE_GETTIMEOFDAY
112 gettimeofday(struct timeval
*pcur_time
, void *tzp
)
114 struct _timeb current
;
115 struct timezone
*tz
= (struct timezone
*) tzp
;
119 pcur_time
->tv_sec
= current
.time
;
120 pcur_time
->tv_usec
= current
.millitm
* 1000L;
122 tz
->tz_minuteswest
= current
.timezone
; /* minutes west of Greenwich */
123 tz
->tz_dsttime
= current
.dstflag
; /* type of dst correction */
127 #endif /* !HAVE_GETTIMEOFDAY */
131 statfs(const char *path
, struct statfs
*sfs
)
134 DWORD spc
, bps
, freec
, totalc
;
135 DWORD vsn
, maxlen
, flags
;
141 strncpy(drive
, path
, 2);
145 if (!GetDiskFreeSpace(drive
, &spc
, &bps
, &freec
, &totalc
)) {
149 if (!GetVolumeInformation(drive
, NULL
, 0, &vsn
, &maxlen
, &flags
, NULL
, 0)) {
154 sfs
->f_bsize
= spc
* bps
;
155 sfs
->f_blocks
= totalc
;
156 sfs
->f_bfree
= sfs
->f_bavail
= freec
;
160 sfs
->f_namelen
= maxlen
;
167 WIN32_ftruncate(int fd
, off_t size
)
175 hfile
= (HANDLE
) _get_osfhandle(fd
);
176 curpos
= SetFilePointer(hfile
, 0, NULL
, FILE_CURRENT
);
177 if (curpos
== 0xFFFFFFFF
178 || SetFilePointer(hfile
, size
, NULL
, FILE_BEGIN
) == 0xFFFFFFFF
179 || !SetEndOfFile(hfile
)) {
180 int error
= GetLastError();
183 case ERROR_INVALID_HANDLE
:
197 WIN32_truncate(const char *pathname
, off_t length
)
202 fd
= open(pathname
, O_RDWR
);
207 res
= WIN32_ftruncate(fd
, length
);
213 #endif /* !_SQUID_MINGW_ */
216 getpwnam(char *unused
) {
217 static struct passwd pwd
= {NULL
, NULL
, 100, 100, NULL
, NULL
, NULL
};
222 getgrnam(char *unused
) {
223 static struct group grp
= {NULL
, NULL
, 100, NULL
};
229 _free_osfhnd(int filehandle
)
231 if (((unsigned) filehandle
< SQUID_MAXFD
) &&
232 (_osfile(filehandle
) & FOPEN
) &&
233 (_osfhnd(filehandle
) != (long) INVALID_HANDLE_VALUE
)) {
234 switch (filehandle
) {
236 SetStdHandle(STD_INPUT_HANDLE
, NULL
);
239 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
242 SetStdHandle(STD_ERROR_HANDLE
, NULL
);
245 _osfhnd(filehandle
) = (long) INVALID_HANDLE_VALUE
;
248 errno
= EBADF
; /* bad handle */
249 _doserrno
= 0L; /* not an OS error */
253 #endif /* _SQUID_MINGW_ */
256 unsigned long WIN32_code
;
260 static struct errorentry errortable
[] = {
261 {ERROR_INVALID_FUNCTION
, EINVAL
},
262 {ERROR_FILE_NOT_FOUND
, ENOENT
},
263 {ERROR_PATH_NOT_FOUND
, ENOENT
},
264 {ERROR_TOO_MANY_OPEN_FILES
, EMFILE
},
265 {ERROR_ACCESS_DENIED
, EACCES
},
266 {ERROR_INVALID_HANDLE
, EBADF
},
267 {ERROR_ARENA_TRASHED
, ENOMEM
},
268 {ERROR_NOT_ENOUGH_MEMORY
, ENOMEM
},
269 {ERROR_INVALID_BLOCK
, ENOMEM
},
270 {ERROR_BAD_ENVIRONMENT
, E2BIG
},
271 {ERROR_BAD_FORMAT
, ENOEXEC
},
272 {ERROR_INVALID_ACCESS
, EINVAL
},
273 {ERROR_INVALID_DATA
, EINVAL
},
274 {ERROR_INVALID_DRIVE
, ENOENT
},
275 {ERROR_CURRENT_DIRECTORY
, EACCES
},
276 {ERROR_NOT_SAME_DEVICE
, EXDEV
},
277 {ERROR_NO_MORE_FILES
, ENOENT
},
278 {ERROR_LOCK_VIOLATION
, EACCES
},
279 {ERROR_BAD_NETPATH
, ENOENT
},
280 {ERROR_NETWORK_ACCESS_DENIED
, EACCES
},
281 {ERROR_BAD_NET_NAME
, ENOENT
},
282 {ERROR_FILE_EXISTS
, EEXIST
},
283 {ERROR_CANNOT_MAKE
, EACCES
},
284 {ERROR_FAIL_I24
, EACCES
},
285 {ERROR_INVALID_PARAMETER
, EINVAL
},
286 {ERROR_NO_PROC_SLOTS
, EAGAIN
},
287 {ERROR_DRIVE_LOCKED
, EACCES
},
288 {ERROR_BROKEN_PIPE
, EPIPE
},
289 {ERROR_DISK_FULL
, ENOSPC
},
290 {ERROR_INVALID_TARGET_HANDLE
, EBADF
},
291 {ERROR_INVALID_HANDLE
, EINVAL
},
292 {ERROR_WAIT_NO_CHILDREN
, ECHILD
},
293 {ERROR_CHILD_NOT_COMPLETE
, ECHILD
},
294 {ERROR_DIRECT_ACCESS_HANDLE
, EBADF
},
295 {ERROR_NEGATIVE_SEEK
, EINVAL
},
296 {ERROR_SEEK_ON_DEVICE
, EACCES
},
297 {ERROR_DIR_NOT_EMPTY
, ENOTEMPTY
},
298 {ERROR_NOT_LOCKED
, EACCES
},
299 {ERROR_BAD_PATHNAME
, ENOENT
},
300 {ERROR_MAX_THRDS_REACHED
, EAGAIN
},
301 {ERROR_LOCK_FAILED
, EACCES
},
302 {ERROR_ALREADY_EXISTS
, EEXIST
},
303 {ERROR_FILENAME_EXCED_RANGE
, ENOENT
},
304 {ERROR_NESTING_NOT_ALLOWED
, EAGAIN
},
305 {ERROR_NOT_ENOUGH_QUOTA
, ENOMEM
}
308 #define MIN_EXEC_ERROR ERROR_INVALID_STARTING_CODESEG
309 #define MAX_EXEC_ERROR ERROR_INFLOOP_IN_RELOC_CHAIN
311 #define MIN_EACCES_RANGE ERROR_WRITE_PROTECT
312 #define MAX_EACCES_RANGE ERROR_SHARING_BUFFER_EXCEEDED
315 WIN32_maperror(unsigned long WIN32_oserrno
)
317 _doserrno
= WIN32_oserrno
;
318 for (size_t i
= 0; i
< (sizeof(errortable
) / sizeof(struct errorentry
)); ++i
) {
319 if (WIN32_oserrno
== errortable
[i
].WIN32_code
) {
320 errno
= errortable
[i
].POSIX_errno
;
324 if (WIN32_oserrno
>= MIN_EACCES_RANGE
&& WIN32_oserrno
<= MAX_EACCES_RANGE
)
326 else if (WIN32_oserrno
>= MIN_EXEC_ERROR
&& WIN32_oserrno
<= MAX_EXEC_ERROR
)
332 /* syslog emulation layer derived from git */
333 static HANDLE ms_eventlog
;
336 openlog(const char *ident
, int logopt
, int facility
)
341 ms_eventlog
= RegisterEventSourceA(NULL
, ident
);
343 // note: RegisterEventAtSourceA may fail and return NULL.
344 // in that case we'll just retry at the next message or not log
346 #define SYSLOG_MAX_MSG_SIZE 1024
349 syslog(int priority
, const char *fmt
, ...)
352 char *str
=static_cast<char *>(xmalloc(SYSLOG_MAX_MSG_SIZE
));
360 str_len
= vsnprintf(str
, SYSLOG_MAX_MSG_SIZE
-1, fmt
, ap
);
364 /* vsnprintf failed */
373 logtype
= EVENTLOG_ERROR_TYPE
;
377 logtype
= EVENTLOG_WARNING_TYPE
;
384 logtype
= EVENTLOG_INFORMATION_TYPE
;
388 //Windows API suck. They are overengineered
389 ReportEventA(ms_eventlog
, logtype
, 0, 0, NULL
, 1, 0,
390 const_cast<const char **>(&str
), NULL
);
393 /* note: this is all MSWindows-specific code; all of it should be conditional */
394 #endif /* _SQUID_WINDOWS_ */