Index: configure.in =================================================================== RCS file: /squid/squid/configure.in,v retrieving revision 1.393 diff -u -p -r1.393 configure.in --- configure.in 19 Aug 2006 12:40:31 -0000 1.393 +++ configure.in 2 Sep 2006 21:32:22 -0000 @@ -58,6 +58,24 @@ mingw|mingw32|cygwin|cygwin32) ;; esac +case "$host_os" in +mingw|mingw32) + AM_CONDITIONAL(ENABLE_MINGW32SPECIFIC, true) + AC_PATH_PROG(WIN32_PSAPI, psapi.dll, none) + CFLAGS="$CFLAGS -mthreads" + if test "$ac_cv_path_WIN32_PSAPI" = "none"; then + echo "PSAPI.DLL is recommended to run Squid on Windows Platform" + echo "Please see PSAPI.DLL section on doc/release-notes/release-2.6.html." + else + AC_DEFINE(HAVE_WIN32_PSAPI,1,[Define if you have PSAPI.DLL on Windows systems]) + LIBS="$LIBS -lpsapi" + fi + ;; +*) + AM_CONDITIONAL(ENABLE_MINGW32SPECIFIC, false) + ;; +esac + if test -z "$CACHE_HTTP_PORT"; then CACHE_HTTP_PORT="3128" fi @@ -1740,21 +1758,30 @@ if test $ac_cv_have_ext_mallinfo = "yes" AC_DEFINE(HAVE_EXT_MALLINFO, 1, [Define if struct mallinfo has mxfast member]) fi -AC_CACHE_CHECK(for struct rusage,ac_cv_have_struct_rusage, [ - AC_TRY_COMPILE([ +case "$host_os" in + mingw|mingw32) + AC_DEFINE(HAVE_STRUCT_RUSAGE) + ac_cv_func_getrusage='yes' + echo "Using own rusage on Windows." + ;; + *) + AC_CACHE_CHECK(for struct rusage,ac_cv_have_struct_rusage, [ + AC_TRY_COMPILE([ #if HAVE_SYS_TIME_H #include #endif #if HAVE_SYS_RESOURCE_H #include #endif], - [struct rusage R;], - ac_cv_have_struct_rusage="yes", - ac_cv_have_struct_rusage="no") + [struct rusage R;], + ac_cv_have_struct_rusage="yes", + ac_cv_have_struct_rusage="no") ]) -if test $ac_cv_have_struct_rusage = "yes" ; then - AC_DEFINE(HAVE_STRUCT_RUSAGE, 1, [Define if you have struct rusage]) -fi + if test $ac_cv_have_struct_rusage = "yes" ; then + AC_DEFINE(HAVE_STRUCT_RUSAGE, 1, [Define if you have struct rusage]) + fi + ;; +esac AC_CACHE_CHECK(for ip->ip_hl, ac_cv_have_ip_hl, [ AC_TRY_COMPILE([#include @@ -2228,6 +2255,13 @@ if test -z "$ac_cv_func_poll"; then esac fi +dnl Override statfs detect on MinGW becasue is emulated in source code +case "$host_os" in +mingw|mingw32) + ac_cv_func_statfs='yes' + ;; +esac + dnl Check for library functions AC_CHECK_FUNCS(\ bcopy \ @@ -2712,6 +2746,12 @@ main() { SQUID_MAXFD=`cat conftestval`, SQUID_MAXFD=256, SQUID_MAXFD=256) +dnl Microsoft MSVCRT.DLL supports 2048 maximum FDs +case "$host_os" in +mingw|mingw32) + SQUID_MAXFD="2048" + ;; +esac AC_MSG_RESULT($SQUID_MAXFD) fi # --with-maxfd SQUID_MAXFD AC_DEFINE_UNQUOTED(SQUID_MAXFD, $SQUID_MAXFD, [Maximum number of open filedescriptors]) Index: doc/release-notes/release-2.6.html =================================================================== RCS file: /squid/squid/doc/release-notes/release-2.6.html,v retrieving revision 1.30 diff -u -p -r1.30 release-2.6.html --- doc/release-notes/release-2.6.html 28 Aug 2006 11:43:06 -0000 1.30 +++ doc/release-notes/release-2.6.html 2 Sep 2006 21:32:23 -0000 @@ -261,6 +261,24 @@ squid -O "-D -u 3130" -n squidsvc

+
PSAPI.DLL (Process Status Helper) Considerations

The process status helper functions make it easier for you to obtain information about +processes and device drivers running on Microsoft® Windows NT®/Windows® 2000. These +functions are available in PSAPI.DLL, which is distributed in the Microsoft® Platform +Software Development Kit (SDK). The same information is generally available through the +performance data in the registry, but it is more difficult to get to it. PSAPI.DLL is +freely redistributable.

+

PSAPI.DLL is available only on Windows NT, 2000, XP and .NET. The implementation in Squid is +aware of this, and try to use it only on the rigth platform.

+

On Windows NT PSAPI.DLL can be found as component of many applications, if you need it, +you can find it on Windows NT Resource KIT. If you have problem, it can be +downloaded from here: +http://download.microsoft.com/download/platformsdk/Redist/4.0.1371.1/NT4/EN-US/psinst.EXE

+

On Windows 2000 and later it is available installing the Windows Support Tools, located on the +Support\Tools folder of the installation Windows CD-ROM.

+
+

+

+

Registry DNS lookup

On Windows platforms, if no value is specified in the dns_nameservers option on squid.conf or in the /etc/resolv.conf file, the list of DNS name servers are taken from the Windows registry, both static and dynamic DHCP configurations @@ -309,6 +327,7 @@ redirect_program c:/winnt/system32/cmd.e

  • Some code sections can make blocking calls.
  • Some external helpers may not work.
  • +
  • File Descriptors number hard-limited to 2048 when building with MinGW.
  • Index: doc/release-notes/release-2.6.sgml =================================================================== RCS file: /squid/squid/doc/release-notes/release-2.6.sgml,v retrieving revision 1.34 diff -u -p -r1.34 release-2.6.sgml --- doc/release-notes/release-2.6.sgml 28 Aug 2006 11:43:06 -0000 1.34 +++ doc/release-notes/release-2.6.sgml 2 Sep 2006 21:32:23 -0000 @@ -217,6 +217,28 @@ In the following example the command lin +PSAPI.DLL (Process Status Helper) Considerations + +The process status helper functions make it easier for you to obtain information about +processes and device drivers running on Microsoft® Windows NT®/Windows® 2000. These +functions are available in PSAPI.DLL, which is distributed in the Microsoft® Platform +Software Development Kit (SDK). The same information is generally available through the +performance data in the registry, but it is more difficult to get to it. PSAPI.DLL is +freely redistributable. + +PSAPI.DLL is available only on Windows NT, 2000, XP and .NET. The implementation in Squid is +aware of this, and try to use it only on the rigth platform. + +On Windows NT PSAPI.DLL can be found as component of many applications, if you need it, +you can find it on Windows NT Resource KIT. If you have problem, it can be +downloaded from here: + + +On Windows 2000 and later it is available installing the Windows Support Tools, located on the +Support\Tools folder of the installation Windows CD-ROM. + + + Registry DNS lookup On Windows platforms, if no value is specified in the Some code sections can make blocking calls. Some external helpers may not work. +File Descriptors number hard-limited to 2048 when building on MinGW. Index: include/config.h =================================================================== RCS file: /squid/squid/include/config.h,v retrieving revision 1.13 diff -u -p -r1.13 config.h --- include/config.h 1 Sep 2006 13:29:17 -0000 1.13 +++ include/config.h 2 Sep 2006 21:32:23 -0000 @@ -121,6 +121,7 @@ #elif defined(WIN32) || defined(WINNT) || defined(__WIN32__) || defined(__WIN32) #define _SQUID_MSWIN_ #define _SQUID_WIN32_ +#include "squid_mswin.h" #elif defined(__APPLE__) #define _SQUID_APPLE_ Index: include/util.h =================================================================== RCS file: /squid/squid/include/util.h,v retrieving revision 1.65 diff -u -p -r1.65 util.h --- include/util.h 12 May 2006 22:06:51 -0000 1.65 +++ include/util.h 2 Sep 2006 21:32:23 -0000 @@ -59,7 +59,6 @@ extern char *uudecode(const char *); extern char *xstrdup(const char *); extern char *xstrndup(const char *, size_t); extern const char *xstrerror(void); -extern const char *xbstrerror(int); extern int tvSubMsec(struct timeval, struct timeval); extern int tvSubUsec(struct timeval, struct timeval); extern double tvSubDsec(struct timeval, struct timeval); @@ -123,4 +122,33 @@ double drand48(void); */ int statMemoryAccounted(void); +/* CygWin & Windows NT Port */ +/* win32lib.c */ +#ifdef _SQUID_MSWIN_ +#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */ +extern int64_t WIN32_strtoll(const char *nptr, char **endptr, int base); +#endif +extern int chroot (const char *); +extern int ftruncate(int, off_t); +extern int gettimeofday(struct timeval *, struct timezone *); +extern int inet_aton(const char *, struct in_addr *); +extern int kill(pid_t, int); +extern int statfs(const char *, struct statfs *); +extern int truncate(const char *, off_t); +extern const char * wsastrerror(int); +extern struct passwd *getpwnam(char *); +extern struct group *getgrnam(char *); +extern uid_t geteuid(void); +extern uid_t getuid(void); +extern int setuid(uid_t); +extern int seteuid(uid_t); +extern gid_t getgid(void); +extern gid_t getegid(void); +extern int setgid(gid_t); +extern int setegid(gid_t); +extern const char *WIN32_strerror(int); +extern void WIN32_maperror(unsigned long); +extern int WIN32_Close_FD_Socket (int); +#endif + #endif /* SQUID_UTIL_H */ Index: lib/Makefile.am =================================================================== RCS file: /squid/squid/lib/Makefile.am,v retrieving revision 1.8 diff -u -p -r1.8 Makefile.am --- lib/Makefile.am 27 May 2006 08:58:31 -0000 1.8 +++ lib/Makefile.am 2 Sep 2006 21:32:23 -0000 @@ -24,6 +24,12 @@ else LIBSSPWIN32= endif +if ENABLE_MINGW32SPECIFIC +WIN32SRC = win32lib.c +else +WIN32SRC= +endif + EXTRA_LIBRARIES = \ libdlmalloc.a \ libregex.a \ @@ -37,7 +43,8 @@ noinst_LIBRARIES = \ EXTRA_libmiscutil_a_SOURCES = \ md5.c \ snprintf.c \ - strsep.c + strsep.c \ + win32lib.c libmiscutil_a_SOURCES = \ Array.c \ base64.c \ @@ -59,7 +66,8 @@ libmiscutil_a_SOURCES = \ $(STRSEPSOURCE) \ stub_memaccount.c \ util.c \ - uudecode.c + uudecode.c \ + $(WIN32SRC) libmiscutil_a_LIBADD = \ @LIBOBJS@ # $(top_srcdir)/include/version.h should be a dependency Index: lib/util.c =================================================================== RCS file: /squid/squid/lib/util.c,v retrieving revision 1.92 diff -u -p -r1.92 util.c --- lib/util.c 26 Jun 2006 15:01:59 -0000 1.92 +++ lib/util.c 2 Sep 2006 21:32:23 -0000 @@ -33,6 +33,8 @@ * */ +#ifndef UTIL_C +#define UTIL_C #define _etext etext #include "config.h" @@ -739,3 +741,4 @@ default_failure_notify(const char *messa write(2, "\n", 1); abort(); } +#endif /* UTIL_C */ Index: src/Makefile.am =================================================================== RCS file: /squid/squid/src/Makefile.am,v retrieving revision 1.54 diff -u -p -r1.54 Makefile.am --- src/Makefile.am 2 Sep 2006 14:08:42 -0000 1.54 +++ src/Makefile.am 2 Sep 2006 21:32:23 -0000 @@ -62,6 +62,14 @@ else WIN32SOURCE = endif +if ENABLE_MINGW32SPECIFIC +MINGWEXLIB = -lmingwex +IPC_SOURCE = ipc_win32.c +else +MINGWEXLIB = +IPC_SOURCE = ipc.c +endif + if USE_POLL COMMLOOP_SOURCE = comm_poll.c endif @@ -121,6 +129,7 @@ EXTRA_squid_SOURCES = \ comm_select_win32.c \ comm_kqueue.c \ comm_generic.c \ + ipc_win32.c \ win32.c squid_SOURCES = \ @@ -172,7 +181,7 @@ squid_SOURCES = \ icp_v3.c \ ident.c \ internal.c \ - ipc.c \ + $(IPC_SOURCE) \ ipcache.c \ $(LEAKFINDERSOURCE) \ locrewrite.c \ @@ -250,7 +259,8 @@ squid_LDADD = \ @SSLLIB@ \ @LIB_EPOLL@ \ -lmiscutil \ - @XTRA_LIBS@ + @XTRA_LIBS@ \ + $(MINGWEXLIB) unlinkd_SOURCES = unlinkd_LDADD = unlinkd-daemon.o Index: src/cf.data.pre =================================================================== RCS file: /squid/squid/src/cf.data.pre,v retrieving revision 1.366 diff -u -p -r1.366 cf.data.pre --- src/cf.data.pre 2 Sep 2006 14:08:42 -0000 1.366 +++ src/cf.data.pre 2 Sep 2006 21:32:24 -0000 @@ -5042,6 +5042,8 @@ DOC_START processes, these sleep delays will add up and your Squid will not service requests for some amount of time until all the child processes have been started. + On Windows value less then 1000 (1 milliseconds) are + rounded to 1000. DOC_END NAME: minimum_expiry_time Index: src/comm.c =================================================================== RCS file: /squid/squid/src/comm.c,v retrieving revision 1.355 diff -u -p -r1.355 comm.c --- src/comm.c 12 Aug 2006 23:27:20 -0000 1.355 +++ src/comm.c 2 Sep 2006 21:32:24 -0000 @@ -33,6 +33,8 @@ * */ +#ifndef COMM_C +#define COMM_C #include "squid.h" #if defined(_SQUID_CYGWIN_) @@ -1181,3 +1183,4 @@ commCloseAllSockets(void) } } } +#endif /* COMM_C */ Index: src/debug.c =================================================================== RCS file: /squid/squid/src/debug.c,v retrieving revision 1.91 diff -u -p -r1.91 debug.c --- src/debug.c 2 Sep 2006 14:16:10 -0000 1.91 +++ src/debug.c 2 Sep 2006 21:32:24 -0000 @@ -48,6 +48,10 @@ static void _db_print_syslog(const char static void _db_print_stderr(const char *format, va_list args); static void _db_print_file(const char *format, va_list args); +#ifdef _SQUID_MSWIN_ +extern LPCRITICAL_SECTION dbg_mutex; +#endif + #ifdef _SQUID_LINUX_ /* Workaround for crappy glic header files */ extern int backtrace(void *, int); @@ -74,6 +78,33 @@ _db_print(va_alist) #define args2 args1 #define args3 args1 #endif +#ifdef _SQUID_MSWIN_ + /* Multiple WIN32 threads may call this simultaneously */ + if (!dbg_mutex) { + HMODULE krnl_lib = GetModuleHandle("Kernel32"); + BOOL(FAR WINAPI * InitializeCriticalSectionAndSpinCount) + (LPCRITICAL_SECTION, DWORD) = NULL; + if (krnl_lib) + (FARPROC) InitializeCriticalSectionAndSpinCount = + GetProcAddress(krnl_lib, + "InitializeCriticalSectionAndSpinCount"); + dbg_mutex = xcalloc(1, sizeof(CRITICAL_SECTION)); + + if (InitializeCriticalSectionAndSpinCount) { + /* let multiprocessor systems EnterCriticalSection() fast */ + if (!InitializeCriticalSectionAndSpinCount(dbg_mutex, 4000)) { + if (debug_log) { + fprintf(debug_log, "FATAL: _db_print: can't initialize critical section\n"); + fflush(debug_log); + } + fprintf(stderr, "FATAL: _db_print: can't initialize critical section\n"); + abort(); + } else + InitializeCriticalSection(dbg_mutex); + } + } + EnterCriticalSection(dbg_mutex); +#endif /* give a chance to context-based debugging to print current context */ if (!Ctx_Lock) ctx_print(); @@ -92,6 +123,9 @@ _db_print(va_alist) #if HAVE_SYSLOG _db_print_syslog(format, args3); #endif +#ifdef _SQUID_MSWIN_ + LeaveCriticalSection(dbg_mutex); +#endif va_end(args1); #if STDC_HEADERS va_end(args2); Index: src/helper.c =================================================================== RCS file: /squid/squid/src/helper.c,v retrieving revision 1.61 diff -u -p -r1.61 helper.c --- src/helper.c 9 Jul 2006 15:44:32 -0000 1.61 +++ src/helper.c 2 Sep 2006 21:32:24 -0000 @@ -70,6 +70,10 @@ helperOpenServers(helper * hlp) int rfd; int wfd; wordlist *w; +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; + pid_t pid; +#endif if (hlp->cmdline == NULL) return; progname = hlp->cmdline->key; @@ -94,7 +98,11 @@ helperOpenServers(helper * hlp) args, shortname, &rfd, - &wfd); + &wfd +#ifdef _SQUID_MSWIN_ + , &hIpc, &pid +#endif + ); if (x < 0) { debug(84, 1) ("WARNING: Cannot run '%s' process.\n", progname); continue; @@ -102,7 +110,12 @@ helperOpenServers(helper * hlp) hlp->n_running++; hlp->n_active++; srv = cbdataAlloc(helper_server); +#ifdef _SQUID_MSWIN_ + srv->hIpc = hIpc; + srv->pid = pid; +#else srv->pid = x; +#endif srv->index = k; srv->rfd = rfd; srv->wfd = wfd; @@ -149,6 +162,11 @@ helperStatefulOpenServers(statefulhelper int rfd; int wfd; wordlist *w; +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; + pid_t pid; +#endif + if (hlp->cmdline == NULL) return; progname = hlp->cmdline->key; @@ -173,7 +191,11 @@ helperStatefulOpenServers(statefulhelper args, shortname, &rfd, - &wfd); + &wfd +#ifdef _SQUID_MSWIN_ + , &hIpc, &pid +#endif + ); if (x < 0) { debug(84, 1) ("WARNING: Cannot run '%s' process.\n", progname); continue; @@ -181,7 +203,12 @@ helperStatefulOpenServers(statefulhelper hlp->n_running++; hlp->n_active++; srv = cbdataAlloc(helper_stateful_server); +#ifdef _SQUID_MSWIN_ + srv->hIpc = hIpc; + srv->pid = pid; +#else srv->pid = x; +#endif srv->flags.reserved = 0; srv->stats.submits = 0; srv->index = k; @@ -439,6 +466,11 @@ void helperShutdown(helper * hlp) { dlink_node *link = hlp->servers.head; +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; + pid_t pid; + int no; +#endif while (link) { int wfd; helper_server *srv; @@ -468,9 +500,26 @@ helperShutdown(helper * hlp) continue; } srv->flags.closing = 1; +#ifdef _SQUID_MSWIN_ + hIpc = srv->hIpc; + pid = srv->pid; + no = srv->index + 1; + shutdown(srv->wfd, SD_BOTH); +#endif wfd = srv->wfd; srv->wfd = -1; comm_close(wfd); +#ifdef _SQUID_MSWIN_ + if (hIpc) { + if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { + getCurrentTime(); + debug(84, 1) ("helperShutdown: WARNING: %s #%d (%s,%ld) " + "didn't exit in 5 seconds\n", + hlp->id_name, no, hlp->cmdline->key, (long int)pid); + } + CloseHandle(hIpc); + } +#endif } } @@ -479,6 +528,11 @@ helperStatefulShutdown(statefulhelper * { dlink_node *link = hlp->servers.head; helper_stateful_server *srv; +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; + pid_t pid; + int no; +#endif int wfd; while (link) { srv = link->data; @@ -507,9 +561,26 @@ helperStatefulShutdown(statefulhelper * continue; } srv->flags.closing = 1; +#ifdef _SQUID_MSWIN_ + hIpc = srv->hIpc; + pid = srv->pid; + no = srv->index + 1; + shutdown(srv->wfd, SD_BOTH); +#endif wfd = srv->wfd; srv->wfd = -1; comm_close(wfd); +#ifdef _SQUID_MSWIN_ + if (hIpc) { + if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { + getCurrentTime(); + debug(84, 1) ("helperShutdown: WARNING: %s #%d (%s,%ld) " + "didn't exit in 5 seconds\n", + hlp->id_name, no, hlp->cmdline->key, (long int)pid); + } + CloseHandle(hIpc); + } +#endif } } Index: src/icmp.c =================================================================== RCS file: /squid/squid/src/icmp.c,v retrieving revision 1.80 diff -u -p -r1.80 icmp.c --- src/icmp.c 22 May 2006 19:01:32 -0000 1.80 +++ src/icmp.c 2 Sep 2006 21:32:24 -0000 @@ -50,6 +50,11 @@ static void icmpSend(pingerEchoData * pk static void icmpHandleSourcePing(const struct sockaddr_in *from, const char *buf); #endif +#ifdef _SQUID_MSWIN_ +static HANDLE hIpc; +static pid_t pid; +#endif + static void icmpSendEcho(struct in_addr to, int opcode, const char *payload, int len) { @@ -193,7 +198,11 @@ icmpOpen(void) args, "Pinger Socket", &rfd, - &wfd); + &wfd +#ifdef _SQUID_MSWIN_ + , &hIpc, &pid +#endif + ); if (x < 0) return; assert(rfd == wfd); @@ -212,7 +221,21 @@ icmpClose(void) if (icmp_sock < 0) return; debug(37, 1) ("Closing Pinger socket on FD %d\n", icmp_sock); +#ifdef _SQUID_MSWIN_ + send(icmp_sock, "$shutdown\n", 10, 0); +#endif comm_close(icmp_sock); +#ifdef _SQUID_MSWIN_ + if (hIpc) { + if (WaitForSingleObject(hIpc, 12000) != WAIT_OBJECT_0) { + getCurrentTime(); + debug(37, 1) + ("icmpClose: WARNING: (pinger,%ld) didn't exit in 12 seconds\n", + (long int)pid); + } + CloseHandle(hIpc); + } +#endif icmp_sock = -1; #endif } Index: src/protos.h =================================================================== RCS file: /squid/squid/src/protos.h,v retrieving revision 1.515 diff -u -p -r1.515 protos.h --- src/protos.h 2 Sep 2006 14:16:10 -0000 1.515 +++ src/protos.h 2 Sep 2006 21:32:24 -0000 @@ -1232,7 +1232,11 @@ extern int ipcCreate(int type, const char *const args[], const char *name, int *rfd, - int *wfd); + int *wfd +#ifdef _SQUID_MSWIN_ + ,HANDLE * hIpc, pid_t * ppid +#endif +); /* CacheDigest */ extern CacheDigest *cacheDigestCreate(int capacity, int bpe); Index: src/squid.h =================================================================== RCS file: /squid/squid/src/squid.h,v retrieving revision 1.243 diff -u -p -r1.243 squid.h --- src/squid.h 19 Aug 2006 12:40:31 -0000 1.243 +++ src/squid.h 2 Sep 2006 21:32:24 -0000 @@ -505,6 +505,17 @@ struct rusage { #define IPPROTO_TCP 0 #endif + +#if defined(_SQUID_MSWIN_) +/* Windows lacks getpagesize() prototype */ +#ifndef getpagesize +extern size_t getpagesize(void); +#endif +#if defined(_MSC_VER) /* Microsoft C Compiler ONLY */ +#define strtoll WIN32_strtoll +#endif +#endif /* _SQUID_MSWIN_ */ + /* * Trap attempts to build large file cache support without support for * large objects Index: src/ssl_support.h =================================================================== RCS file: /squid/squid/src/ssl_support.h,v retrieving revision 1.5 diff -u -p -r1.5 ssl_support.h --- src/ssl_support.h 17 May 2006 23:17:05 -0000 1.5 +++ src/ssl_support.h 2 Sep 2006 21:32:24 -0000 @@ -59,4 +59,10 @@ const char *sslGetCAAttribute(SSL * ssl, const char *sslGetUserCertificatePEM(SSL * ssl); const char *sslGetUserCertificateChainPEM(SSL * ssl); +#ifdef _SQUID_MSWIN_ + +#define SSL_set_fd(s,f) (SSL_set_fd(s,fd_table[fd].win32.handle)) + +#endif /* _SQUID_MSWIN_ */ + #endif /* SQUID_SSL_SUPPORT_H */ Index: src/stat.c =================================================================== RCS file: /squid/squid/src/stat.c,v retrieving revision 1.374 diff -u -p -r1.374 stat.c --- src/stat.c 15 Aug 2006 19:27:28 -0000 1.374 +++ src/stat.c 2 Sep 2006 21:32:25 -0000 @@ -440,21 +440,37 @@ statFiledescriptors(StoreEntry * sentry) int i; fde *f; storeAppendPrintf(sentry, "Active file descriptors:\n"); +#ifdef _SQUID_MSWIN_ + storeAppendPrintf(sentry, "%-4s %-10s %-6s %-4s %-7s* %-7s* %-21s %s\n", + "File", + "Handle", +#else storeAppendPrintf(sentry, "%-4s %-6s %-4s %-7s* %-7s* %-21s %s\n", "File", +#endif "Type", "Tout", "Nread", "Nwrite", "Remote Address", "Description"); +#ifdef _SQUID_MSWIN_ + storeAppendPrintf(sentry, "---- ---------- ------ ---- -------- -------- --------------------- ------------------------------\n"); +#else storeAppendPrintf(sentry, "---- ------ ---- -------- -------- --------------------- ------------------------------\n"); +#endif for (i = 0; i < Squid_MaxFD; i++) { f = &fd_table[i]; if (!f->flags.open) continue; +#ifdef _SQUID_MSWIN_ + storeAppendPrintf(sentry, "%4d 0x%-8lX %-6.6s %4d %7" PRINTF_OFF_T "%c %7" PRINTF_OFF_T "%c %-21s %s\n", + i, + f->win32.handle, +#else storeAppendPrintf(sentry, "%4d %-6.6s %4d %7" PRINTF_OFF_T "%c %7" PRINTF_OFF_T "%c %-21s %s\n", i, +#endif fdTypeStr[f->type], f->timeout_handler ? (int) (f->timeout - squid_curtime) / 60 : 0, f->bytes_read, Index: src/structs.h =================================================================== RCS file: /squid/squid/src/structs.h,v retrieving revision 1.499 diff -u -p -r1.499 structs.h --- src/structs.h 2 Sep 2006 14:08:42 -0000 1.499 +++ src/structs.h 2 Sep 2006 21:32:25 -0000 @@ -914,6 +914,11 @@ struct _fde { #if USE_SSL SSL *ssl; #endif +#ifdef _SQUID_MSWIN_ +struct { + long handle; + } win32; +#endif }; struct _fileMap { @@ -2327,6 +2332,9 @@ struct _helper_server { int uses; unsigned int pending; } stats; +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; +#endif }; @@ -2356,6 +2364,9 @@ struct _helper_stateful_server { int releases; } stats; void *data; /* State data used by the calling routines */ +#ifdef _SQUID_MSWIN_ + HANDLE hIpc; +#endif }; /* Index: src/unlinkd.c =================================================================== RCS file: /squid/squid/src/unlinkd.c,v retrieving revision 1.52 diff -u -p -r1.52 unlinkd.c --- src/unlinkd.c 19 Aug 2006 12:40:31 -0000 1.52 +++ src/unlinkd.c 2 Sep 2006 21:32:25 -0000 @@ -74,6 +74,11 @@ main(int argc, char *argv[]) static int unlinkd_wfd = -1; static int unlinkd_rfd = -1; +#ifdef _SQUID_MSWIN_ +static HANDLE hIpc; +static pid_t pid; +#endif + #define UNLINKD_QUEUE_LIMIT 20 void @@ -106,7 +111,11 @@ unlinkdUnlink(const char *path) int x; int i; char rbuf[512]; +#ifdef _SQUID_MSWIN_ + x = recv(unlinkd_rfd, rbuf, 511, 0); +#else x = read(unlinkd_rfd, rbuf, 511); +#endif if (x > 0) { rbuf[x] = '\0'; for (i = 0; i < x; i++) @@ -119,7 +128,11 @@ unlinkdUnlink(const char *path) assert(l < MAXPATHLEN); xstrncpy(buf, path, MAXPATHLEN); buf[l++] = '\n'; +#ifdef _SQUID_MSWIN_ + x = send(unlinkd_wfd, buf, l, 0); +#else x = write(unlinkd_wfd, buf, l); +#endif if (x < 0) { debug(2, 1) ("unlinkdUnlink: write FD %d failed: %s\n", unlinkd_wfd, xstrerror()); @@ -139,6 +152,28 @@ unlinkdUnlink(const char *path) void unlinkdClose(void) { +#ifdef _SQUID_MSWIN_ + if (unlinkd_wfd > -1) { + debug(2, 1) ("Closing unlinkd pipe on FD %d\n", unlinkd_wfd); + shutdown(unlinkd_wfd, SD_BOTH); + comm_close(unlinkd_wfd); + if (unlinkd_wfd != unlinkd_rfd) + comm_close(unlinkd_rfd); + unlinkd_wfd = -1; + unlinkd_rfd = -1; + } else + debug(2, 0) ("unlinkdClose: WARNING: unlinkd_wfd is %d\n", + unlinkd_wfd); + if (hIpc) { + if (WaitForSingleObject(hIpc, 5000) != WAIT_OBJECT_0) { + getCurrentTime(); + debug(2, 1) + ("unlinkdClose: WARNING: (unlinkd,%ld) didn't exit in 5 seconds\n", + pid); + } + CloseHandle(hIpc); + } +#else if (unlinkd_wfd < 0) return; debug(2, 1) ("Closing unlinkd pipe on FD %d\n", unlinkd_wfd); @@ -147,6 +182,7 @@ unlinkdClose(void) file_close(unlinkd_rfd); unlinkd_wfd = -1; unlinkd_rfd = -1; +#endif } void @@ -157,8 +193,9 @@ unlinkdInit(void) struct timeval slp; args[0] = "(unlinkd)"; args[1] = NULL; -#if HAVE_POLL && defined(_SQUID_OSF_) +#if (HAVE_POLL && defined(_SQUID_OSF_)) || defined(_SQUID_MSWIN_) /* pipes and poll() don't get along on DUNIX -DW */ + /* On Windows select() will fail on a pipe */ x = ipcCreate(IPC_STREAM, #else /* We currently need to use FIFO.. see below */ @@ -168,7 +205,11 @@ unlinkdInit(void) args, "unlinkd", &unlinkd_rfd, - &unlinkd_wfd); + &unlinkd_wfd +#ifdef _SQUID_MSWIN_ + , &hIpc, &pid +#endif + ); if (x < 0) fatal("Failed to create unlinkd subprocess"); slp.tv_sec = 0; Index: src/win32.c =================================================================== RCS file: /squid/squid/src/win32.c,v retrieving revision 1.12 diff -u -p -r1.12 win32.c --- src/win32.c 20 Aug 2006 09:32:28 -0000 1.12 +++ src/win32.c 2 Sep 2006 21:32:25 -0000 @@ -44,6 +44,9 @@ #ifdef _SQUID_WIN32_ #include #ifdef _SQUID_MSWIN_ +#if HAVE_WIN32_PSAPI +#include +#endif #ifndef _MSWSOCK_ #include #endif @@ -59,6 +62,9 @@ static void WIN32_build_argv(char *); void WINAPI SquidWinSvcMain(DWORD, char **); #if defined(_SQUID_MSWIN_) +static int Win32SockInit(void); +static void Win32SockCleanup(void); +extern LPCRITICAL_SECTION dbg_mutex; void WIN32_ExceptionHandlerCleanup(void); static LPTOP_LEVEL_EXCEPTION_FILTER Win32_Old_ExceptionHandler = NULL; #endif /* _SQUID_MSWIN_ */ @@ -330,6 +336,9 @@ WIN32_Abort(int sig) void WIN32_Exit() { +#ifdef _SQUID_MSWIN_ + Win32SockCleanup(); +#endif #if USE_WIN32_SERVICE if (WIN32_run_mode == _WIN_SQUID_RUN_MODE_SERVICE) { if (!Squid_Aborting) { @@ -339,6 +348,8 @@ WIN32_Exit() } #endif #ifdef _SQUID_MSWIN_ + if (dbg_mutex) + DeleteCriticalSection(dbg_mutex); WIN32_ExceptionHandlerCleanup(); #endif _exit(0); @@ -412,8 +423,15 @@ WIN32_Subsystem_Init(int *argc, char *** svcStatus.dwCheckPoint = 0; svcStatus.dwWaitHint = 10000; SetServiceStatus(svcHandle, &svcStatus); +#ifdef _SQUID_MSWIN_ + _setmaxstdio(Squid_MaxFD); +#endif } #endif +#ifdef _SQUID_MSWIN_ + if (Win32SockInit() < 0) + return 1; +#endif return 0; } @@ -734,6 +752,152 @@ main(int argc, char **argv) #endif #if defined(_SQUID_MSWIN_) +static int s_iInitCount = 0; + +int +WIN32_pipe(int handles[2]) +{ + int new_socket; + fde *F = NULL; + + struct sockaddr_in serv_addr; + int len = sizeof(serv_addr); + u_short handle1_port; + + handles[0] = handles[1] = -1; + + statCounter.syscalls.sock.sockets++; + if ((new_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) + return -1; + + memset((void *) &serv_addr, 0, sizeof(serv_addr)); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(0); + serv_addr.sin_addr = local_addr; + + if (bind(new_socket, (SOCKADDR *) & serv_addr, len) < 0 || + listen(new_socket, 1) < 0 || getsockname(new_socket, (SOCKADDR *) & serv_addr, &len) < 0 || + (handles[1] = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + closesocket(new_socket); + return -1; + } + handle1_port = ntohs(serv_addr.sin_port); + if (connect(handles[1], (SOCKADDR *) & serv_addr, len) < 0 || + (handles[0] = accept(new_socket, (SOCKADDR *) & serv_addr, &len)) < 0) { + closesocket(handles[1]); + handles[1] = -1; + closesocket(new_socket); + return -1; + } + closesocket(new_socket); + + F = &fd_table[handles[0]]; + F->local_addr = local_addr; + F->local_port = ntohs(serv_addr.sin_port); + + F = &fd_table[handles[1]]; + F->local_addr = local_addr; + xstrncpy(F->ipaddr, inet_ntoa(local_addr), 16); + F->remote_port = handle1_port; + + return 0; +} + +int +WIN32_getrusage(int who, struct rusage *usage) +{ +#if HAVE_WIN32_PSAPI + if ((WIN32_OS_version == _WIN_OS_WINNT) || (WIN32_OS_version == _WIN_OS_WIN2K) + || (WIN32_OS_version == _WIN_OS_WINXP) || (WIN32_OS_version == _WIN_OS_WINNET)) { + /* On Windows NT/2000 call PSAPI.DLL for process Memory */ + /* informations -- Guido Serassio */ + HANDLE hProcess; + PROCESS_MEMORY_COUNTERS pmc; + hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, GetCurrentProcessId()); + { + /* Microsoft CRT doesn't have getrusage function, */ + /* so we get process CPU time information from PSAPI.DLL. */ + FILETIME ftCreate, ftExit, ftKernel, ftUser; + if (GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) { + int64_t tUser64 = (*(int64_t *) & ftUser / 10); + int64_t tKernel64 = (*(int64_t *) & ftKernel / 10); + usage->ru_utime.tv_sec = (long) (tUser64 / 1000000); + usage->ru_stime.tv_sec = (long) (tKernel64 / 1000000); + usage->ru_utime.tv_usec = (long) (tUser64 % 1000000); + usage->ru_stime.tv_usec = (long) (tKernel64 % 1000000); + } else { + CloseHandle(hProcess); + return -1; + } + } + if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) { + usage->ru_maxrss = (DWORD) (pmc.WorkingSetSize / getpagesize()); + usage->ru_majflt = pmc.PageFaultCount; + } else { + CloseHandle(hProcess); + return -1; + } + CloseHandle(hProcess); + } +#endif + return 0; +} + +static int +Win32SockInit(void) +{ + int iVersionRequested; + WSADATA wsaData; + int err, opt; + int optlen = sizeof(opt); + + + if (s_iInitCount > 0) { + s_iInitCount++; + return (0); + } else if (s_iInitCount < 0) + return (s_iInitCount); + /* s_iInitCount == 0. Do the initailization */ + iVersionRequested = MAKEWORD(2, 0); + err = WSAStartup((WORD) iVersionRequested, &wsaData); + if (err) { + s_iInitCount = -1; + return (s_iInitCount); + } + if (LOBYTE(wsaData.wVersion) != 2 || + HIBYTE(wsaData.wVersion) != 0) { + s_iInitCount = -2; + WSACleanup(); + return (s_iInitCount); + } + if (WIN32_OS_version != _WIN_OS_WINNT) { + if (getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &opt, &optlen)) { + s_iInitCount = -3; + WSACleanup(); + return (s_iInitCount); + } else { + opt = opt | SO_SYNCHRONOUS_NONALERT; + if (setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *) &opt, optlen)) { + s_iInitCount = -3; + WSACleanup(); + return (s_iInitCount); + } + } + } + WIN32_Socks_initialized = 1; + s_iInitCount++; + return (s_iInitCount); +} + +static void +Win32SockCleanup(void) +{ + if (--s_iInitCount == 0) + WSACleanup(); + return; +} LONG CALLBACK WIN32_ExceptionHandler(EXCEPTION_POINTERS * ep) @@ -754,9 +918,11 @@ WIN32_ExceptionHandler(EXCEPTION_POINTER default: break; } + return EXCEPTION_CONTINUE_SEARCH; } + void WIN32_ExceptionHandlerInit() {