diff -u -r -N squid-4.0.8/ChangeLog squid-4.0.9/ChangeLog
--- squid-4.0.8/ChangeLog	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/ChangeLog	2016-04-21 01:19:59.000000000 +1200
@@ -1,3 +1,12 @@
+Changes to squid-4.0.9 (20 Apr 2016):
+
+	- Bug #4405: assertion failed: comm.cc:554: "Comm::IsConnOpen(conn)"
+	- Add a new error page token for unquoted external ACL messages.
+	- Stop parsing response prefix after discovering an "HTTP/0.9" response.
+	- ... and some documentation updates
+	- ... and some code polishing
+	- ... and all fixes from 3.5.17
+
 Changes to squid-4.0.8 (02 Apr 2016):
 
 	- Bug 4459: FHS compliance: move netdb.state and ssl_db to /var/cache/squid
@@ -139,6 +148,23 @@
 	- ... and many documentation changes
 	- ... and much code cleanup and polishing
 
+Changes to squid-3.5.17 (20 Apr 2016):
+
+	- Regression Bug 4480: logformat [.width_max]
+	- Regression Bug 4481: varyEvaluateMatch: Oops. Not a Vary match on second attempt
+	- Bug 4495: Unknown SSL option SSL_OP_NO_TICKET
+	- Bug 4493: theObject->sharedMemorySize() == theSegment.size() exception
+	- Bug 4483: ./configure garbles -Og option in CFLAGS
+	- Bug 4482: Solaris GCC 5.2 warning in src/ip/Intercept.cc
+	- Bug 4468: NotNode (!acl) naming: Terminate the name before strncat(name).
+	- Bug 4465: Header forgery detection leads to crash
+	- Bug 2460 partial: workaround deferred reads on shutdown and restart
+	- cachemgr.cgi: use dynamic MemBuf for internal content generation
+	- ESI: Fix several element construction issues
+	- TLS: Fix Handshake Error: ccs received early
+	- TLS: Add chained and signing cert to peek-then-bumped connections
+	- Fix some startup/shutdown crashes
+
 Changes to squid-3.5.16 (02 Apr 2016):
 
 	- Bug 4476: Removed duplicated #include lines
diff -u -r -N squid-4.0.8/compat/xstrerror.h squid-4.0.9/compat/xstrerror.h
--- squid-4.0.8/compat/xstrerror.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/compat/xstrerror.h	2016-04-21 01:19:59.000000000 +1200
@@ -13,15 +13,9 @@
 #include <errno.h>
 #endif
 
-/** strerror() wrapper replacement.
- *
- * Provides the guarantee that a string is always returned.
- * Where strerror() would have provided NULL this will report the error as unknown.
- */
-#define xstrerror() xstrerr(errno)
-
 /** Provide the textual display of a system error number.
  * A string is always returned.
+ * Where strerror() would have provided NULL this will report the error as unknown.
  * On MS Windows the native Win32 errors are also translated.
  */
 extern const char * xstrerr(int error);
diff -u -r -N squid-4.0.8/configure squid-4.0.9/configure
--- squid-4.0.8/configure	2016-04-02 10:08:39.000000000 +1300
+++ squid-4.0.9/configure	2016-04-21 01:22:03.000000000 +1200
@@ -1,7 +1,7 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.8.
+# Generated by GNU Autoconf 2.69 for Squid Web Proxy 4.0.9.
 #
 # Report bugs to <http://bugs.squid-cache.org/>.
 #
@@ -595,8 +595,8 @@
 # Identity of this package.
 PACKAGE_NAME='Squid Web Proxy'
 PACKAGE_TARNAME='squid'
-PACKAGE_VERSION='4.0.8'
-PACKAGE_STRING='Squid Web Proxy 4.0.8'
+PACKAGE_VERSION='4.0.9'
+PACKAGE_STRING='Squid Web Proxy 4.0.9'
 PACKAGE_BUGREPORT='http://bugs.squid-cache.org/'
 PACKAGE_URL=''
 
@@ -1650,7 +1650,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Squid Web Proxy 4.0.8 to adapt to many kinds of systems.
+\`configure' configures Squid Web Proxy 4.0.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1721,7 +1721,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Squid Web Proxy 4.0.8:";;
+     short | recursive ) echo "Configuration of Squid Web Proxy 4.0.9:";;
    esac
   cat <<\_ACEOF
 
@@ -2148,7 +2148,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Squid Web Proxy configure 4.0.8
+Squid Web Proxy configure 4.0.9
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -3252,7 +3252,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Squid Web Proxy $as_me 4.0.8, which was
+It was created by Squid Web Proxy $as_me 4.0.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -4119,7 +4119,7 @@
 
 # Define the identity of the package.
  PACKAGE='squid'
- VERSION='4.0.8'
+ VERSION='4.0.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -20862,8 +20862,8 @@
 if test "x$enableval" = "xno" ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling compiler optimizations (-O flag)" >&5
 $as_echo "$as_me: Disabling compiler optimizations (-O flag)" >&6;}
-  CFLAGS="`echo $CFLAGS | sed -e 's/-O[0-9]*//'`"
-  CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-O[0-9]*//'`"
+  CFLAGS="`echo $CFLAGS | sed -e 's/-O[0-9g]*//'`"
+  CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-O[0-9g]*//'`"
   enable_inline="no"
 fi
 
@@ -39162,7 +39162,7 @@
     if test "x$GCC" = "xyes"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: Removing -O for gcc on $host" >&5
 $as_echo "$as_me: Removing -O for gcc on $host" >&6;}
-      CFLAGS="`echo $CFLAGS | sed -e 's/-O[0-9]*//'`"
+      CFLAGS="`echo $CFLAGS | sed -e 's/-O[0-9g]*//'`"
     fi
   ;;
 
@@ -42473,7 +42473,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Squid Web Proxy $as_me 4.0.8, which was
+This file was extended by Squid Web Proxy $as_me 4.0.9, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -42539,7 +42539,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-Squid Web Proxy config.status 4.0.8
+Squid Web Proxy config.status 4.0.9
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -u -r -N squid-4.0.8/configure.ac squid-4.0.9/configure.ac
--- squid-4.0.8/configure.ac	2016-04-02 10:08:38.000000000 +1300
+++ squid-4.0.9/configure.ac	2016-04-21 01:22:03.000000000 +1200
@@ -5,7 +5,7 @@
 ## Please see the COPYING and CONTRIBUTORS files for details.
 ##
 
-AC_INIT([Squid Web Proxy],[4.0.8],[http://bugs.squid-cache.org/],[squid])
+AC_INIT([Squid Web Proxy],[4.0.9],[http://bugs.squid-cache.org/],[squid])
 AC_PREREQ(2.61)
 AC_CONFIG_HEADERS([include/autoconf.h])
 AC_CONFIG_AUX_DIR(cfgaux)
@@ -380,8 +380,8 @@
                   --disable-inline]), [
 if test "x$enableval" = "xno" ; then
   AC_MSG_NOTICE([Disabling compiler optimizations (-O flag)])
-  CFLAGS="`echo $CFLAGS | sed -e 's/-O[[0-9]]*//'`"
-  CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-O[[0-9]]*//'`"
+  CFLAGS="`echo $CFLAGS | sed -e 's/-O[[0-9g]]*//'`"
+  CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-O[[0-9g]]*//'`"
   enable_inline="no"
 fi
 ])
@@ -3226,7 +3226,7 @@
   i386-*-solaris2.*)
     if test "x$GCC" = "xyes"; then
       AC_MSG_NOTICE([Removing -O for gcc on $host])
-      CFLAGS="`echo $CFLAGS | sed -e 's/-O[[0-9]]*//'`"
+      CFLAGS="`echo $CFLAGS | sed -e 's/-O[[0-9g]]*//'`"
     fi
   ;;
 
diff -u -r -N squid-4.0.8/doc/release-notes/release-4.html squid-4.0.9/doc/release-notes/release-4.html
--- squid-4.0.8/doc/release-notes/release-4.html	2016-04-02 11:47:00.000000000 +1300
+++ squid-4.0.9/doc/release-notes/release-4.html	2016-04-21 02:16:10.000000000 +1200
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.71">
- <TITLE>Squid 4.0.8 release notes</TITLE>
+ <TITLE>Squid 4.0.9 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 4.0.8 release notes</H1>
+<H1>Squid 4.0.9 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -61,7 +61,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-4.0.8 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-4.0.9 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v4/">http://www.squid-cache.org/Versions/v4/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -265,10 +265,18 @@
 <P>New directive to limit the size of a table used for sharing information
 about collapsible entries among SMP workers.</P>
 
+<DT><B>on_unsupported_protocol</B><DD>
+<P>New directive to set the action performed when encountering strange
+protocol requests at the beginning of an accepted TCP connection.</P>
+
 <DT><B>reply_header_add</B><DD>
 <P>New directive to add header fields to outgoing HTTP responses to
 the client.</P>
 
+<DT><B>request_start_timeout</B><DD>
+<P>New directive controlling how long Squid waits for the first request
+bytes to arrive after initial connection establishment by a client.</P>
+
 <DT><B>server_pconn_for_nonretriable</B><DD>
 <P>New directive to provide fine-grained control over persistent connection
 reuse when forwarding HTTP requests that Squid cannot retry. It is useful
diff -u -r -N squid-4.0.8/include/version.h squid-4.0.9/include/version.h
--- squid-4.0.8/include/version.h	2016-04-02 10:08:39.000000000 +1300
+++ squid-4.0.9/include/version.h	2016-04-21 01:22:03.000000000 +1200
@@ -7,7 +7,7 @@
  */
 
 #ifndef SQUID_RELEASE_TIME
-#define SQUID_RELEASE_TIME 1459544634
+#define SQUID_RELEASE_TIME 1461158391
 #endif
 
 /*
diff -u -r -N squid-4.0.8/lib/snmplib/parse.c squid-4.0.9/lib/snmplib/parse.c
--- squid-4.0.8/lib/snmplib/parse.c	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/lib/snmplib/parse.c	2016-04-21 01:19:59.000000000 +1200
@@ -1089,8 +1089,9 @@
     char *p;
 
     fp = fopen(filename, "r");
-    if (fp == NULL) {
-        snmplib_debug(1, "init_mib: %s: %s\n", filename, xstrerror());
+    if (!fp) {
+        int xerrno = errno;
+        snmplib_debug(1, "init_mib: %s: %s\n", filename, xstrerr(xerrno));
         return (NULL);
     }
     mbuf[0] = '\0';
diff -u -r -N squid-4.0.8/RELEASENOTES.html squid-4.0.9/RELEASENOTES.html
--- squid-4.0.8/RELEASENOTES.html	2016-04-02 11:47:00.000000000 +1300
+++ squid-4.0.9/RELEASENOTES.html	2016-04-21 02:16:10.000000000 +1200
@@ -2,10 +2,10 @@
 <HTML>
 <HEAD>
  <META NAME="GENERATOR" CONTENT="LinuxDoc-Tools 0.9.71">
- <TITLE>Squid 4.0.8 release notes</TITLE>
+ <TITLE>Squid 4.0.9 release notes</TITLE>
 </HEAD>
 <BODY>
-<H1>Squid 4.0.8 release notes</H1>
+<H1>Squid 4.0.9 release notes</H1>
 
 <H2>Squid Developers</H2>
 <HR>
@@ -61,7 +61,7 @@
 <HR>
 <H2><A NAME="s1">1.</A> <A HREF="#toc1">Notice</A></H2>
 
-<P>The Squid Team are pleased to announce the release of Squid-4.0.8 for testing.</P>
+<P>The Squid Team are pleased to announce the release of Squid-4.0.9 for testing.</P>
 <P>This new release is available for download from 
 <A HREF="http://www.squid-cache.org/Versions/v4/">http://www.squid-cache.org/Versions/v4/</A> or the
 <A HREF="http://www.squid-cache.org/Download/http-mirrors.html">mirrors</A>.</P>
@@ -265,10 +265,18 @@
 <P>New directive to limit the size of a table used for sharing information
 about collapsible entries among SMP workers.</P>
 
+<DT><B>on_unsupported_protocol</B><DD>
+<P>New directive to set the action performed when encountering strange
+protocol requests at the beginning of an accepted TCP connection.</P>
+
 <DT><B>reply_header_add</B><DD>
 <P>New directive to add header fields to outgoing HTTP responses to
 the client.</P>
 
+<DT><B>request_start_timeout</B><DD>
+<P>New directive controlling how long Squid waits for the first request
+bytes to arrive after initial connection establishment by a client.</P>
+
 <DT><B>server_pconn_for_nonretriable</B><DD>
 <P>New directive to provide fine-grained control over persistent connection
 reuse when forwarding HTTP requests that Squid cannot retry. It is useful
diff -u -r -N squid-4.0.8/src/acl/BoolOps.cc squid-4.0.9/src/acl/BoolOps.cc
--- squid-4.0.8/src/acl/BoolOps.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/acl/BoolOps.cc	2016-04-21 01:19:59.000000000 +1200
@@ -17,6 +17,7 @@
 {
     assert(acl);
     name[0] = '!';
+    name[1] = '\0';
     strncat(&name[1], acl->name, sizeof(name)-1-1);
     add(acl);
 }
diff -u -r -N squid-4.0.8/src/acl/external/delayer/ext_delayer_acl.8 squid-4.0.9/src/acl/external/delayer/ext_delayer_acl.8
--- squid-4.0.8/src/acl/external/delayer/ext_delayer_acl.8	2016-04-02 11:48:10.000000000 +1300
+++ squid-4.0.9/src/acl/external/delayer/ext_delayer_acl.8	2016-04-21 02:16:49.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_DELAYER_ACL 8"
-.TH EXT_DELAYER_ACL 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH EXT_DELAYER_ACL 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/acl/external/file_userip/ext_file_userip_acl.cc squid-4.0.9/src/acl/external/file_userip/ext_file_userip_acl.cc
--- squid-4.0.8/src/acl/external/file_userip/ext_file_userip_acl.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/acl/external/file_userip/ext_file_userip_acl.cc	2016-04-21 01:19:59.000000000 +1200
@@ -251,7 +251,8 @@
     }
     FILE *FH = fopen(filename, "r");
     if (!FH) {
-        fprintf(stderr, "%s: FATAL: Unable to open file '%s': %s", program_name, filename, xstrerror());
+        int xerrno = errno;
+        fprintf(stderr, "%s: FATAL: Unable to open file '%s': %s", program_name, filename, xstrerr(xerrno));
         exit(1);
     }
     current_entry = load_dict(FH);
diff -u -r -N squid-4.0.8/src/acl/external/SQL_session/ext_sql_session_acl.8 squid-4.0.9/src/acl/external/SQL_session/ext_sql_session_acl.8
--- squid-4.0.8/src/acl/external/SQL_session/ext_sql_session_acl.8	2016-04-02 11:48:18.000000000 +1300
+++ squid-4.0.9/src/acl/external/SQL_session/ext_sql_session_acl.8	2016-04-21 02:16:56.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_SQL_SESSION_ACL 8"
-.TH EXT_SQL_SESSION_ACL 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH EXT_SQL_SESSION_ACL 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8 squid-4.0.9/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8
--- squid-4.0.8/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2016-04-02 11:48:22.000000000 +1300
+++ squid-4.0.9/src/acl/external/wbinfo_group/ext_wbinfo_group_acl.8	2016-04-21 02:16:59.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "EXT_WBINFO_GROUP_ACL 8"
-.TH EXT_WBINFO_GROUP_ACL 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH EXT_WBINFO_GROUP_ACL 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/auth/basic/DB/basic_db_auth.8 squid-4.0.9/src/auth/basic/DB/basic_db_auth.8
--- squid-4.0.8/src/auth/basic/DB/basic_db_auth.8	2016-04-02 11:48:45.000000000 +1300
+++ squid-4.0.9/src/auth/basic/DB/basic_db_auth.8	2016-04-21 02:17:22.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_DB_AUTH 8"
-.TH BASIC_DB_AUTH 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH BASIC_DB_AUTH 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/auth/basic/NCSA/basic_ncsa_auth.cc squid-4.0.9/src/auth/basic/NCSA/basic_ncsa_auth.cc
--- squid-4.0.8/src/auth/basic/NCSA/basic_ncsa_auth.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/auth/basic/NCSA/basic_ncsa_auth.cc	2016-04-21 01:19:59.000000000 +1200
@@ -52,8 +52,9 @@
     usermap.clear();
     //TODO: change to c++ streams
     f = fopen(passwdfile, "r");
-    if (NULL == f) {
-        fprintf(stderr, "FATAL: %s: %s\n", passwdfile, xstrerror());
+    if (!f) {
+        int xerrno = errno;
+        fprintf(stderr, "FATAL: %s: %s\n", passwdfile, xstrerr(xerrno));
         exit(1);
     }
     unsigned int lineCount = 0;
diff -u -r -N squid-4.0.8/src/auth/basic/POP3/basic_pop3_auth.8 squid-4.0.9/src/auth/basic/POP3/basic_pop3_auth.8
--- squid-4.0.8/src/auth/basic/POP3/basic_pop3_auth.8	2016-04-02 11:48:52.000000000 +1300
+++ squid-4.0.9/src/auth/basic/POP3/basic_pop3_auth.8	2016-04-21 02:17:29.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "BASIC_POP3_AUTH 8"
-.TH BASIC_POP3_AUTH 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH BASIC_POP3_AUTH 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/auth/basic/RADIUS/basic_radius_auth.cc squid-4.0.9/src/auth/basic/RADIUS/basic_radius_auth.cc
--- squid-4.0.8/src/auth/basic/RADIUS/basic_radius_auth.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/auth/basic/RADIUS/basic_radius_auth.cc	2016-04-21 01:19:59.000000000 +1200
@@ -418,10 +418,11 @@
          */
         gettimeofday(&sent, NULL);
         if (send(socket_fd, (char *) auth, total_length, 0) < 0) {
+            int xerrno = errno;
             // EAGAIN is expected at high traffic, just retry
             // TODO: block/sleep a few ms to let the apparently full buffer drain ?
-            if (errno != EAGAIN && errno != EWOULDBLOCK)
-                fprintf(stderr,"ERROR: RADIUS send() failure: %s\n", xstrerror());
+            if (xerrno != EAGAIN && xerrno != EWOULDBLOCK)
+                fprintf(stderr,"ERROR: RADIUS send() failure: %s\n", xstrerr(xerrno));
             continue;
         }
         while ((time_spent = time_since(&sent)) < 1000000) {
@@ -569,7 +570,8 @@
     }
 #ifdef O_NONBLOCK
     if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL, 0) | O_NONBLOCK) < 0) {
-        fprintf(stderr,"%s| ERROR: fcntl() failure: %s\n", argv[0], xstrerror());
+        int xerrno = errno;
+        fprintf(stderr,"%s| ERROR: fcntl() failure: %s\n", argv[0], xstrerr(xerrno));
         exit(1);
     }
 #endif
diff -u -r -N squid-4.0.8/src/auth/digest/file/text_backend.cc squid-4.0.9/src/auth/digest/file/text_backend.cc
--- squid-4.0.8/src/auth/digest/file/text_backend.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/auth/digest/file/text_backend.cc	2016-04-21 01:19:59.000000000 +1200
@@ -80,7 +80,8 @@
     }
     FILE *f = fopen(passwordFile, "r");
     if (!f) {
-        fprintf(stderr, "digest_file_auth: cannot open password file: %s\n", xstrerror());
+        int xerrno = errno;
+        fprintf(stderr, "digest_file_auth: cannot open password file: %s\n", xstrerr(xerrno));
         exit(1);
     }
     unsigned int lineCount = 0;
diff -u -r -N squid-4.0.8/src/cache_cf.cc squid-4.0.9/src/cache_cf.cc
--- squid-4.0.8/src/cache_cf.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/cache_cf.cc	2016-04-21 01:19:59.000000000 +1200
@@ -293,8 +293,8 @@
     memset(&globbuf, 0, sizeof(globbuf));
     for (path = strwordtok(files, &saveptr); path; path = strwordtok(NULL, &saveptr)) {
         if (glob(path, globbuf.gl_pathc ? GLOB_APPEND : 0, NULL, &globbuf) != 0) {
-            fatalf("Unable to find configuration file: %s: %s",
-                   path, xstrerror());
+            int xerrno = errno;
+            fatalf("Unable to find configuration file: %s: %s", path, xstrerr(xerrno));
         }
     }
     for (i = 0; i < (int)globbuf.gl_pathc; ++i) {
@@ -441,8 +441,10 @@
         fp = fopen(file_name, "r");
     }
 
-    if (fp == NULL)
-        fatalf("Unable to open configuration file: %s: %s", file_name, xstrerror());
+    if (!fp) {
+        int xerrno = errno;
+        fatalf("Unable to open configuration file: %s: %s", file_name, xstrerr(xerrno));
+    }
 
 #if _SQUID_WINDOWS_
     setmode(fileno(fp), O_TEXT);
@@ -3863,13 +3865,14 @@
     }
 
     if (stat(path, &sb) < 0) {
-        debugs(0, DBG_CRITICAL, (opt_parse_cfg_only?"FATAL: ":"ERROR: ") << name << " " << path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(0, DBG_CRITICAL, (opt_parse_cfg_only?"FATAL: ":"ERROR: ") << name << " " << path << ": " << xstrerr(xerrno));
         // keep going to find more issues if we are only checking the config file with "-k parse"
         if (opt_parse_cfg_only)
             return;
         // this is fatal if it is found during startup or reconfigure
         if (opt_send_signal == -1 || opt_send_signal == SIGHUP)
-            fatalf("%s %s: %s", name, path, xstrerror());
+            fatalf("%s %s: %s", name, path, xstrerr(xerrno));
     }
 }
 
diff -u -r -N squid-4.0.8/src/cf.data.pre squid-4.0.9/src/cf.data.pre
--- squid-4.0.8/src/cf.data.pre	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/cf.data.pre	2016-04-21 01:19:59.000000000 +1200
@@ -2571,7 +2571,7 @@
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 
-			    SSL_OP_NO_TICKET
+			    NO_TICKET
 				      Disable use of RFC5077 session tickets.
 				      Some servers may have problems
 				      understanding the TLS extension due
@@ -3336,7 +3336,7 @@
 				      Always create a new key when using
 				      temporary/ephemeral DH key exchanges
 
-			    SSL_OP_NO_TICKET
+			    NO_TICKET
 				      Disable use of RFC5077 session tickets.
 				      Some servers may have problems
 				      understanding the TLS extension due
@@ -7967,6 +7967,7 @@
 		%H	- Request domain name
 		%i	- Client IP Address
 		%M	- Request Method
+		%O	- Unescaped message result from external ACL helper
 		%o	- Message result from external ACL helper
 		%p	- Request Port number
 		%P	- Request Protocol name
diff -u -r -N squid-4.0.8/src/clients/FtpGateway.cc squid-4.0.9/src/clients/FtpGateway.cc
--- squid-4.0.8/src/clients/FtpGateway.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/clients/FtpGateway.cc	2016-04-21 01:19:59.000000000 +1200
@@ -1775,8 +1775,9 @@
         errno = 0;
         if (setsockopt(ftpState->ctrl.conn->fd, SOL_SOCKET, SO_REUSEADDR,
                        (char *) &on, sizeof(on)) == -1) {
+            int xerrno = errno;
             // SO_REUSEADDR is only an optimization, no need to be verbose about error
-            debugs(9, 4, "setsockopt failed: " << xstrerror());
+            debugs(9, 4, "setsockopt failed: " << xstrerr(xerrno));
         }
         ftpState->ctrl.conn->flags |= COMM_REUSEADDR;
         temp->flags |= COMM_REUSEADDR;
diff -u -r -N squid-4.0.8/src/client_side.cc squid-4.0.9/src/client_side.cc
--- squid-4.0.8/src/client_side.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/client_side.cc	2016-04-21 01:19:59.000000000 +1200
@@ -1578,8 +1578,7 @@
                 conn->pipeline.popMe(Http::StreamPointer(context));
             }
             Comm::SetSelect(conn->clientConnection->fd, COMM_SELECT_READ, NULL, NULL, 0);
-            conn->fakeAConnectRequest("unknown-protocol", conn->preservedClientData);
-            return true;
+            return conn->fakeAConnectRequest("unknown-protocol", conn->preservedClientData);
         } else {
             debugs(33, 3, "Continue with returning the error: " << requestError);
         }
@@ -2453,8 +2452,10 @@
             (transparent() || port->disable_pmtu_discovery == DISABLE_PMTU_ALWAYS)) {
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
         int i = IP_PMTUDISC_DONT;
-        if (setsockopt(clientConnection->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof(i)) < 0)
-            debugs(33, 2, "WARNING: Path MTU discovery disabling failed on " << clientConnection << " : " << xstrerror());
+        if (setsockopt(clientConnection->fd, SOL_IP, IP_MTU_DISCOVER, &i, sizeof(i)) < 0) {
+            int xerrno = errno;
+            debugs(33, 2, "WARNING: Path MTU discovery disabling failed on " << clientConnection << " : " << xstrerr(xerrno));
+        }
 #else
         static bool reported = false;
 
@@ -2761,7 +2762,8 @@
         debugs(33, 2, HERE << "sslBump not needed for " << connState->clientConnection);
         connState->sslBumpMode = Ssl::bumpNone;
     }
-    connState->fakeAConnectRequest("ssl-bump", connState->inBuf);
+    if (!connState->fakeAConnectRequest("ssl-bump", connState->inBuf))
+        connState->clientConnection->close();
 }
 
 /** handle a new HTTPS connection */
@@ -2865,6 +2867,9 @@
                     bool ret = Ssl::configureSSLUsingPkeyAndCertFromMemory(ssl, reply_message.getBody().c_str(), *port);
                     if (!ret)
                         debugs(33, 5, "Failed to set certificates to ssl object for PeekAndSplice mode");
+
+                    SSL_CTX *sslContext = SSL_get_SSL_CTX(ssl);
+                    Ssl::configureUnconfiguredSslContext(sslContext, signAlgorithm, *port);
                 } else {
                     auto ctx = Ssl::generateSslContextUsingPkeyAndCertFromMemory(reply_message.getBody().c_str(), *port);
                     getSslContextDone(ctx, true);
@@ -3024,6 +3029,9 @@
             auto ssl = fd_table[clientConnection->fd].ssl.get();
             if (!Ssl::configureSSL(ssl, certProperties, *port))
                 debugs(33, 5, "Failed to set certificates to ssl object for PeekAndSplice mode");
+
+            SSL_CTX *sslContext = SSL_get_SSL_CTX(ssl);
+            Ssl::configureUnconfiguredSslContext(sslContext, certProperties.signAlgorithm, *port);
         } else {
             auto dynCtx = Ssl::generateSslContext(certProperties, *port);
             getSslContextDone(dynCtx, true);
@@ -3039,17 +3047,10 @@
     // Try to add generated ssl context to storage.
     if (port->generateHostCertificates && isNew) {
 
-        if (signAlgorithm == Ssl::algSignTrusted) {
-            // Add signing certificate to the certificates chain
-            X509 *cert = port->signingCert.get();
-            if (SSL_CTX_add_extra_chain_cert(sslContext, cert)) {
-                // increase the certificate lock
-                CRYPTO_add(&(cert->references),1,CRYPTO_LOCK_X509);
-            } else {
-                const int ssl_error = ERR_get_error();
-                debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
-            }
-            Ssl::addChainToSslContext(sslContext, port->certsToChain.get());
+        if (sslContext && (signAlgorithm == Ssl::algSignTrusted)) {
+            Ssl::chainCertificatesToSSLContext(sslContext, *port);
+        } else if (signAlgorithm == Ssl::algSignTrusted) {
+            debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain because SSL context chain is invalid!");
         }
         //else it is self-signed or untrusted do not attrach any certificate
 
@@ -3141,8 +3142,7 @@
         checklist.conn(this);
         allow_t answer = checklist.fastCheck();
         if (answer == ACCESS_ALLOWED && answer.kind == 1) {
-            splice();
-            return true;
+            return splice();
         }
     }
     return false;
@@ -3244,11 +3244,11 @@
         connState->clientConnection->close();
     } else if (bumpAction != Ssl::bumpSplice) {
         connState->startPeekAndSpliceDone();
-    } else
-        connState->splice();
+    } else if (!connState->splice())
+        connState->clientConnection->close();
 }
 
-void
+bool
 ConnStateData::splice()
 {
     // normally we can splice here, because we just got client hello message
@@ -3272,7 +3272,7 @@
         // XXX: copy from MemBuf reallocates, not a regression since old code did too
         SBuf temp;
         temp.append(rbuf.content(), rbuf.contentSize());
-        fakeAConnectRequest("intercepted TLS spliced", temp);
+        return fakeAConnectRequest("intercepted TLS spliced", temp);
     } else {
         // XXX: assuming that there was an HTTP/1.1 CONNECT to begin with...
 
@@ -3283,6 +3283,7 @@
         Http::StreamPointer context = pipeline.front();
         ClientHttpRequest *http = context->http;
         tunnelStart(http);
+        return true;
     }
 }
 
@@ -3349,7 +3350,7 @@
 
 #endif /* USE_OPENSSL */
 
-void
+bool
 ConnStateData::fakeAConnectRequest(const char *reason, const SBuf &payload)
 {
     // fake a CONNECT request to force connState to tunnel
@@ -3380,8 +3381,9 @@
 
     if (!ret) {
         debugs(33, 2, "Failed to start fake CONNECT request for " << reason << " connection: " << clientConnection);
-        clientConnection->close();
+        return false;
     }
+    return true;
 }
 
 /// check FD after clientHttp[s]ConnectionOpened, adjust HttpSockets as needed
diff -u -r -N squid-4.0.8/src/client_side.h squid-4.0.9/src/client_side.h
--- squid-4.0.8/src/client_side.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/client_side.h	2016-04-21 01:19:59.000000000 +1200
@@ -213,7 +213,7 @@
     void httpsPeeked(Comm::ConnectionPointer serverConnection);
 
     /// Splice a bumped client connection on peek-and-splice mode
-    void splice();
+    bool splice();
 
     /// Check on_unsupported_protocol access list and splice if required
     /// \retval true on splice
@@ -280,7 +280,7 @@
 
     /// generate a fake CONNECT request with the given payload
     /// at the beginning of the client I/O buffer
-    void fakeAConnectRequest(const char *reason, const SBuf &payload);
+    bool fakeAConnectRequest(const char *reason, const SBuf &payload);
 
     /// client data which may need to forward as-is to server after an
     /// on_unsupported_protocol tunnel decision.
diff -u -r -N squid-4.0.8/src/client_side_request.cc squid-4.0.9/src/client_side_request.cc
--- squid-4.0.8/src/client_side_request.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/client_side_request.cc	2016-04-21 01:19:59.000000000 +1200
@@ -574,7 +574,8 @@
 
     debugs(85, DBG_IMPORTANT, "SECURITY ALERT: Host header forgery detected on " <<
            http->getConn()->clientConnection << " (" << A << " does not match " << B << ")");
-    debugs(85, DBG_IMPORTANT, "SECURITY ALERT: By user agent: " << http->request->header.getStr(Http::HdrType::USER_AGENT));
+    if (const char *ua = http->request->header.getStr(Http::HdrType::USER_AGENT))
+        debugs(85, DBG_IMPORTANT, "SECURITY ALERT: By user agent: " << ua);
     debugs(85, DBG_IMPORTANT, "SECURITY ALERT: on URL: " << http->request->effectiveRequestUri());
 
     // IP address validation for Host: failed. reject the connection.
diff -u -r -N squid-4.0.8/src/comm/ConnOpener.cc squid-4.0.9/src/comm/ConnOpener.cc
--- squid-4.0.8/src/comm/ConnOpener.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ConnOpener.cc	2016-04-21 01:19:59.000000000 +1200
@@ -410,7 +410,8 @@
     Ip::Address::InitAddr(addr);
 
     if (getsockname(conn_->fd, addr->ai_addr, &(addr->ai_addrlen)) != 0) {
-        debugs(50, DBG_IMPORTANT, "ERROR: Failed to retrieve TCP/UDP details for socket: " << conn_ << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR: Failed to retrieve TCP/UDP details for socket: " << conn_ << ": " << xstrerr(xerrno));
         Ip::Address::FreeAddr(addr);
         return;
     }
diff -u -r -N squid-4.0.8/src/comm/ModDevPoll.cc squid-4.0.9/src/comm/ModDevPoll.cc
--- squid-4.0.8/src/comm/ModDevPoll.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ModDevPoll.cc	2016-04-21 01:19:59.000000000 +1200
@@ -197,8 +197,10 @@
 
     /* attempt to open /dev/poll device */
     devpoll_fd = open("/dev/poll", O_RDWR);
-    if (devpoll_fd < 0)
-        fatalf("comm_select_init: can't open /dev/poll: %s\n", xstrerror());
+    if (devpoll_fd < 0) {
+        int xerrno = errno;
+        fatalf("comm_select_init: can't open /dev/poll: %s\n", xstrerr(xerrno));
+    }
 
     fd_open(devpoll_fd, FD_UNKNOWN, "devpoll ctl");
 
diff -u -r -N squid-4.0.8/src/comm/ModEpoll.cc squid-4.0.9/src/comm/ModEpoll.cc
--- squid-4.0.8/src/comm/ModEpoll.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ModEpoll.cc	2016-04-21 01:19:59.000000000 +1200
@@ -69,13 +69,15 @@
     pevents = (struct epoll_event *) xmalloc(SQUID_MAXFD * sizeof(struct epoll_event));
 
     if (!pevents) {
-        fatalf("comm_select_init: xmalloc() failed: %s\n",xstrerror());
+        int xerrno = errno;
+        fatalf("comm_select_init: xmalloc() failed: %s\n", xstrerr(xerrno));
     }
 
     kdpfd = epoll_create(SQUID_MAXFD);
 
     if (kdpfd < 0) {
-        fatalf("comm_select_init: epoll_create(): %s\n",xstrerror());
+        int xerrno = errno;
+        fatalf("comm_select_init: epoll_create(): %s\n", xstrerr(xerrno));
     }
 
     commEPollRegisterWithCacheManager();
@@ -168,8 +170,9 @@
         F->epoll_state = ev.events;
 
         if (epoll_ctl(kdpfd, epoll_ctl_type, fd, &ev) < 0) {
-            debugs(5, DEBUG_EPOLL ? 0 : 8, HERE << "epoll_ctl(," << epolltype_atoi(epoll_ctl_type) <<
-                   ",,): failed on FD " << fd << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(5, DEBUG_EPOLL ? 0 : 8, "epoll_ctl(," << epolltype_atoi(epoll_ctl_type) <<
+                   ",,): failed on FD " << fd << ": " << xstrerr(xerrno));
         }
     }
 
diff -u -r -N squid-4.0.8/src/comm/ModPoll.cc squid-4.0.9/src/comm/ModPoll.cc
--- squid-4.0.8/src/comm/ModPoll.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ModPoll.cc	2016-04-21 01:19:59.000000000 +1200
@@ -412,18 +412,19 @@
             PROF_start(comm_poll_normal);
             ++ statCounter.syscalls.selects;
             num = poll(pfds, nfds, msec);
+            int xerrno = errno;
             ++ statCounter.select_loops;
             PROF_stop(comm_poll_normal);
 
             if (num >= 0 || npending > 0)
                 break;
 
-            if (ignoreErrno(errno))
+            if (ignoreErrno(xerrno))
                 continue;
 
-            debugs(5, DBG_CRITICAL, "comm_poll: poll failure: " << xstrerror());
+            debugs(5, DBG_CRITICAL, MYNAME << "poll failure: " << xstrerr(xerrno));
 
-            assert(errno != EINVAL);
+            assert(xerrno != EINVAL);
 
             return Comm::COMM_ERROR;
 
diff -u -r -N squid-4.0.8/src/comm/ModSelect.cc squid-4.0.9/src/comm/ModSelect.cc
--- squid-4.0.8/src/comm/ModSelect.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ModSelect.cc	2016-04-21 01:19:59.000000000 +1200
@@ -434,15 +434,16 @@
             poll_time.tv_usec = (msec % 1000) * 1000;
             ++ statCounter.syscalls.selects;
             num = select(maxfd, &readfds, &writefds, NULL, &poll_time);
+            int xerrno = errno;
             ++ statCounter.select_loops;
 
             if (num >= 0 || pending > 0)
                 break;
 
-            if (ignoreErrno(errno))
+            if (ignoreErrno(xerrno))
                 break;
 
-            debugs(5, DBG_CRITICAL, "comm_select: select failure: " << xstrerror());
+            debugs(5, DBG_CRITICAL, MYNAME << "select failure: " << xstrerr(xerrno));
 
             examine_select(&readfds, &writefds);
 
@@ -712,9 +713,10 @@
             debugs(5, 5, "FD " << fd << " is valid.");
             continue;
         }
+        int xerrno = errno;
 
         F = &fd_table[fd];
-        debugs(5, DBG_CRITICAL, "FD " << fd << ": " << xstrerror());
+        debugs(5, DBG_CRITICAL, "fstat(FD " << fd << "): " << xstrerr(xerrno));
         debugs(5, DBG_CRITICAL, "WARNING: FD " << fd << " has handlers, but it's invalid.");
         debugs(5, DBG_CRITICAL, "FD " << fd << " is a " << fdTypeStr[F->type] << " called '" << F->desc << "'");
         debugs(5, DBG_CRITICAL, "tmout:" << F->timeoutHandler << " read:" << F->read_handler << " write:" << F->write_handler);
diff -u -r -N squid-4.0.8/src/comm/ModSelectWin32.cc squid-4.0.9/src/comm/ModSelectWin32.cc
--- squid-4.0.8/src/comm/ModSelectWin32.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/ModSelectWin32.cc	2016-04-21 01:19:59.000000000 +1200
@@ -425,15 +425,16 @@
             poll_time.tv_usec = (msec % 1000) * 1000;
             ++ statCounter.syscalls.selects;
             num = select(maxfd, &readfds, &writefds, &errfds, &poll_time);
+            int xerrno = errno;
             ++ statCounter.select_loops;
 
             if (num >= 0 || pending > 0)
                 break;
 
-            if (ignoreErrno(errno))
+            if (ignoreErrno(xerrno))
                 break;
 
-            debugs(5, DBG_CRITICAL, "comm_select: select failure: " << xstrerror());
+            debugs(5, DBG_CRITICAL, MYNAME << "WARNING: select failure: " << xstrerr(xerrno));
 
             examine_select(&readfds, &writefds);
 
@@ -723,9 +724,10 @@
             debugs(5, 5, "FD " << fd << " is valid.");
             continue;
         }
+        int xerrno = errno;
 
         F = &fd_table[fd];
-        debugs(5, DBG_CRITICAL, "FD " << fd << ": " << xstrerror());
+        debugs(5, DBG_CRITICAL, "fstat(FD " << fd << "): " << xstrerr(xerrno));
         debugs(5, DBG_CRITICAL, "WARNING: FD " << fd << " has handlers, but it's invalid.");
         debugs(5, DBG_CRITICAL, "FD " << fd << " is a " << fdTypeStr[F->type] << " called '" << F->desc << "'");
         debugs(5, DBG_CRITICAL, "tmout:" << F->timeoutHandler << " read:" << F->read_handler << " write:" << F->write_handler);
diff -u -r -N squid-4.0.8/src/comm/TcpAcceptor.cc squid-4.0.9/src/comm/TcpAcceptor.cc
--- squid-4.0.8/src/comm/TcpAcceptor.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm/TcpAcceptor.cc	2016-04-21 01:19:59.000000000 +1200
@@ -163,14 +163,18 @@
         bzero(&afa, sizeof(afa));
         debugs(5, DBG_IMPORTANT, "Installing accept filter '" << Config.accept_filter << "' on " << conn);
         xstrncpy(afa.af_name, Config.accept_filter, sizeof(afa.af_name));
-        if (setsockopt(conn->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0)
-            debugs(5, DBG_CRITICAL, "WARNING: SO_ACCEPTFILTER '" << Config.accept_filter << "': '" << xstrerror());
+        if (setsockopt(conn->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) {
+            int xerrno = errno;
+            debugs(5, DBG_CRITICAL, "WARNING: SO_ACCEPTFILTER '" << Config.accept_filter << "': '" << xstrerr(xerrno));
+        }
 #elif defined(TCP_DEFER_ACCEPT)
         int seconds = 30;
         if (strncmp(Config.accept_filter, "data=", 5) == 0)
             seconds = atoi(Config.accept_filter + 5);
-        if (setsockopt(conn->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &seconds, sizeof(seconds)) < 0)
-            debugs(5, DBG_CRITICAL, "WARNING: TCP_DEFER_ACCEPT '" << Config.accept_filter << "': '" << xstrerror());
+        if (setsockopt(conn->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &seconds, sizeof(seconds)) < 0) {
+            int xerrno = errno;
+            debugs(5, DBG_CRITICAL, "WARNING: TCP_DEFER_ACCEPT '" << Config.accept_filter << "': '" << xstrerr(xerrno));
+        }
 #else
         debugs(5, DBG_CRITICAL, "WARNING: accept_filter not supported on your OS");
 #endif
@@ -344,14 +348,14 @@
 
         PROF_stop(comm_accept);
 
-        if (ignoreErrno(errno)) {
-            debugs(50, 5, HERE << status() << ": " << xstrerror());
+        if (ignoreErrno(errcode)) {
+            debugs(50, 5, status() << ": " << xstrerr(errcode));
             return Comm::NOMESSAGE;
         } else if (ENFILE == errno || EMFILE == errno) {
-            debugs(50, 3, HERE << status() << ": " << xstrerror());
+            debugs(50, 3, status() << ": " << xstrerr(errcode));
             return Comm::COMM_ERROR;
         } else {
-            debugs(50, DBG_IMPORTANT, HERE << status() << ": " << xstrerror());
+            debugs(50, DBG_IMPORTANT, MYNAME << status() << ": " << xstrerr(errcode));
             return Comm::COMM_ERROR;
         }
     }
@@ -373,7 +377,8 @@
     Ip::Address::InitAddr(gai);
     details->local.setEmpty();
     if (getsockname(sock, gai->ai_addr, &gai->ai_addrlen) != 0) {
-        debugs(50, DBG_IMPORTANT, "ERROR: getsockname() failed to locate local-IP on " << details << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR: getsockname() failed to locate local-IP on " << details << ": " << xstrerr(xerrno));
         Ip::Address::FreeAddr(gai);
         PROF_stop(comm_accept);
         return Comm::COMM_ERROR;
diff -u -r -N squid-4.0.8/src/comm.cc squid-4.0.9/src/comm.cc
--- squid-4.0.8/src/comm.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/comm.cc	2016-04-21 01:19:59.000000000 +1200
@@ -181,7 +181,8 @@
     Ip::Address::InitAddr(addr);
 
     if (getsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) {
-        debugs(50, DBG_IMPORTANT, "comm_local_port: Failed to retrieve TCP/UDP port number for socket: FD " << fd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "Failed to retrieve TCP/UDP port number for socket: FD " << fd << ": " << xstrerr(xerrno));
         Ip::Address::FreeAddr(addr);
         return 0;
     }
@@ -206,11 +207,11 @@
     ++ statCounter.syscalls.sock.binds;
 
     if (bind(s, inaddr.ai_addr, inaddr.ai_addrlen) == 0) {
-        debugs(50, 6, "commBind: bind socket FD " << s << " to " << fd_table[s].local_addr);
+        debugs(50, 6, "bind socket FD " << s << " to " << fd_table[s].local_addr);
         return Comm::OK;
     }
-
-    debugs(50, 0, "commBind: Cannot bind socket FD " << s << " to " << fd_table[s].local_addr << ": " << xstrerror());
+    int xerrno = errno;
+    debugs(50, DBG_CRITICAL, MYNAME << "Cannot bind socket FD " << s << " to " << fd_table[s].local_addr << ": " << xstrerr(xerrno));
 
     return Comm::COMM_ERROR;
 }
@@ -271,10 +272,11 @@
 {
 #ifdef IPV6_V6ONLY
     if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tos, sizeof(int)) < 0) {
-        debugs(50, DBG_IMPORTANT, "comm_open: setsockopt(IPV6_V6ONLY) " << (tos?"ON":"OFF") << " for FD " << fd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(IPV6_V6ONLY) " << (tos?"ON":"OFF") << " for FD " << fd << ": " << xstrerr(xerrno));
     }
 #else
-    debugs(50, 0, "WARNING: comm_open: setsockopt(IPV6_V6ONLY) not supported on this platform");
+    debugs(50, DBG_CRITICAL, MYNAME << "WARNING: setsockopt(IPV6_V6ONLY) not supported on this platform");
 #endif /* sockopt */
 }
 
@@ -311,7 +313,8 @@
 #if defined(soLevel) && defined(soFlag)
     int tos = 1;
     if (setsockopt(fd, soLevel, soFlag, (char *) &tos, sizeof(int)) < 0) {
-        debugs(50, DBG_IMPORTANT, "comm_open: setsockopt(TPROXY) on FD " << fd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(TPROXY) on FD " << fd << ": " << xstrerr(xerrno));
     } else {
         /* mark the socket as having transparent options */
         fd_table[fd].flags.transparent = true;
@@ -347,6 +350,7 @@
     debugs(50, 3, "comm_openex: Attempt open socket for: " << addr );
 
     new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
+    int xerrno = errno;
 
     /* under IPv6 there is the possibility IPv6 is present but disabled. */
     /* try again as IPv4-native if possible */
@@ -357,9 +361,9 @@
         addr.getAddrInfo(AI);
         AI->ai_socktype = sock_type;
         AI->ai_protocol = proto;
-        debugs(50, 3, "comm_openex: Attempt fallback open socket for: " << addr );
+        debugs(50, 3, "Attempt fallback open socket for: " << addr );
         new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
-        debugs(50, 2, HERE << "attempt open " << note << " socket on: " << addr);
+        debugs(50, 2, "attempt open " << note << " socket on: " << addr);
     }
 
     if (new_socket < 0) {
@@ -368,15 +372,16 @@
          * limits the number of simultaneous clients */
 
         if (limitError(errno)) {
-            debugs(50, DBG_IMPORTANT, "comm_open: socket failure: " << xstrerror());
+            debugs(50, DBG_IMPORTANT, MYNAME << "socket failure: " << xstrerr(xerrno));
             fdAdjustReserved();
         } else {
-            debugs(50, DBG_CRITICAL, "comm_open: socket failure: " << xstrerror());
+            debugs(50, DBG_CRITICAL, MYNAME << "socket failure: " << xstrerr(xerrno));
         }
 
         Ip::Address::FreeAddr(AI);
 
         PROF_stop(comm_open);
+        errno = xerrno; // restore for caller
         return -1;
     }
 
@@ -404,6 +409,7 @@
 
     // XXX transition only. prevent conn from closing the new FD on function exit.
     conn->fd = -1;
+    errno = xerrno; // restore for caller
     return new_socket;
 }
 
@@ -737,12 +743,11 @@
 commLingerClose(int fd, void *unused)
 {
     LOCAL_ARRAY(char, buf, 1024);
-    int n;
-    n = FD_READ_METHOD(fd, buf, 1024);
-
-    if (n < 0)
-        debugs(5, 3, "commLingerClose: FD " << fd << " read: " << xstrerror());
-
+    int n = FD_READ_METHOD(fd, buf, 1024);
+    if (n < 0) {
+        int xerrno = errno;
+        debugs(5, 3, "FD " << fd << " read: " << xstrerr(xerrno));
+    }
     comm_close(fd);
 }
 
@@ -798,9 +803,10 @@
     L.l_onoff = 1;
     L.l_linger = 0;
 
-    if (setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0)
-        debugs(50, DBG_CRITICAL, "ERROR: Closing " << conn << " with TCP RST: " << xstrerror());
-
+    if (setsockopt(conn->fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "ERROR: Closing " << conn << " with TCP RST: " << xstrerr(xerrno));
+    }
     conn->close();
 }
 
@@ -812,9 +818,10 @@
     L.l_onoff = 1;
     L.l_linger = 0;
 
-    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0)
-        debugs(50, DBG_CRITICAL, "ERROR: Closing FD " << fd << " with TCP RST: " << xstrerror());
-
+    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "ERROR: Closing FD " << fd << " with TCP RST: " << xstrerr(xerrno));
+    }
     comm_close(fd);
 }
 
@@ -955,20 +962,22 @@
     struct addrinfo *AI = NULL;
     to_addr.getAddrInfo(AI, fd_table[fd].sock_family);
     int x = sendto(fd, buf, len, 0, AI->ai_addr, AI->ai_addrlen);
+    int xerrno = errno;
     Ip::Address::FreeAddr(AI);
 
     PROF_stop(comm_udp_sendto);
 
-    if (x >= 0)
+    if (x >= 0) {
+        errno = xerrno; // restore for caller to use
         return x;
+    }
 
 #if _SQUID_LINUX_
-
-    if (ECONNREFUSED != errno)
+    if (ECONNREFUSED != xerrno)
 #endif
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", (family=" << fd_table[fd].sock_family << ") " << to_addr << ": " << xstrerr(xerrno));
 
-        debugs(50, DBG_IMPORTANT, "comm_udp_sendto: FD " << fd << ", (family=" << fd_table[fd].sock_family << ") " << to_addr << ": " << xstrerror());
-
+    errno = xerrno; // restore for caller to use
     return Comm::COMM_ERROR;
 }
 
@@ -1051,9 +1060,10 @@
     L.l_onoff = 0;      /* off */
     L.l_linger = 0;
 
-    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0)
-        debugs(50, 0, "commSetNoLinger: FD " << fd << ": " << xstrerror());
-
+    if (setsockopt(fd, SOL_SOCKET, SO_LINGER, (char *) &L, sizeof(L)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+    }
     fd_table[fd].flags.nolinger = true;
 }
 
@@ -1061,21 +1071,28 @@
 commSetReuseAddr(int fd)
 {
     int on = 1;
-
-    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0)
-        debugs(50, DBG_IMPORTANT, "commSetReuseAddr: FD " << fd << ": " << xstrerror());
+    if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+    }
 }
 
 static void
 commSetTcpRcvbuf(int fd, int size)
 {
-    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) < 0)
-        debugs(50, DBG_IMPORTANT, "commSetTcpRcvbuf: FD " << fd << ", SIZE " << size << ": " << xstrerror());
-    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) < 0)
-        debugs(50, DBG_IMPORTANT, "commSetTcpRcvbuf: FD " << fd << ", SIZE " << size << ": " << xstrerror());
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
+    }
+    if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &size, sizeof(size)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
+    }
 #ifdef TCP_WINDOW_CLAMP
-    if (setsockopt(fd, SOL_TCP, TCP_WINDOW_CLAMP, (char *) &size, sizeof(size)) < 0)
-        debugs(50, DBG_IMPORTANT, "commSetTcpRcvbuf: FD " << fd << ", SIZE " << size << ": " << xstrerror());
+    if (setsockopt(fd, SOL_TCP, TCP_WINDOW_CLAMP, (char *) &size, sizeof(size)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno));
+    }
 #endif
 }
 
@@ -1086,7 +1103,8 @@
     int nonblocking = TRUE;
 
     if (ioctl(fd, FIONBIO, &nonblocking) < 0) {
-        debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror() << " " << fd_table[fd].type);
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": " << xstrerr(xerrno) << " " << fd_table[fd].type);
         return Comm::COMM_ERROR;
     }
 
@@ -1095,12 +1113,14 @@
     int dummy = 0;
 
     if ((flags = fcntl(fd, F_GETFL, dummy)) < 0) {
-        debugs(50, 0, "FD " << fd << ": fcntl F_GETFL: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": fcntl F_GETFL: " << xstrerr(xerrno));
         return Comm::COMM_ERROR;
     }
 
     if (fcntl(fd, F_SETFL, flags | SQUID_NONBLOCK) < 0) {
-        debugs(50, 0, "commSetNonBlocking: FD " << fd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
         return Comm::COMM_ERROR;
     }
 #endif
@@ -1121,13 +1141,15 @@
     int dummy = 0;
 
     if ((flags = fcntl(fd, F_GETFL, dummy)) < 0) {
-        debugs(50, 0, "FD " << fd << ": fcntl F_GETFL: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": fcntl F_GETFL: " << xstrerr(xerrno));
         return Comm::COMM_ERROR;
     }
 
     if (fcntl(fd, F_SETFL, flags & (~SQUID_NONBLOCK)) < 0) {
 #endif
-        debugs(50, 0, "commUnsetNonBlocking: FD " << fd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
         return Comm::COMM_ERROR;
     }
 
@@ -1143,12 +1165,15 @@
     int dummy = 0;
 
     if ((flags = fcntl(fd, F_GETFD, dummy)) < 0) {
-        debugs(50, 0, "FD " << fd << ": fcntl F_GETFD: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": fcntl F_GETFD: " << xstrerr(xerrno));
         return;
     }
 
-    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
-        debugs(50, 0, "FD " << fd << ": set close-on-exec failed: " << xstrerror());
+    if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "FD " << fd << ": set close-on-exec failed: " << xstrerr(xerrno));
+    }
 
     fd_table[fd].flags.close_on_exec = true;
 
@@ -1161,8 +1186,10 @@
 {
     int on = 1;
 
-    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0)
-        debugs(50, DBG_IMPORTANT, "commSetTcpNoDelay: FD " << fd << ": " << xstrerror());
+    if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+    }
 
     fd_table[fd].flags.nodelay = true;
 }
@@ -1176,24 +1203,32 @@
 #ifdef TCP_KEEPCNT
     if (timeout && interval) {
         int count = (timeout + interval - 1) / interval;
-        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(on)) < 0)
-            debugs(5, DBG_IMPORTANT, "commSetKeepalive: FD " << fd << ": " << xstrerror());
+        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(on)) < 0) {
+            int xerrno = errno;
+            debugs(5, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+        }
     }
 #endif
 #ifdef TCP_KEEPIDLE
     if (idle) {
-        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(on)) < 0)
-            debugs(5, DBG_IMPORTANT, "commSetKeepalive: FD " << fd << ": " << xstrerror());
+        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(on)) < 0) {
+            int xerrno = errno;
+            debugs(5, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+        }
     }
 #endif
 #ifdef TCP_KEEPINTVL
     if (interval) {
-        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(on)) < 0)
-            debugs(5, DBG_IMPORTANT, "commSetKeepalive: FD " << fd << ": " << xstrerror());
+        if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(on)) < 0) {
+            int xerrno = errno;
+            debugs(5, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+        }
     }
 #endif
-    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0)
-        debugs(5, DBG_IMPORTANT, "commSetKeepalive: FD " << fd << ": " << xstrerror());
+    if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) {
+        int xerrno = errno;
+        debugs(5, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno));
+    }
 }
 
 void
@@ -1873,15 +1908,16 @@
     debugs(50, 3, HERE << "Attempt open socket for: " << addr->sun_path);
 
     if ((new_socket = socket(AI.ai_family, AI.ai_socktype, AI.ai_protocol)) < 0) {
+        int xerrno = errno;
         /* Increase the number of reserved fd's if calls to socket()
          * are failing because the open file table is full.  This
          * limits the number of simultaneous clients */
 
-        if (limitError(errno)) {
-            debugs(50, DBG_IMPORTANT, HERE << "socket failure: " << xstrerror());
+        if (limitError(xerrno)) {
+            debugs(50, DBG_IMPORTANT, MYNAME << "socket failure: " << xstrerr(xerrno));
             fdAdjustReserved();
         } else {
-            debugs(50, DBG_CRITICAL, HERE << "socket failure: " << xstrerror());
+            debugs(50, DBG_CRITICAL, MYNAME << "socket failure: " << xstrerr(xerrno));
         }
 
         PROF_stop(comm_open);
diff -u -r -N squid-4.0.8/src/CpuAffinitySet.cc squid-4.0.9/src/CpuAffinitySet.cc
--- squid-4.0.8/src/CpuAffinitySet.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/CpuAffinitySet.cc	2016-04-21 01:19:59.000000000 +1200
@@ -31,9 +31,10 @@
 
     bool success = false;
     if (sched_getaffinity(0, sizeof(theOrigCpuSet), &theOrigCpuSet)) {
+        int xerrno = errno;
         debugs(54, DBG_IMPORTANT, "ERROR: failed to get CPU affinity for "
                "process PID " << getpid() << ", ignoring CPU affinity for "
-               "this process: " << xstrerror());
+               "this process: " << xstrerr(xerrno));
     } else {
         cpu_set_t cpuSet;
         memcpy(&cpuSet, &theCpuSet, sizeof(cpuSet));
@@ -43,8 +44,9 @@
                    "PID " << getpid() << ", may be caused by an invalid core in "
                    "'cpu_affinity_map' or by external affinity restrictions");
         } else if (sched_setaffinity(0, sizeof(cpuSet), &cpuSet)) {
+            int xerrno = errno;
             debugs(54, DBG_IMPORTANT, "ERROR: failed to set CPU affinity for "
-                   "process PID " << getpid() << ": " << xstrerror());
+                   "process PID " << getpid() << ": " << xstrerr(xerrno));
         } else
             success = true;
     }
@@ -57,9 +59,10 @@
 {
     if (applied()) {
         if (sched_setaffinity(0, sizeof(theOrigCpuSet), &theOrigCpuSet)) {
+            int xerrno = errno;
             debugs(54, DBG_IMPORTANT, "ERROR: failed to restore original CPU "
                    "affinity for process PID " << getpid() << ": " <<
-                   xstrerror());
+                   xstrerr(xerrno));
         }
         CPU_ZERO(&theOrigCpuSet);
     }
diff -u -r -N squid-4.0.8/src/DiskIO/AIO/AIODiskFile.cc squid-4.0.9/src/DiskIO/AIO/AIODiskFile.cc
--- squid-4.0.8/src/DiskIO/AIO/AIODiskFile.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/AIO/AIODiskFile.cc	2016-04-21 01:19:59.000000000 +1200
@@ -132,8 +132,9 @@
 
     /* Initiate aio */
     if (aio_read(&qe->aq_e_aiocb) < 0) {
-        fatalf("Aiee! aio_read() returned error (%d)  FIXME and wrap file_read !\n", errno);
-        debugs(79, DBG_IMPORTANT, "WARNING: aio_read() returned error: " << xstrerror());
+        int xerrno = errno;
+        fatalf("Aiee! aio_read() returned error (%d)  FIXME and wrap file_read !\n", xerrno);
+        debugs(79, DBG_IMPORTANT, "WARNING: aio_read() returned error: " << xstrerr(xerrno));
         /* fall back to blocking method */
         //        file_read(fd, request->buf, request->len, request->offset, callback, data);
     }
@@ -190,8 +191,9 @@
 
     /* Initiate aio */
     if (aio_write(&qe->aq_e_aiocb) < 0) {
-        fatalf("Aiee! aio_write() returned error (%d) FIXME and wrap file_write !\n", errno);
-        debugs(79, DBG_IMPORTANT, "WARNING: aio_write() returned error: " << xstrerror());
+        int xerrno = errno;
+        fatalf("Aiee! aio_write() returned error (%d) FIXME and wrap file_write !\n", xerrno);
+        debugs(79, DBG_IMPORTANT, "WARNING: aio_write() returned error: " << xstrerr(xerrno));
         /* fall back to blocking method */
         //       file_write(fd, offset, buf, len, callback, data, freefunc);
     }
diff -u -r -N squid-4.0.8/src/DiskIO/DiskDaemon/diskd.cc squid-4.0.9/src/DiskIO/DiskDaemon/diskd.cc
--- squid-4.0.8/src/DiskIO/DiskDaemon/diskd.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/DiskDaemon/diskd.cc	2016-04-21 01:19:59.000000000 +1200
@@ -350,7 +350,7 @@
     hash = hash_create(fsCmp, 1 << 4, fsHash);
     assert(hash);
     if (fcntl(0, F_SETFL, SQUID_NONBLOCK) < 0) {
-        perror(xstrerror());
+        perror(xstrerr(errno));
         return 1;
     }
     memset(&sa, '\0', sizeof(sa));
diff -u -r -N squid-4.0.8/src/DiskIO/DiskDaemon/DiskdFile.cc squid-4.0.9/src/DiskIO/DiskDaemon/DiskdFile.cc
--- squid-4.0.8/src/DiskIO/DiskDaemon/DiskdFile.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/DiskDaemon/DiskdFile.cc	2016-04-21 01:19:59.000000000 +1200
@@ -101,10 +101,11 @@
                      NULL);
 
     if (x < 0) {
+        int xerrno = errno;
         ioCompleted();
         errorOccured = true;
         //        IO->shm.put (shm_offset);
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerror());
+        debugs(79, DBG_IMPORTANT, "storeDiskdSend CREATE: " << xstrerr(xerrno));
         notifyClient();
         ioRequestor = NULL;
         return;
@@ -130,10 +131,11 @@
                      aRead);
 
     if (x < 0) {
+        int xerrno = errno;
         ioCompleted();
         errorOccured = true;
         //        IO->shm.put (shm_offset);
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerror());
+        debugs(79, DBG_IMPORTANT, "storeDiskdSend READ: " << xstrerr(xerrno));
         notifyClient();
         ioRequestor = NULL;
         return;
@@ -157,9 +159,10 @@
                      NULL);
 
     if (x < 0) {
+        int xerrno = errno;
         ioCompleted();
         errorOccured = true;
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerror());
+        debugs(79, DBG_IMPORTANT, "storeDiskdSend CLOSE: " << xstrerr(xerrno));
         notifyClient();
         ioRequestor = NULL;
         return;
@@ -294,9 +297,10 @@
                      aRequest);
 
     if (x < 0) {
+        int xerrno = errno;
         ioCompleted();
         errorOccured = true;
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerror());
+        debugs(79, DBG_IMPORTANT, "storeDiskdSend WRITE: " << xstrerr(xerrno));
         //        IO->shm.put (shm_offset);
         notifyClient();
         ioRequestor = NULL;
diff -u -r -N squid-4.0.8/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc squid-4.0.9/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc
--- squid-4.0.8/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc	2016-04-21 01:19:59.000000000 +1200
@@ -124,7 +124,8 @@
              shm_offset);
 
     if (x < 0) {
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend UNLINK: " << xstrerror());
+        int xerrno = errno;
+        debugs(79, DBG_IMPORTANT, "storeDiskdSend UNLINK: " << xstrerr(xerrno));
         ::unlink(buf);      /* XXX EWW! */
         //        shm.put (shm_offset);
     }
@@ -150,14 +151,16 @@
     smsgid = msgget((key_t) ikey, 0700 | IPC_CREAT);
 
     if (smsgid < 0) {
-        debugs(50, DBG_CRITICAL, "storeDiskdInit: msgget: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "msgget: " << xstrerr(xerrno));
         fatal("msgget failed");
     }
 
     rmsgid = msgget((key_t) (ikey + 1), 0700 | IPC_CREAT);
 
     if (rmsgid < 0) {
-        debugs(50, DBG_CRITICAL, "storeDiskdInit: msgget: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "msgget: " << xstrerr(xerrno));
         fatal("msgget failed");
     }
 
@@ -248,14 +251,16 @@
                 nbufs * SHMBUF_BLKSZ, 0600 | IPC_CREAT);
 
     if (id < 0) {
-        debugs(50, DBG_CRITICAL, "storeDiskdInit: shmget: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "shmget: " << xstrerr(xerrno));
         fatal("shmget failed");
     }
 
     buf = (char *)shmat(id, NULL, 0);
 
     if (buf == (void *) -1) {
-        debugs(50, DBG_CRITICAL, "storeDiskdInit: shmat: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "shmat: " << xstrerr(xerrno));
         fatal("shmat failed");
     }
 
@@ -380,7 +385,8 @@
         ++diskd_stats.sent_count;
         ++away;
     } else {
-        debugs(79, DBG_IMPORTANT, "storeDiskdSend: msgsnd: " << xstrerror());
+        int xerrno = errno;
+        debugs(79, DBG_IMPORTANT, MYNAME << "msgsnd: " << xstrerr(xerrno));
         cbdataReferenceDone(M->callback_data);
         ++send_errors;
         assert(send_errors < 100);
diff -u -r -N squid-4.0.8/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc squid-4.0.9/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc
--- squid-4.0.8/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/DiskThreads/DiskThreadsDiskFile.cc	2016-04-21 01:19:59.000000000 +1200
@@ -143,8 +143,7 @@
     fd = anFD;
 
     if (errflag || fd < 0) {
-        errno = errflag;
-        debugs(79, DBG_CRITICAL, "DiskThreadsDiskFile::openDone: " << xstrerror());
+        debugs(79, DBG_CRITICAL, MYNAME << xstrerr(errflag));
         debugs(79, DBG_IMPORTANT, "\t" << path_);
         errorOccured = true;
     } else {
diff -u -r -N squid-4.0.8/src/DiskIO/Mmapped/MmappedFile.cc squid-4.0.9/src/DiskIO/Mmapped/MmappedFile.cc
--- squid-4.0.8/src/DiskIO/Mmapped/MmappedFile.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/DiskIO/Mmapped/MmappedFile.cc	2016-04-21 01:19:59.000000000 +1200
@@ -78,11 +78,12 @@
     ioRequestor = callback;
 
     if (fd < 0) {
-        debugs(79,3, HERE << "open error: " << xstrerror());
+        int xerrno = errno;
+        debugs(79,3, "open error: " << xstrerr(xerrno));
         error_ = true;
     } else {
         ++store_open_disk_fd;
-        debugs(79,3, HERE << "FD " << fd);
+        debugs(79,3, "FD " << fd);
 
         // setup mapping boundaries
         struct stat sb;
diff -u -r -N squid-4.0.8/src/dns_internal.cc squid-4.0.9/src/dns_internal.cc
--- squid-4.0.8/src/dns_internal.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/dns_internal.cc	2016-04-21 01:19:59.000000000 +1200
@@ -433,8 +433,9 @@
 #if !_SQUID_WINDOWS_
     FILE *fp = fopen(_PATH_RESCONF, "r");
 
-    if (fp == NULL) {
-        debugs(78, DBG_IMPORTANT, "" << _PATH_RESCONF << ": " << xstrerror());
+    if (!fp) {
+        int xerrno = errno;
+        debugs(78, DBG_IMPORTANT, "" << _PATH_RESCONF << ": " << xstrerr(xerrno));
         return false;
     }
 
@@ -994,15 +995,16 @@
             else if (DnsSocketA >= 0)
                 x = comm_udp_sendto(DnsSocketA, nameservers[nsn].S, q->buf, q->sz);
         }
+        int xerrno = errno;
 
         ++ q->nsends;
 
         q->sent_t = current_time;
 
         if (y < 0 && nameservers[nsn].S.isIPv6())
-            debugs(50, DBG_IMPORTANT, "idnsSendQuery: FD " << DnsSocketB << ": sendto: " << xstrerror());
+            debugs(50, DBG_IMPORTANT, MYNAME << "FD " << DnsSocketB << ": sendto: " << xstrerr(xerrno));
         if (x < 0 && nameservers[nsn].S.isIPv4())
-            debugs(50, DBG_IMPORTANT, "idnsSendQuery: FD " << DnsSocketA << ": sendto: " << xstrerror());
+            debugs(50, DBG_IMPORTANT, MYNAME << "FD " << DnsSocketA << ": sendto: " << xstrerr(xerrno));
 
     } while ( (x<0 && y<0) && q->nsends % nns != 0);
 
@@ -1350,7 +1352,8 @@
             break;
 
         if (len < 0) {
-            if (ignoreErrno(errno))
+            int xerrno = errno;
+            if (ignoreErrno(xerrno))
                 break;
 
 #if _SQUID_LINUX_
@@ -1358,10 +1361,9 @@
              * return ECONNREFUSED when sendto() fails and generates an ICMP
              * port unreachable message. */
             /* or maybe an EHOSTUNREACH "No route to host" message */
-            if (errno != ECONNREFUSED && errno != EHOSTUNREACH)
+            if (xerrno != ECONNREFUSED && xerrno != EHOSTUNREACH)
 #endif
-
-                debugs(50, DBG_IMPORTANT, "idnsRead: FD " << fd << " recvfrom: " << xstrerror());
+                debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << " recvfrom: " << xstrerr(xerrno));
 
             break;
         }
diff -u -r -N squid-4.0.8/src/errorpage.cc squid-4.0.9/src/errorpage.cc
--- squid-4.0.8/src/errorpage.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/errorpage.cc	2016-04-21 01:19:59.000000000 +1200
@@ -330,15 +330,17 @@
 
     if (fd < 0) {
         /* with dynamic locale negotiation we may see some failures before a success. */
-        if (!silent && templateCode < TCP_RESET)
-            debugs(4, DBG_CRITICAL, HERE << "'" << path << "': " << xstrerror());
+        if (!silent && templateCode < TCP_RESET) {
+            int xerrno = errno;
+            debugs(4, DBG_CRITICAL, MYNAME << "'" << path << "': " << xstrerr(xerrno));
+        }
         wasLoaded = false;
         return wasLoaded;
     }
 
     while ((len = FD_READ_METHOD(fd, buf, sizeof(buf))) > 0) {
         if (!parse(buf, len, false)) {
-            debugs(4, DBG_CRITICAL, HERE << " parse error while reading template file: " << path);
+            debugs(4, DBG_CRITICAL, MYNAME << "parse error while reading template file: " << path);
             wasLoaded = false;
             return wasLoaded;
         }
@@ -346,7 +348,8 @@
     parse(buf, 0, true);
 
     if (len < 0) {
-        debugs(4, DBG_CRITICAL, HERE << "failed to fully read: '" << path << "': " << xstrerror());
+        int xerrno = errno;
+        debugs(4, DBG_CRITICAL, MYNAME << "ERROR: failed to fully read: '" << path << "': " << xstrerr(xerrno));
     }
 
     file_close(fd);
@@ -924,6 +927,9 @@
             p = "[unknown method]";
         break;
 
+    case 'O':
+        if (!building_deny_info_url)
+            do_quote = 0;
     case 'o':
         p = request ? request->extacl_message.termedBuf() : external_acl_message;
         if (!p && !building_deny_info_url)
diff -u -r -N squid-4.0.8/src/esi/Esi.cc squid-4.0.9/src/esi/Esi.cc
--- squid-4.0.8/src/esi/Esi.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/esi/Esi.cc	2016-04-21 01:19:59.000000000 +1200
@@ -953,7 +953,7 @@
     ESIElement::Pointer element;
     int specifiedattcount = attrCount * 2;
     char *position;
-    assert (ellen < sizeof (localbuf)); /* prevent unexpected overruns. */
+    Must(ellen < sizeof(localbuf)); /* prevent unexpected overruns. */
 
     debugs(86, 5, "ESIContext::Start: element '" << el << "' with " << specifiedattcount << " tags");
 
@@ -967,15 +967,17 @@
         /* Spit out elements we aren't interested in */
         localbuf[0] = '<';
         localbuf[1] = '\0';
-        assert (xstrncpy (&localbuf[1], el, sizeof(localbuf) - 2));
+        xstrncpy(&localbuf[1], el, sizeof(localbuf) - 2);
         position = localbuf + strlen (localbuf);
 
         for (i = 0; i < specifiedattcount && attr[i]; i += 2) {
+            Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 1);
             *position = ' ';
             ++position;
             /* TODO: handle thisNode gracefully */
-            assert (xstrncpy (position, attr[i], sizeof(localbuf) + (position - localbuf)));
+            xstrncpy(position, attr[i], sizeof(localbuf) - (position - localbuf));
             position += strlen (position);
+            Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 2);
             *position = '=';
             ++position;
             *position = '\"';
@@ -984,18 +986,21 @@
             char ch;
             while ((ch = *chPtr++) != '\0') {
                 if (ch == '\"') {
-                    assert( xstrncpy(position, "&quot;", sizeof(localbuf) + (position-localbuf)) );
+                    Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 6);
+                    xstrncpy(position, "&quot;", sizeof(localbuf) - (position-localbuf));
                     position += 6;
                 } else {
+                    Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 1);
                     *position = ch;
                     ++position;
                 }
             }
-            position += strlen (position);
+            Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 1);
             *position = '\"';
             ++position;
         }
 
+        Must(static_cast<size_t>(position - localbuf) < sizeof(localbuf) - 2);
         *position = '>';
         ++position;
         *position = '\0';
@@ -1081,11 +1086,11 @@
     switch (ESIElement::IdentifyElement (el)) {
 
     case ESIElement::ESI_ELEMENT_NONE:
-        assert (ellen < sizeof (localbuf)); /* prevent unexpected overruns. */
+        Must(ellen < sizeof(localbuf) - 3); /* prevent unexpected overruns. */
         /* Add elements we aren't interested in */
         localbuf[0] = '<';
         localbuf[1] = '/';
-        assert (xstrncpy (&localbuf[2], el, sizeof(localbuf) - 3));
+        xstrncpy(&localbuf[2], el, sizeof(localbuf) - 3);
         position = localbuf + strlen (localbuf);
         *position = '>';
         ++position;
diff -u -r -N squid-4.0.8/src/eui/Eui48.cc squid-4.0.9/src/eui/Eui48.cc
--- squid-4.0.8/src/eui/Eui48.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/eui/Eui48.cc	2016-04-21 01:19:59.000000000 +1200
@@ -148,7 +148,8 @@
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
     if (tmpSocket < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerr(xerrno));
         clear();
         return false;
     }
@@ -204,7 +205,8 @@
     ifc.ifc_buf = (char *)ifbuffer;
 
     if (ioctl(tmpSocket, SIOCGIFCONF, &ifc) < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to retrieve interface list failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to retrieve interface list failed: " << xstrerr(xerrno));
         clear();
         close(tmpSocket);
         return false;
@@ -249,17 +251,10 @@
 
         /* Query ARP table */
         if (-1 == ioctl(tmpSocket, SIOCGARP, &arpReq)) {
-            /*
-             * Query failed.  Do not log failed lookups or "device
-             * not supported"
-             */
-
-            if (ENXIO == errno)
-                (void) 0;
-            else if (ENODEV == errno)
-                (void) 0;
-            else
-                debugs(28, DBG_IMPORTANT, "ARP query " << ipAddr << " failed: " << ifr->ifr_name << ": " << xstrerror());
+            int xerrno = errno;
+            //  Query failed.  Do not log failed lookups or "device not supported"
+            if (ENXIO != xerrno && ENODEV != xerrno)
+                debugs(28, DBG_IMPORTANT, "ARP query " << ipAddr << " failed: " << ifr->ifr_name << ": " << xstrerr(xerrno));
 
             continue;
         }
@@ -298,7 +293,8 @@
     /* IPv6 builds do not provide the first http_port as an IPv4 socket for ARP */
     int tmpSocket = socket(AF_INET,SOCK_STREAM,0);
     if (tmpSocket < 0) {
-        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(28, DBG_IMPORTANT, "Attempt to open socket for EUI retrieval failed: " << xstrerr(xerrno));
         clear();
         return false;
     }
diff -u -r -N squid-4.0.8/src/fs/rock/RockSwapDir.cc squid-4.0.9/src/fs/rock/RockSwapDir.cc
--- squid-4.0.8/src/fs/rock/RockSwapDir.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/fs/rock/RockSwapDir.cc	2016-04-21 01:19:59.000000000 +1200
@@ -291,8 +291,9 @@
 void
 Rock::SwapDir::createError(const char *const msg)
 {
+    int xerrno = errno; // XXX: where does errno come from?
     debugs(47, DBG_CRITICAL, "ERROR: Failed to initialize Rock Store db in " <<
-           filePath << "; " << msg << " error: " << xstrerror());
+           filePath << "; " << msg << " error: " << xstrerr(xerrno));
     fatal("Rock Store db creation error");
 }
 
@@ -814,9 +815,11 @@
     if (!theFile)
         fatalf("Rock cache_dir failed to initialize db file: %s", filePath);
 
-    if (theFile->error())
+    if (theFile->error()) {
+        int xerrno = errno; // XXX: where does errno come from
         fatalf("Rock cache_dir at %s failed to open db file: %s", filePath,
-               xstrerror());
+               xstrerr(xerrno));
+    }
 
     debugs(47, 2, "Rock cache_dir[" << index << "] limits: " <<
            std::setw(12) << maxSize() << " disk bytes, " <<
diff -u -r -N squid-4.0.8/src/fs/ufs/RebuildState.cc squid-4.0.9/src/fs/ufs/RebuildState.cc
--- squid-4.0.8/src/fs/ufs/RebuildState.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/fs/ufs/RebuildState.cc	2016-04-21 01:19:59.000000000 +1200
@@ -169,7 +169,8 @@
     ++n_read;
 
     if (fstat(fd, &sb) < 0) {
-        debugs(47, DBG_IMPORTANT, HERE << "fstat(FD " << fd << "): " << xstrerror());
+        int xerrno = errno;
+        debugs(47, DBG_IMPORTANT, MYNAME << "fstat(FD " << fd << "): " << xstrerr(xerrno));
         file_close(fd);
         --store_open_disk_fd;
         fd = -1;
@@ -471,8 +472,9 @@
 
             ++dirs_opened;
 
-            if (td == NULL) {
-                debugs(47, DBG_IMPORTANT, HERE << "error in opendir (" << fullpath << "): " << xstrerror());
+            if (!td) {
+                int xerrno = errno;
+                debugs(47, DBG_IMPORTANT, MYNAME << "error in opendir (" << fullpath << "): " << xstrerr(xerrno));
             } else {
                 entry = readdir(td);    /* skip . and .. */
                 entry = readdir(td);
@@ -510,9 +512,10 @@
             debugs(47, 3, HERE << "Opening " << fullfilename);
             fd = file_open(fullfilename, O_RDONLY | O_BINARY);
 
-            if (fd < 0)
-                debugs(47, DBG_IMPORTANT, HERE << "error opening " << fullfilename << ": " << xstrerror());
-            else
+            if (fd < 0) {
+                int xerrno = errno;
+                debugs(47, DBG_IMPORTANT, MYNAME << "error opening " << fullfilename << ": " << xstrerr(xerrno));
+            } else
                 ++store_open_disk_fd;
 
             continue;
diff -u -r -N squid-4.0.8/src/fs/ufs/UFSSwapDir.cc squid-4.0.9/src/fs/ufs/UFSSwapDir.cc
--- squid-4.0.8/src/fs/ufs/UFSSwapDir.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/fs/ufs/UFSSwapDir.cc	2016-04-21 01:19:59.000000000 +1200
@@ -100,9 +100,10 @@
 
     if (outbuf_offset + ss >= CLEAN_BUF_SZ) {
         if (FD_WRITE_METHOD(fd, outbuf, outbuf_offset) < 0) {
+            int xerrno = errno;
             /* XXX This error handling should probably move up to the caller */
-            debugs(50, DBG_CRITICAL, HERE << newLog << ": write: " << xstrerror());
-            debugs(50, DBG_CRITICAL, HERE << "Current swap logfile not replaced.");
+            debugs(50, DBG_CRITICAL, MYNAME << newLog << ": write: " << xstrerr(xerrno));
+            debugs(50, DBG_CRITICAL, MYNAME << "Current swap logfile not replaced.");
             file_close(fd);
             fd = -1;
             unlink(newLog);
@@ -617,8 +618,8 @@
         debugs(47, (should_exist ? DBG_IMPORTANT : 3), aPath << " created");
         created = 1;
     } else {
-        fatalf("Failed to make swap directory %s: %s",
-               aPath, xstrerror());
+        int xerrno = errno;
+        fatalf("Failed to make swap directory %s: %s", aPath, xstrerr(xerrno));
     }
 
     return created;
@@ -631,7 +632,8 @@
     struct stat sb;
 
     if (::stat(aPath, &sb) < 0) {
-        debugs(47, DBG_CRITICAL, "ERROR: " << aPath << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(47, DBG_CRITICAL, "ERROR: " << aPath << ": " << xstrerr(xerrno));
         return false;
     }
 
@@ -728,7 +730,8 @@
     swaplog_fd = file_open(logPath, O_WRONLY | O_CREAT | O_BINARY);
 
     if (swaplog_fd < 0) {
-        debugs(50, DBG_IMPORTANT, "ERROR opening swap log " << logPath << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR opening swap log " << logPath << ": " << xstrerr(xerrno));
         fatal("UFSSwapDir::openLog: Failed to open swap log.");
     }
 
@@ -851,7 +854,8 @@
     fd = file_open(swaplog_path, O_WRONLY | O_CREAT | O_BINARY);
 
     if (fd < 0) {
-        debugs(50, DBG_IMPORTANT, "ERROR: " << swaplog_path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR: " << swaplog_path << ": " << xstrerr(xerrno));
         fatalf("Failed to open swap log %s", swaplog_path);
     }
 
@@ -892,7 +896,8 @@
     fd = file_open(new_path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
 
     if (fd < 0) {
-        debugs(50, DBG_IMPORTANT, "ERROR: while opening swap log" << new_path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR: while opening swap log" << new_path << ": " << xstrerr(xerrno));
         fatalf("Failed to open swap log %s", new_path);
     }
 
@@ -913,8 +918,9 @@
     /* open a read-only stream of the old log */
     fp = fopen(swaplog_path, "rb");
 
-    if (fp == NULL) {
-        debugs(50, DBG_CRITICAL, "ERROR: while opening " << swaplog_path << ": " << xstrerror());
+    if (!fp) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "ERROR: while opening " << swaplog_path << ": " << xstrerr(xerrno));
         fatalf("Failed to open swap log for reading %s", swaplog_path);
     }
 
@@ -1002,8 +1008,9 @@
     state->walker->Done(state->walker);
 
     if (FD_WRITE_METHOD(state->fd, state->outbuf, state->outbuf_offset) < 0) {
-        debugs(50, DBG_CRITICAL, HERE << state->newLog << ": write: " << xstrerror());
-        debugs(50, DBG_CRITICAL, HERE << "Current swap logfile not replaced.");
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << state->newLog << ": write: " << xstrerr(xerrno));
+        debugs(50, DBG_CRITICAL, MYNAME << "Current swap logfile not replaced.");
         file_close(state->fd);
         state->fd = -1;
         ::unlink(state->newLog);
@@ -1327,14 +1334,15 @@
     debugs(36, 3, HERE << "Cleaning directory " << p1);
     dir_pointer = opendir(p1);
 
-    if (dir_pointer == NULL) {
-        if (errno == ENOENT) {
-            debugs(36, DBG_CRITICAL, HERE << "WARNING: Creating " << p1);
+    if (!dir_pointer) {
+        int xerrno = errno;
+        if (xerrno == ENOENT) {
+            debugs(36, DBG_CRITICAL, MYNAME << "WARNING: Creating " << p1);
             if (mkdir(p1, 0777) == 0)
                 return 0;
         }
 
-        debugs(50, DBG_CRITICAL, HERE << p1 << ": " << xstrerror());
+        debugs(50, DBG_CRITICAL, MYNAME << p1 << ": " << xstrerr(xerrno));
         safeunlink(p1, 1);
         return 0;
     }
diff -u -r -N squid-4.0.8/src/fs_io.cc squid-4.0.9/src/fs_io.cc
--- squid-4.0.8/src/fs_io.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/fs_io.cc	2016-04-21 01:19:59.000000000 +1200
@@ -58,10 +58,11 @@
     ++ statCounter.syscalls.disk.opens;
 
     if (fd < 0) {
-        debugs(50, 3, "file_open: error opening file " << path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, 3, "error opening file " << path << ": " << xstrerr(xerrno));
         fd = DISK_ERROR;
     } else {
-        debugs(6, 5, "file_open: FD " << fd);
+        debugs(6, 5, "FD " << fd);
         commSetCloseOnExec(fd);
         fd_open(fd, FD_FILE, path);
     }
@@ -216,7 +217,8 @@
     if (fdd->write_q->file_offset != -1) {
         errno = 0;
         if (lseek(fd, fdd->write_q->file_offset, SEEK_SET) == -1) {
-            debugs(50, DBG_IMPORTANT, "error in seek for fd " << fd << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(50, DBG_IMPORTANT, "error in seek for FD " << fd << ": " << xstrerr(xerrno));
             // XXX: handle error?
         }
     }
@@ -234,7 +236,8 @@
     if (len < 0) {
         if (!ignoreErrno(errno)) {
             status = errno == ENOSPC ? DISK_NO_SPACE_LEFT : DISK_ERROR;
-            debugs(50, DBG_IMPORTANT, "diskHandleWrite: FD " << fd << ": disk write error: " << xstrerror());
+            int xerrno = errno;
+            debugs(50, DBG_IMPORTANT, "diskHandleWrite: FD " << fd << ": disk write error: " << xstrerr(xerrno));
 
             /*
              * If there is no write callback, then this file is
@@ -402,6 +405,8 @@
     fde *F = &fd_table[fd];
     int len;
     int rc = DISK_OK;
+    int xerrno;
+
     /*
      * FD < 0 indicates premature close; we just have to free
      * the state data.
@@ -422,8 +427,9 @@
         debugs(6, 3, "diskHandleRead: FD " << fd << " seeking to offset " << ctrl_dat->offset);
         errno = 0;
         if (lseek(fd, ctrl_dat->offset, SEEK_SET) == -1) {
+            xerrno = errno;
             // shouldn't happen, let's detect that
-            debugs(50, DBG_IMPORTANT, "error in seek for fd " << fd << ": " << xstrerror());
+            debugs(50, DBG_IMPORTANT, "error in seek for FD " << fd << ": " << xstrerr(xerrno));
             // XXX handle failures?
         }
         ++ statCounter.syscalls.disk.seeks;
@@ -432,6 +438,7 @@
 
     errno = 0;
     len = FD_READ_METHOD(fd, ctrl_dat->buf, ctrl_dat->req_len);
+    xerrno = errno;
 
     if (len > 0)
         F->disk.offset += len;
@@ -441,13 +448,13 @@
     fd_bytes(fd, len, FD_READ);
 
     if (len < 0) {
-        if (ignoreErrno(errno)) {
+        if (ignoreErrno(xerrno)) {
             Comm::SetSelect(fd, COMM_SELECT_READ, diskHandleRead, ctrl_dat, 0);
             PROF_stop(diskHandleRead);
             return;
         }
 
-        debugs(50, DBG_IMPORTANT, "diskHandleRead: FD " << fd << ": " << xstrerror());
+        debugs(50, DBG_IMPORTANT, "diskHandleRead: FD " << fd << ": " << xstrerr(xerrno));
         len = 0;
         rc = DISK_ERROR;
     } else if (len == 0) {
@@ -491,8 +498,10 @@
 {
     ++ statCounter.syscalls.disk.unlinks;
 
-    if (unlink(s) < 0 && !quiet)
-        debugs(50, DBG_IMPORTANT, "safeunlink: Couldn't delete " << s << ": " << xstrerror());
+    if (unlink(s) < 0 && !quiet) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "safeunlink: Couldn't delete " << s << ": " << xstrerr(xerrno));
+    }
 }
 
 /*
@@ -511,7 +520,8 @@
     if (0 == rename(from, to))
         return 0;
 
-    debugs(21, errno == ENOENT ? 2 : 1, "xrename: Cannot rename " << from << " to " << to << ": " << xstrerror());
+    int xerrno = errno;
+    debugs(21, errno == ENOENT ? 2 : 1, "xrename: Cannot rename " << from << " to " << to << ": " << xstrerr(xerrno));
 
     return -1;
 }
@@ -522,7 +532,8 @@
     struct statvfs sfs;
 
     if (xstatvfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerr(xerrno));
         *blksize = 2048;
         return 1;
     }
@@ -545,7 +556,8 @@
     struct statvfs sfs;
 
     if (xstatvfs(path, &sfs)) {
-        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "" << path << ": " << xstrerr(xerrno));
         return 1;
     }
 
diff -u -r -N squid-4.0.8/src/gopher.cc squid-4.0.9/src/gopher.cc
--- squid-4.0.8/src/gopher.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/gopher.cc	2016-04-21 01:19:59.000000000 +1200
@@ -784,7 +784,7 @@
     }
 
     if (flag != Comm::OK) {
-        debugs(50, DBG_IMPORTANT, "gopherReadReply: error reading: " << xstrerror());
+        debugs(50, DBG_IMPORTANT, MYNAME << "error reading: " << xstrerr(xerrno));
 
         if (ignoreErrno(xerrno)) {
             AsyncCall::Pointer call = commCbCall(5,4, "gopherReadReply",
diff -u -r -N squid-4.0.8/src/htcp.cc squid-4.0.9/src/htcp.cc
--- squid-4.0.8/src/htcp.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/htcp.cc	2016-04-21 01:19:59.000000000 +1200
@@ -576,12 +576,13 @@
 static void
 htcpSend(const char *buf, int len, Ip::Address &to)
 {
-    debugs(31, 3, HERE << to);
+    debugs(31, 3, to);
     htcpHexdump("htcpSend", buf, len);
 
-    if (comm_udp_sendto(htcpOutgoingConn->fd, to, buf, len) < 0)
-        debugs(31, 3, HERE << htcpOutgoingConn << " sendto: " << xstrerror());
-    else
+    if (comm_udp_sendto(htcpOutgoingConn->fd, to, buf, len) < 0) {
+        int xerrno = errno;
+        debugs(31, 3, htcpOutgoingConn << " sendto: " << xstrerr(xerrno));
+    } else
         ++statCounter.htcp.pkts_sent;
 }
 
diff -u -r -N squid-4.0.8/src/http/one/Parser.cc squid-4.0.9/src/http/one/Parser.cc
--- squid-4.0.8/src/http/one/Parser.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/http/one/Parser.cc	2016-04-21 01:19:59.000000000 +1200
@@ -142,3 +142,11 @@
     return NULL;
 }
 
+#if USE_HTTP_VIOLATIONS
+int
+Http::One::Parser::violationLevel() const
+{
+    return Config.onoff.relaxed_header_parser < 0 ? DBG_IMPORTANT : 5;
+}
+#endif
+
diff -u -r -N squid-4.0.8/src/http/one/Parser.h squid-4.0.9/src/http/one/Parser.h
--- squid-4.0.8/src/http/one/Parser.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/http/one/Parser.h	2016-04-21 01:19:59.000000000 +1200
@@ -91,6 +91,11 @@
     /// the remaining unprocessed section of buffer
     const SBuf &remaining() const {return buf_;}
 
+#if USE_HTTP_VIOLATIONS
+    /// the right debugs() level for parsing HTTP violation messages
+    int violationLevel() const;
+#endif
+
     /**
      * HTTP status code resulting from the parse process.
      * to be used on the invalid message handling.
diff -u -r -N squid-4.0.8/src/http/one/ResponseParser.cc squid-4.0.9/src/http/one/ResponseParser.cc
--- squid-4.0.8/src/http/one/ResponseParser.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/http/one/ResponseParser.cc	2016-04-21 01:19:59.000000000 +1200
@@ -219,7 +219,7 @@
         const int retcode = parseResponseFirstLine();
 
         // first-line (or a look-alike) found successfully.
-        if (retcode > 0)
+        if (retcode > 0 && parsingStage_ == HTTP_PARSE_FIRST)
             parsingStage_ = HTTP_PARSE_MIME;
         debugs(74, 5, "status-line: retval " << retcode);
         debugs(74, 5, "status-line: proto " << msgProtocol_);
diff -u -r -N squid-4.0.8/src/http/one/TeChunkedParser.cc squid-4.0.9/src/http/one/TeChunkedParser.cc
--- squid-4.0.8/src/http/one/TeChunkedParser.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/http/one/TeChunkedParser.cc	2016-04-21 01:19:59.000000000 +1200
@@ -14,6 +14,7 @@
 #include "http/ProtocolVersion.h"
 #include "MemBuf.h"
 #include "Parsing.h"
+#include "SquidConfig.h"
 
 Http::One::TeChunkedParser::TeChunkedParser()
 {
diff -u -r -N squid-4.0.8/src/http/url_rewriters/LFS/url_lfs_rewrite.8 squid-4.0.9/src/http/url_rewriters/LFS/url_lfs_rewrite.8
--- squid-4.0.8/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2016-04-02 11:49:14.000000000 +1300
+++ squid-4.0.9/src/http/url_rewriters/LFS/url_lfs_rewrite.8	2016-04-21 02:17:52.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "URL_LFS_REWRITE 8"
-.TH URL_LFS_REWRITE 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH URL_LFS_REWRITE 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/icmp/Icmp4.cc squid-4.0.9/src/icmp/Icmp4.cc
--- squid-4.0.8/src/icmp/Icmp4.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icmp/Icmp4.cc	2016-04-21 01:19:59.000000000 +1200
@@ -69,7 +69,8 @@
     icmp_sock = socket(PF_INET, SOCK_RAW, IPPROTO_ICMP);
 
     if (icmp_sock < 0) {
-        debugs(50, DBG_CRITICAL, HERE << " icmp_sock: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << " icmp_sock: " << xstrerr(xerrno));
         return -1;
     }
 
@@ -142,7 +143,8 @@
                S->ai_addrlen);
 
     if (x < 0) {
-        debugs(42, DBG_IMPORTANT, HERE << "Error sending to ICMP packet to " << to << ". ERR: " << xstrerror());
+        int xerrno = errno;
+        debugs(42, DBG_IMPORTANT, MYNAME << "ERROR: sending to ICMP packet to " << to << ": " << xstrerr(xerrno));
     }
 
     Log(to, ' ', NULL, 0, 0);
diff -u -r -N squid-4.0.8/src/icmp/Icmp6.cc squid-4.0.9/src/icmp/Icmp6.cc
--- squid-4.0.8/src/icmp/Icmp6.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icmp/Icmp6.cc	2016-04-21 01:19:59.000000000 +1200
@@ -101,7 +101,8 @@
     icmp_sock = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
 
     if (icmp_sock < 0) {
-        debugs(50, DBG_CRITICAL, HERE << " icmp_sock: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << " icmp_sock: " << xstrerr(xerrno));
         return -1;
     }
 
@@ -178,7 +179,8 @@
                S->ai_addrlen);
 
     if (x < 0) {
-        debugs(42, DBG_IMPORTANT, HERE << "Error sending to ICMPv6 packet to " << to << ". ERR: " << xstrerror());
+        int xerrno = errno;
+        debugs(42, DBG_IMPORTANT, MYNAME << "ERROR: sending to ICMPv6 packet to " << to << ": " << xstrerr(xerrno));
     }
     debugs(42,9, HERE << "x=" << x);
 
diff -u -r -N squid-4.0.8/src/icmp/IcmpPinger.cc squid-4.0.9/src/icmp/IcmpPinger.cc
--- squid-4.0.8/src/icmp/IcmpPinger.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icmp/IcmpPinger.cc	2016-04-21 01:19:59.000000000 +1200
@@ -54,6 +54,7 @@
     int x;
 
     struct sockaddr_in PS;
+    int xerrno;
 
     WSAStartup(2, &wsaData);
     atexit(Win32SockCleanup);
@@ -65,8 +66,9 @@
     x = read(0, buf, sizeof(wpi));
 
     if (x < (int)sizeof(wpi)) {
+        xerrno = errno;
         getCurrentTime();
-        debugs(42, DBG_CRITICAL, HERE << "read: FD 0: " << xstrerror());
+        debugs(42, DBG_CRITICAL, MYNAME << " read: FD 0: " << xstrerr(xerrno));
         write(1, "ERR\n", 4);
         return -1;
     }
@@ -77,8 +79,9 @@
     x = read(0, buf, sizeof(PS));
 
     if (x < (int)sizeof(PS)) {
+        xerrno = errno;
         getCurrentTime();
-        debugs(42, DBG_CRITICAL, HERE << "read: FD 0: " << xstrerror());
+        debugs(42, DBG_CRITICAL, MYNAME << " read: FD 0: " << xstrerr(xerrno));
         write(1, "ERR\n", 4);
         return -1;
     }
@@ -88,8 +91,9 @@
     icmp_sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wpi, 0, 0);
 
     if (icmp_sock == -1) {
+        xerrno = errno;
         getCurrentTime();
-        debugs(42, DBG_CRITICAL, HERE << "WSASocket: " << xstrerror());
+        debugs(42, DBG_CRITICAL, MYNAME << "WSASocket: " << xstrerr(xerrno));
         write(1, "ERR\n", 4);
         return -1;
     }
@@ -97,8 +101,9 @@
     x = connect(icmp_sock, (struct sockaddr *) &PS, sizeof(PS));
 
     if (SOCKET_ERROR == x) {
+        xerrno = errno;
         getCurrentTime();
-        debugs(42, DBG_CRITICAL, HERE << "connect: " << xstrerror());
+        debugs(42, DBG_CRITICAL, MYNAME << "connect: " << xstrerr(xerrno));
         write(1, "ERR\n", 4);
         return -1;
     }
@@ -108,14 +113,16 @@
     x = recv(icmp_sock, (void *) buf, sizeof(buf), 0);
 
     if (x < 3) {
-        debugs(42, DBG_CRITICAL, HERE << "recv: " << xstrerror());
+        xerrno = errno;
+        debugs(42, DBG_CRITICAL, MYNAME << "recv: " << xstrerr(xerrno));
         return -1;
     }
 
     x = send(icmp_sock, (const void *) buf, strlen(buf), 0);
+    xerrno = errno;
 
     if (x < 3 || strncmp("OK\n", buf, 3)) {
-        debugs(42, DBG_CRITICAL, HERE << "recv: " << xstrerror());
+        debugs(42, DBG_CRITICAL, MYNAME << "recv: " << xstrerr(xerrno));
         return -1;
     }
 
@@ -211,7 +218,8 @@
     debugs(42, 2, HERE << "return result to squid. len=" << len);
 
     if (send(socket_to_squid, &preply, len, 0) < 0) {
-        debugs(42, DBG_CRITICAL, "pinger: FATAL error on send: " << xstrerror());
+        int xerrno = errno;
+        debugs(42, DBG_CRITICAL, "pinger: FATAL error on send: " << xstrerr(xerrno));
         Close();
         exit(1);
     }
diff -u -r -N squid-4.0.8/src/icmp/IcmpSquid.cc squid-4.0.9/src/icmp/IcmpSquid.cc
--- squid-4.0.8/src/icmp/IcmpSquid.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icmp/IcmpSquid.cc	2016-04-21 01:19:59.000000000 +1200
@@ -93,11 +93,12 @@
     x = comm_udp_send(icmp_sock, (char *)&pecho, slen, 0);
 
     if (x < 0) {
-        debugs(37, DBG_IMPORTANT, HERE << "send: " << xstrerror());
+        int xerrno = errno;
+        debugs(37, DBG_IMPORTANT, MYNAME << "send: " << xstrerr(xerrno));
 
         /** \li  If the send results in ECONNREFUSED or EPIPE errors from helper, will cleanly shutdown the module. */
         /** \todo This should try restarting the helper a few times?? before giving up? */
-        if (errno == ECONNREFUSED || errno == EPIPE) {
+        if (xerrno == ECONNREFUSED || xerrno == EPIPE) {
             Close();
             return;
         }
@@ -131,12 +132,13 @@
                       0);
 
     if (n < 0 && EAGAIN != errno) {
-        debugs(37, DBG_IMPORTANT, HERE << "recv: " << xstrerror());
+        int xerrno = errno;
+        debugs(37, DBG_IMPORTANT, MYNAME << "recv: " << xstrerr(xerrno));
 
-        if (errno == ECONNREFUSED)
+        if (xerrno == ECONNREFUSED)
             Close();
 
-        if (errno == ECONNRESET)
+        if (xerrno == ECONNRESET)
             Close();
 
         if (++fail_count == 10)
diff -u -r -N squid-4.0.8/src/icmp/net_db.cc squid-4.0.9/src/icmp/net_db.cc
--- squid-4.0.8/src/icmp/net_db.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icmp/net_db.cc	2016-04-21 01:19:59.000000000 +1200
@@ -499,8 +499,9 @@
     unlink(Config.netdbFilename);
     lf = logfileOpen(Config.netdbFilename, 4096, 0);
 
-    if (NULL == lf) {
-        debugs(50, DBG_IMPORTANT, "netdbSaveState: " << Config.netdbFilename << ": " << xstrerror());
+    if (lf) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, MYNAME << Config.netdbFilename << ": " << xstrerr(xerrno));
         return;
     }
 
diff -u -r -N squid-4.0.8/src/icp_v2.cc squid-4.0.9/src/icp_v2.cc
--- squid-4.0.8/src/icp_v2.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/icp_v2.cc	2016-04-21 01:19:59.000000000 +1200
@@ -600,7 +600,8 @@
             break;
 
         if (len < 0) {
-            if (ignoreErrno(errno))
+            int xerrno = errno;
+            if (ignoreErrno(xerrno))
                 break;
 
 #if _SQUID_LINUX_
@@ -608,10 +609,9 @@
              * return ECONNREFUSED when sendto() fails and generates an ICMP
              * port unreachable message. */
             /* or maybe an EHOSTUNREACH "No route to host" message */
-            if (errno != ECONNREFUSED && errno != EHOSTUNREACH)
+            if (xerrno != ECONNREFUSED && xerrno != EHOSTUNREACH)
 #endif
-
-                debugs(50, DBG_IMPORTANT, "icpHandleUdp: FD " << sock << " recvfrom: " << xstrerror());
+                debugs(50, DBG_IMPORTANT, "icpHandleUdp: FD " << sock << " recvfrom: " << xstrerr(xerrno));
 
             break;
         }
diff -u -r -N squid-4.0.8/src/ip/Intercept.cc squid-4.0.9/src/ip/Intercept.cc
--- squid-4.0.8/src/ip/Intercept.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ip/Intercept.cc	2016-04-21 01:19:59.000000000 +1200
@@ -141,7 +141,8 @@
                     &lookup,
                     &len) != 0) {
         if (!silent) {
-            debugs(89, DBG_IMPORTANT, "ERROR: NF getsockopt(ORIGINAL_DST) failed on " << newConn << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(89, DBG_IMPORTANT, "ERROR: NF getsockopt(ORIGINAL_DST) failed on " << newConn << ": " << xstrerr(xerrno));
             lastReported_ = squid_curtime;
         }
         debugs(89, 9, "address: " << newConn);
@@ -205,7 +206,7 @@
         // warn once every 10 at critical level, then push down a level each repeated event
         static int warningLevel = DBG_CRITICAL;
         debugs(89, warningLevel, "IPF (IPFilter v4) NAT does not support IPv6. Please upgrade to IPFilter v5.1");
-        warningLevel = ++warningLevel % 10;
+        warningLevel = (warningLevel + 1) % 10;
         return false;
 #else
         natLookup.nl_v = 6;
@@ -235,7 +236,8 @@
 
     if (natfd < 0) {
         if (!silent) {
-            debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT open failed: " << xstrerror());
+            int xerrno = errno;
+            debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT open failed: " << xstrerr(xerrno));
             lastReported_ = squid_curtime;
             return false;
         }
@@ -268,9 +270,10 @@
 
 #endif
     if (x < 0) {
-        if (errno != ESRCH) {
+        int xerrno = errno;
+        if (xerrno != ESRCH) {
             if (!silent) {
-                debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT lookup failed: ioctl(SIOCGNATL) (v=" << IPFILTER_VERSION << "): " << xstrerror());
+                debugs(89, DBG_IMPORTANT, "IPF (IPFilter) NAT lookup failed: ioctl(SIOCGNATL) (v=" << IPFILTER_VERSION << "): " << xstrerr(xerrno));
                 lastReported_ = squid_curtime;
             }
 
@@ -316,7 +319,8 @@
 
     if (pffd < 0) {
         if (!silent) {
-            debugs(89, DBG_IMPORTANT, HERE << "PF open failed: " << xstrerror());
+            int xerrno = errno;
+            debugs(89, DBG_IMPORTANT, MYNAME << "PF open failed: " << xstrerr(xerrno));
             lastReported_ = squid_curtime;
         }
         return false;
@@ -334,9 +338,10 @@
     nl.direction = PF_OUT;
 
     if (ioctl(pffd, DIOCNATLOOK, &nl)) {
-        if (errno != ENOENT) {
+        int xerrno = errno;
+        if (xerrno != ENOENT) {
             if (!silent) {
-                debugs(89, DBG_IMPORTANT, HERE << "PF lookup failed: ioctl(DIOCNATLOOK)");
+                debugs(89, DBG_IMPORTANT, HERE << "PF lookup failed: ioctl(DIOCNATLOOK): " << xstrerr(xerrno));
                 lastReported_ = squid_curtime;
             }
             close(pffd);
diff -u -r -N squid-4.0.8/src/ip/Qos.cci squid-4.0.9/src/ip/Qos.cci
--- squid-4.0.8/src/ip/Qos.cci	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ip/Qos.cci	2016-04-21 01:19:59.000000000 +1200
@@ -24,8 +24,10 @@
     if (type == AF_INET) {
 #if defined(IP_TOS)
         const int x = setsockopt(fd, IPPROTO_IP, IP_TOS, &bTos, sizeof(bTos));
-        if (x < 0)
-            debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IP_TOS) on " << fd << ": " << xstrerror());
+        if (x < 0) {
+            int xerrno = errno;
+            debugs(50, 2, "setsockopt(IP_TOS) on " << fd << ": " << xstrerr(xerrno));
+        }
         return x;
 #else
         debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IP_TOS) not supported on this platform");
@@ -34,8 +36,10 @@
     } else { // type == AF_INET6
 #if defined(IPV6_TCLASS)
         const int x = setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &bTos, sizeof(bTos));
-        if (x < 0)
-            debugs(50, 2, "Ip::Qos::setSockTos: setsockopt(IPV6_TCLASS) on " << fd << ": " << xstrerror());
+        if (x < 0) {
+            int xerrno = errno;
+            debugs(50, 2, "setsockopt(IPV6_TCLASS) on " << fd << ": " << xstrerr(xerrno));
+        }
         return x;
 #else
         debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(IPV6_TCLASS) not supported on this platform");
@@ -60,8 +64,10 @@
 #if SO_MARK && USE_LIBCAP
     debugs(50, 3, "for FD " << fd << " to " << mark);
     const int x = setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(nfmark_t));
-    if (x < 0)
-        debugs(50, 2, "setSockNfmark: setsockopt(SO_MARK) on " << fd << ": " << xstrerror());
+    if (x < 0) {
+        int xerrno = errno;
+        debugs(50, 2, "setsockopt(SO_MARK) on " << fd << ": " << xstrerr(xerrno));
+    }
     return x;
 #elif USE_LIBCAP
     debugs(50, DBG_IMPORTANT, "WARNING: setsockopt(SO_MARK) not supported on this platform");
diff -u -r -N squid-4.0.8/src/ip/QosConfig.cc squid-4.0.9/src/ip/QosConfig.cc
--- squid-4.0.8/src/ip/QosConfig.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ip/QosConfig.cc	2016-04-21 01:19:59.000000000 +1200
@@ -68,10 +68,12 @@
                 pbuf += CMSG_LEN(o->cmsg_len);
             }
         } else {
-            debugs(33, DBG_IMPORTANT, "QOS: error in getsockopt(IP_PKTOPTIONS) on " << server << " " << xstrerror());
+            int xerrno = errno;
+            debugs(33, DBG_IMPORTANT, "QOS: error in getsockopt(IP_PKTOPTIONS) on " << server << " " << xstrerr(xerrno));
         }
     } else {
-        debugs(33, DBG_IMPORTANT, "QOS: error in setsockopt(IP_RECVTOS) on " << server << " " << xstrerror());
+        int xerrno = errno;
+        debugs(33, DBG_IMPORTANT, "QOS: error in setsockopt(IP_RECVTOS) on " << server << " " << xstrerr(xerrno));
     }
 #endif
 }
diff -u -r -N squid-4.0.8/src/ipc/mem/Pointer.h squid-4.0.9/src/ipc/mem/Pointer.h
--- squid-4.0.8/src/ipc/mem/Pointer.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc/mem/Pointer.h	2016-04-21 01:19:59.000000000 +1200
@@ -165,7 +165,7 @@
     theSegment.open();
     Must(theSegment.mem());
     theObject = reinterpret_cast<Class*>(theSegment.mem());
-    Must(static_cast<off_t>(theObject->sharedMemorySize()) == theSegment.size());
+    Must(static_cast<off_t>(theObject->sharedMemorySize()) <= theSegment.size());
 }
 
 template <class Class>
diff -u -r -N squid-4.0.8/src/ipc/mem/Segment.cc squid-4.0.9/src/ipc/mem/Segment.cc
--- squid-4.0.8/src/ipc/mem/Segment.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc/mem/Segment.cc	2016-04-21 01:19:59.000000000 +1200
@@ -69,8 +69,10 @@
 {
     if (theFD >= 0) {
         detach();
-        if (close(theFD) != 0)
-            debugs(54, 5, HERE << "close " << theName << ": " << xstrerror());
+        if (close(theFD) != 0) {
+            int xerrno = errno;
+            debugs(54, 5, "close " << theName << ": " << xstrerr(xerrno));
+        }
     }
     if (doUnlink)
         unlink();
@@ -89,27 +91,29 @@
     assert(aSize > 0);
     assert(theFD < 0);
 
+    int xerrno = 0;
+
     // Why a brand new segment? A Squid crash may leave a reusable segment, but
     // our placement-new code requires an all-0s segment. We could truncate and
     // resize the old segment, but OS X does not allow using O_TRUNC with
     // shm_open() and does not support ftruncate() for old segments.
-    if (!createFresh() && errno == EEXIST) {
+    if (!createFresh(xerrno) && xerrno == EEXIST) {
         unlink();
-        createFresh();
+        createFresh(xerrno);
     }
 
     if (theFD < 0) {
-        debugs(54, 5, HERE << "shm_open " << theName << ": " << xstrerror());
+        debugs(54, 5, "shm_open " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::create failed to shm_open(%s): %s\n",
-               theName.termedBuf(), xstrerror());
+               theName.termedBuf(), xstrerr(xerrno));
     }
 
     if (ftruncate(theFD, aSize)) {
-        const int savedError = errno;
+        xerrno = errno;
         unlink();
-        debugs(54, 5, HERE << "ftruncate " << theName << ": " << xstrerr(savedError));
+        debugs(54, 5, "ftruncate " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::create failed to ftruncate(%s): %s\n",
-               theName.termedBuf(), xstrerr(savedError));
+               theName.termedBuf(), xstrerr(xerrno));
     }
     // We assume that the shm_open(O_CREAT)+ftruncate() combo zeros the segment.
 
@@ -121,8 +125,7 @@
     theReserved = 0;
     doUnlink = true;
 
-    debugs(54, 3, HERE << "created " << theName << " segment: " << theSize);
-
+    debugs(54, 3, "created " << theName << " segment: " << theSize);
     attach();
 }
 
@@ -133,9 +136,10 @@
 
     theFD = shm_open(theName.termedBuf(), O_RDWR, 0);
     if (theFD < 0) {
-        debugs(54, 5, HERE << "shm_open " << theName << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, 5, "shm_open " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::open failed to shm_open(%s): %s\n",
-               theName.termedBuf(), xstrerror());
+               theName.termedBuf(), xstrerr(xerrno));
     }
 
     theSize = statSize("Ipc::Mem::Segment::open");
@@ -148,11 +152,12 @@
 /// Creates a brand new shared memory segment and returns true.
 /// Fails and returns false if there exist an old segment with the same name.
 bool
-Ipc::Mem::Segment::createFresh()
+Ipc::Mem::Segment::createFresh(int &xerrno)
 {
     theFD = shm_open(theName.termedBuf(),
                      O_EXCL | O_CREAT | O_RDWR,
                      S_IRUSR | S_IWUSR);
+    xerrno = errno;
     return theFD >= 0;
 }
 
@@ -170,9 +175,10 @@
     void *const p =
         mmap(NULL, theSize, PROT_READ | PROT_WRITE, MAP_SHARED, theFD, 0);
     if (p == MAP_FAILED) {
-        debugs(54, 5, HERE << "mmap " << theName << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, 5, "mmap " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::attach failed to mmap(%s): %s\n",
-               theName.termedBuf(), xstrerror());
+               theName.termedBuf(), xstrerr(xerrno));
     }
     theMem = p;
 
@@ -187,9 +193,10 @@
         return;
 
     if (munmap(theMem, theSize)) {
-        debugs(54, 5, HERE << "munmap " << theName << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, 5, "munmap " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::detach failed to munmap(%s): %s\n",
-               theName.termedBuf(), xstrerror());
+               theName.termedBuf(), xstrerr(xerrno));
     }
     theMem = 0;
 }
@@ -230,10 +237,11 @@
 void
 Ipc::Mem::Segment::unlink()
 {
-    if (shm_unlink(theName.termedBuf()) != 0)
-        debugs(54, 5, HERE << "shm_unlink(" << theName << "): " << xstrerror());
-    else
-        debugs(54, 3, HERE << "unlinked " << theName << " segment");
+    if (shm_unlink(theName.termedBuf()) != 0) {
+        int xerrno = errno;
+        debugs(54, 5, "shm_unlink(" << theName << "): " << xstrerr(xerrno));
+    } else
+        debugs(54, 3, "unlinked " << theName << " segment");
 }
 
 /// determines the size of the underlying "file"
@@ -246,9 +254,10 @@
     memset(&s, 0, sizeof(s));
 
     if (fstat(theFD, &s) != 0) {
-        debugs(54, 5, HERE << context << " fstat " << theName << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, 5, context << " fstat " << theName << ": " << xstrerr(xerrno));
         fatalf("Ipc::Mem::Segment::statSize: %s failed to fstat(%s): %s\n",
-               context, theName.termedBuf(), xstrerror());
+               context, theName.termedBuf(), xstrerr(xerrno));
     }
 
     return s.st_size;
diff -u -r -N squid-4.0.8/src/ipc/mem/Segment.h squid-4.0.9/src/ipc/mem/Segment.h
--- squid-4.0.8/src/ipc/mem/Segment.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc/mem/Segment.h	2016-04-21 01:19:59.000000000 +1200
@@ -53,7 +53,7 @@
 
 #if HAVE_SHM
 
-    bool createFresh();
+    bool createFresh(int &err);
     void attach();
     void detach();
     void lock();
diff -u -r -N squid-4.0.8/src/ipc/UdsOp.cc squid-4.0.9/src/ipc/UdsOp.cc
--- squid-4.0.8/src/ipc/UdsOp.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc/UdsOp.cc	2016-04-21 01:19:59.000000000 +1200
@@ -204,7 +204,8 @@
         comm_import_opened(conn, Ipc::FdNote(noteId), addr_info);
         Ip::Address::FreeAddr(addr_info);
     } else {
-        debugs(54, DBG_CRITICAL, "ERROR: Ipc::ImportFdIntoComm: " << conn << ' ' << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ERROR: Ipc::ImportFdIntoComm: " << conn << ' ' << xstrerr(xerrno));
         conn->close();
     }
     return conn;
diff -u -r -N squid-4.0.8/src/ipc.cc squid-4.0.9/src/ipc.cc
--- squid-4.0.8/src/ipc.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc.cc	2016-04-21 01:19:59.000000000 +1200
@@ -72,6 +72,7 @@
     int fd;
     int t1, t2, t3;
     int x;
+    int xerrno;
 
 #if USE_POLL && _SQUID_OSF_
     assert(type != IPC_FIFO);
@@ -124,14 +125,16 @@
         int c2p[2];
 
         if (pipe(p2c) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: pipe: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: pipe: " << xstrerr(xerrno));
             return -1; // maybe ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
         fd_open(prfd = p2c[0], FD_PIPE, "IPC FIFO Parent Read");
         fd_open(cwfd = p2c[1], FD_PIPE, "IPC FIFO Child Write");
 
         if (pipe(c2p) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: pipe: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: pipe: " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
         fd_open(crfd = c2p[0], FD_PIPE, "IPC FIFO Child Read");
@@ -147,25 +150,30 @@
         int buflen = 32768;
 
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: socketpair: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: socketpair: " << xstrerr(xerrno));
             return -1;
         }
 
         errno = 0;
         if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, (void *) &buflen, sizeof(buflen)) == -1)  {
-            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerr(xerrno));
             errno = 0;
         }
         if (setsockopt(fds[0], SOL_SOCKET, SO_RCVBUF, (void *) &buflen, sizeof(buflen)) == -1) {
-            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerr(xerrno));
             errno = 0;
         }
         if (setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, (void *) &buflen, sizeof(buflen)) == -1) {
-            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerr(xerrno));
             errno = 0;
         }
         if (setsockopt(fds[1], SOL_SOCKET, SO_RCVBUF, (void *) &buflen, sizeof(buflen)) == -1) {
-            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "setsockopt failed: " << xstrerr(xerrno));
             errno = 0;
         }
         fd_open(prfd = pwfd = fds[0], FD_PIPE, "IPC UNIX STREAM Parent");
@@ -177,7 +185,8 @@
         int fds[2];
 
         if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: socketpair: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: socketpair: " << xstrerr(xerrno));
             return -1;
         }
 
@@ -201,8 +210,9 @@
         Ip::Address::InitAddr(AI);
 
         if (getsockname(pwfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            xerrno = errno;
             Ip::Address::FreeAddr(AI);
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -215,8 +225,9 @@
         Ip::Address::InitAddr(AI);
 
         if (getsockname(crfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            xerrno = errno;
             Ip::Address::FreeAddr(AI);
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -230,7 +241,8 @@
 
     if (type == IPC_TCP_SOCKET) {
         if (listen(crfd, 1) < 0) {
-            debugs(54, DBG_IMPORTANT, "ipcCreate: listen FD " << crfd << ": " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "ipcCreate: listen FD " << crfd << ": " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -241,7 +253,8 @@
     logsFlush();
 
     if ((pid = fork()) < 0) {
-        debugs(54, DBG_IMPORTANT, "ipcCreate: fork: " << xstrerror());
+        xerrno = errno;
+        debugs(54, DBG_IMPORTANT, "ipcCreate: fork: " << xstrerr(xerrno));
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
@@ -263,12 +276,13 @@
             x = comm_udp_recv(prfd, hello_buf, sizeof(hello_buf)-1, 0);
         else
             x = read(prfd, hello_buf, sizeof(hello_buf)-1);
+        xerrno = errno;
         if (x >= 0)
             hello_buf[x] = '\0';
 
         if (x < 0) {
             debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: hello read test failed");
-            debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+            debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         } else if (strcmp(hello_buf, hello_string)) {
             debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: hello read test failed");
@@ -319,7 +333,8 @@
         debugs(54, 3, "ipcCreate: calling accept on FD " << crfd);
 
         if ((fd = accept(crfd, NULL, NULL)) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: FD " << crfd << " accept: " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: FD " << crfd << " accept: " << xstrerr(xerrno));
             _exit(1);
         }
 
@@ -335,13 +350,15 @@
         x = comm_udp_send(cwfd, hello_string, strlen(hello_string) + 1, 0);
 
         if (x < 0) {
-            debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
             _exit(1);
         }
     } else {
         if (write(cwfd, hello_string, strlen(hello_string) + 1) < 0) {
-            debugs(54, DBG_CRITICAL, "write FD " << cwfd << ": " << xstrerror());
+            xerrno = errno;
+            debugs(54, DBG_CRITICAL, "write FD " << cwfd << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
             _exit(1);
         }
@@ -397,10 +414,11 @@
 #endif
 
     execvp(prog, (char *const *) args);
+    xerrno = errno;
 
     debug_log = fdopen(2, "a+");
 
-    debugs(54, DBG_CRITICAL, "ipcCreate: " << prog << ": " << xstrerror());
+    debugs(54, DBG_CRITICAL, "ipcCreate: " << prog << ": " << xstrerr(xerrno));
 
     _exit(1);
 
diff -u -r -N squid-4.0.8/src/ipc_win32.cc squid-4.0.9/src/ipc_win32.cc
--- squid-4.0.8/src/ipc_win32.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ipc_win32.cc	2016-04-21 01:19:59.000000000 +1200
@@ -183,7 +183,8 @@
         Ip::Address::InitAddr(aiPS);
 
         if (getsockname(pwfd, aiPS->ai_addr, &(aiPS->ai_addrlen) ) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             Ip::Address::FreeAddr(aiPS);
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
@@ -196,7 +197,8 @@
         Ip::Address::InitAddr(aiCS);
 
         if (getsockname(crfd, aiCS->ai_addr, &(aiCS->ai_addrlen) ) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             Ip::Address::FreeAddr(aiCS);
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
@@ -210,7 +212,8 @@
 
     if (type == IPC_TCP_SOCKET) {
         if (listen(crfd, 1) < 0) {
-            debugs(54, DBG_IMPORTANT, "ipcCreate: listen FD " << crfd << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_IMPORTANT, "ipcCreate: listen FD " << crfd << ": " << xstrerr(xerrno));
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -237,7 +240,8 @@
     thread = _beginthreadex(NULL, 0, ipc_thread_1, &params, 0, NULL);
 
     if (thread == 0) {
-        debugs(54, DBG_IMPORTANT, "ipcCreate: _beginthread: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_IMPORTANT, "ipcCreate: _beginthread: " << xstrerr(xerrno));
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
@@ -251,8 +255,9 @@
     x = recv(prfd, (void *)hello_buf, HELLO_BUF_SZ - 1, 0);
 
     if (x < 0) {
+        int xerrno = errno;
         debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: hello read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     } else if (strcmp(hello_buf, hello_string)) {
@@ -266,8 +271,9 @@
     x = send(pwfd, (const void *)ok_string, strlen(ok_string), 0);
 
     if (x < 0) {
+        int xerrno = errno;
         debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: OK write test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     }
@@ -276,8 +282,9 @@
     x = recv(prfd, (void *)hello_buf, HELLO_BUF_SZ - 1, 0);
 
     if (x < 0) {
+        int xerrno = errno;
         debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: OK read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     } else if (!strcmp(hello_buf, err_string)) {
@@ -332,12 +339,11 @@
 static int
 ipcSend(int cwfd, const char *buf, int len)
 {
-    int x;
-
-    x = send(cwfd, (const void *)buf, len, 0);
+    int x = send(cwfd, (const void *)buf, len, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerr(xerrno));
         debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
     }
 
@@ -394,7 +400,8 @@
         debugs(54, 3, "ipcCreate: calling accept on FD " << crfd);
 
         if ((fd = accept(crfd, NULL, NULL)) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: FD " << crfd << " accept: " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: FD " << crfd << " accept: " << xstrerr(xerrno));
             goto cleanup;
         }
 
@@ -412,7 +419,8 @@
     x = send(cwfd, (const void *)hello_string, strlen(hello_string) + 1, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerr(xerrno));
         debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
         goto cleanup;
     }
@@ -422,8 +430,9 @@
     x = recv(crfd, (void *)buf1, bufSz-1, 0);
 
     if (x < 0) {
+        int xerrno = errno;
         debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: OK read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         goto cleanup;
     } else if (strcmp(buf1, ok_string)) {
         debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: OK read test failed");
@@ -434,13 +443,15 @@
 
     /* assign file descriptors to child process */
     if (_pipe(p2c, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: pipe: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: pipe: " << xstrerr(xerrno));
         ipcSend(cwfd, err_string, strlen(err_string));
         goto cleanup;
     }
 
     if (_pipe(c2p, 1024, _O_BINARY | _O_NOINHERIT) < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: pipe: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: pipe: " << xstrerr(xerrno));
         ipcSend(cwfd, err_string, strlen(err_string));
         goto cleanup;
     }
@@ -467,7 +478,8 @@
         Ip::Address::InitAddr(aiPS_ipc);
 
         if (getsockname(pwfd_ipc, aiPS_ipc->ai_addr, &(aiPS_ipc->ai_addrlen)) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             ipcSend(cwfd, err_string, strlen(err_string));
             Ip::Address::FreeAddr(aiPS_ipc);
             goto cleanup;
@@ -481,7 +493,8 @@
         Ip::Address::InitAddr(aiCS_ipc);
 
         if (getsockname(crfd_ipc, aiCS_ipc->ai_addr, &(aiCS_ipc->ai_addrlen)) < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: getsockname: " << xstrerr(xerrno));
             ipcSend(cwfd, err_string, strlen(err_string));
             Ip::Address::FreeAddr(aiCS_ipc);
             goto cleanup;
@@ -577,8 +590,7 @@
     close(t3);
 
     if (pid == -1) {
-        errno = x;
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << params->prog << ": " << xstrerror());
+        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << params->prog << ": " << xstrerr(x));
 
         ipcSend(cwfd, err_string, strlen(err_string));
         goto cleanup;
@@ -590,8 +602,8 @@
         memset(&wpi, 0, sizeof(wpi));
 
         if (SOCKET_ERROR == WSADuplicateSocket(crfd_ipc, pid, &wpi)) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: WSADuplicateSocket: " << xstrerror());
-
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: WSADuplicateSocket: " << xstrerr(xerrno));
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
@@ -599,9 +611,9 @@
         x = write(c2p[1], (const char *) &wpi, sizeof(wpi));
 
         if (x < (ssize_t)sizeof(wpi)) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
@@ -609,9 +621,9 @@
         x = read(p2c[0], buf1, bufSz-1);
 
         if (x < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         } else if (strncmp(buf1, ok_string, strlen(ok_string))) {
@@ -626,9 +638,9 @@
         x = write(c2p[1], (const char *) &PS_ipc, sizeof(PS_ipc));
 
         if (x < (ssize_t)sizeof(PS_ipc)) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
@@ -636,9 +648,9 @@
         x = read(p2c[0], buf1, bufSz-1);
 
         if (x < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerr(xerrno));
             debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         } else if (strncmp(buf1, ok_string, strlen(ok_string))) {
@@ -684,7 +696,8 @@
     thread = (HANDLE)_beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL);
 
     if (!thread) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: _beginthreadex: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: _beginthreadex: " << xstrerr(xerrno));
         ipcSend(cwfd, err_string, strlen(err_string));
         goto cleanup;
     }
diff -u -r -N squid-4.0.8/src/log/DB/log_db_daemon.8 squid-4.0.9/src/log/DB/log_db_daemon.8
--- squid-4.0.8/src/log/DB/log_db_daemon.8	2016-04-02 11:49:21.000000000 +1300
+++ squid-4.0.9/src/log/DB/log_db_daemon.8	2016-04-21 02:17:59.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "LOG_DB_DAEMON 8"
-.TH LOG_DB_DAEMON 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH LOG_DB_DAEMON 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/log/file/log_file_daemon.cc squid-4.0.9/src/log/file/log_file_daemon.cc
--- squid-4.0.8/src/log/file/log_file_daemon.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/log/file/log_file_daemon.cc	2016-04-21 01:19:59.000000000 +1200
@@ -55,22 +55,26 @@
         snprintf(to, MAXPATHLEN, "%s.%d", path, i);
 #if _SQUID_OS2_ || _SQUID_WINDOWS_
         if (remove(to) < 0) {
-            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+            int xerrno = errno;
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerr(xerrno));
         }
 #endif
         if (rename(from, to) < 0 && errno != ENOENT) {
-            fprintf(stderr, "WARNING: rename '%s' to '%s' failure: %s\n", from, to, xstrerror());
+            int xerrno = errno;
+            fprintf(stderr, "WARNING: rename '%s' to '%s' failure: %s\n", from, to, xstrerr(xerrno));
         }
     }
     if (rotate_count > 0) {
         snprintf(to, MAXPATHLEN, "%s.%d", path, 0);
 #if _SQUID_OS2_ || _SQUID_WINDOWS_
         if (remove(to) < 0) {
-            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerror());
+            int xerrno = errno;
+            fprintf(stderr, "WARNING: remove '%s' failure: %s\n", to, xstrerr(xerrno));
         }
 #endif
         if (rename(path, to) < 0 && errno != ENOENT) {
-            fprintf(stderr, "WARNING: rename %s to %s failure: %s\n", path, to, xstrerror());
+            int xerrno = errno;
+            fprintf(stderr, "WARNING: rename %s to %s failure: %s\n", path, to, xstrerr(xerrno));
         }
     }
 }
diff -u -r -N squid-4.0.8/src/log/ModDaemon.cc squid-4.0.9/src/log/ModDaemon.cc
--- squid-4.0.8/src/log/ModDaemon.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/log/ModDaemon.cc	2016-04-21 01:19:59.000000000 +1200
@@ -106,15 +106,16 @@
     ll->flush_pending = 0;
 
     int ret = FD_WRITE_METHOD(ll->wfd, b->buf + b->written_len, b->len - b->written_len);
+    int xerrno = errno;
     debugs(50, 3, lf->path << ": write returned " << ret);
     if (ret < 0) {
-        if (ignoreErrno(errno)) {
+        if (ignoreErrno(xerrno)) {
             /* something temporary */
             Comm::SetSelect(ll->wfd, COMM_SELECT_WRITE, logfileHandleWrite, lf, 0);
             ll->flush_pending = 1;
             return;
         }
-        debugs(50, DBG_IMPORTANT,"logfileHandleWrite: " << lf->path << ": error writing (" << xstrerror() << ")");
+        debugs(50, DBG_IMPORTANT,"logfileHandleWrite: " << lf->path << ": error writing (" << xstrerr(xerrno) << ")");
         /* XXX should handle this better */
         fatal("I don't handle this error well!");
     }
diff -u -r -N squid-4.0.8/src/log/ModStdio.cc squid-4.0.9/src/log/ModStdio.cc
--- squid-4.0.8/src/log/ModStdio.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/log/ModStdio.cc	2016-04-21 01:19:59.000000000 +1200
@@ -37,6 +37,7 @@
     l_stdio_t *ll = (l_stdio_t *) lf->data;
     size_t s;
     s = FD_WRITE_METHOD(ll->fd, (char const *) buf, len);
+    int xerrno = errno;
     fd_bytes(ll->fd, s, FD_WRITE);
 
     if (s == len)
@@ -45,7 +46,7 @@
     if (!lf->flags.fatal)
         return;
 
-    fatalf("logfileWrite: %s: %s\n", lf->path, xstrerror());
+    fatalf("logfileWrite: %s: %s\n", lf->path, xstrerr(xerrno));
 }
 
 static void
@@ -142,8 +143,9 @@
     ll->fd = file_open(realpath, O_WRONLY | O_CREAT | O_TEXT);
 
     if (DISK_ERROR == ll->fd && lf->flags.fatal) {
-        debugs(50, DBG_CRITICAL, "ERROR: logfileRotate: " << lf->path << ": " << xstrerror());
-        fatalf("Cannot open %s: %s", lf->path, xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, MYNAME << "ERROR: " << lf->path << ": " << xstrerr(xerrno));
+        fatalf("Cannot open %s: %s", lf->path, xstrerr(xerrno));
     }
 }
 
@@ -182,19 +184,20 @@
     ll->fd = file_open(path, O_WRONLY | O_CREAT | O_TEXT);
 
     if (DISK_ERROR == ll->fd) {
-        if (ENOENT == errno && fatal_flag) {
+        int xerrno = errno;
+        if (ENOENT == xerrno && fatal_flag) {
             fatalf("Cannot open '%s' because\n"
                    "\tthe parent directory does not exist.\n"
                    "\tPlease create the directory.\n", path);
-        } else if (EACCES == errno && fatal_flag) {
+        } else if (EACCES == xerrno && fatal_flag) {
             fatalf("Cannot open '%s' for writing.\n"
                    "\tThe parent directory must be writeable by the\n"
                    "\tuser '%s', which is the cache_effective_user\n"
                    "\tset in squid.conf.", path, Config.effectiveUser);
-        } else if (EISDIR == errno && fatal_flag) {
+        } else if (EISDIR == xerrno && fatal_flag) {
             fatalf("Cannot open '%s' because it is a directory, not a file.\n", path);
         } else {
-            debugs(50, DBG_IMPORTANT, "ERROR: logfileOpen " << lf->path << ": " << xstrerror());
+            debugs(50, DBG_IMPORTANT, MYNAME << "ERROR: " << lf->path << ": " << xstrerr(xerrno));
             return 0;
         }
     }
diff -u -r -N squid-4.0.8/src/log/ModUdp.cc squid-4.0.9/src/log/ModUdp.cc
--- squid-4.0.8/src/log/ModUdp.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/log/ModUdp.cc	2016-04-21 01:19:59.000000000 +1200
@@ -45,7 +45,8 @@
     fd_bytes(ll->fd, s, FD_WRITE);
 #if 0
     if (s < 0) {
-        debugs(1, DBG_IMPORTANT, "logfile (udp): got errno (" << errno << "):" << xstrerror());
+        int xerrno = errno;
+        debugs(1, DBG_IMPORTANT, "logfile (udp): got errno (" << errno << "):" << xstrerr(xerrno));
     }
     if (s != len) {
         debugs(1, DBG_IMPORTANT, "logfile (udp): len=" << len << ", wrote=" << s);
@@ -166,6 +167,7 @@
         any_addr.setIPv4();
 
     ll->fd = comm_open(SOCK_DGRAM, IPPROTO_UDP, any_addr, COMM_NONBLOCKING, "UDP log socket");
+    int xerrno = errno;
     if (ll->fd < 0) {
         if (lf->flags.fatal) {
             fatalf("Unable to open UDP socket for logging\n");
@@ -174,25 +176,26 @@
             return FALSE;
         }
     } else if (!comm_connect_addr(ll->fd, addr)) {
+        xerrno = errno;
         if (lf->flags.fatal) {
-            fatalf("Unable to connect to %s for UDP log: %s\n", lf->path, xstrerror());
+            fatalf("Unable to connect to %s for UDP log: %s\n", lf->path, xstrerr(xerrno));
         } else {
-            debugs(50, DBG_IMPORTANT, "Unable to connect to " << lf->path << " for UDP log: " << xstrerror());
+            debugs(50, DBG_IMPORTANT, "Unable to connect to " << lf->path << " for UDP log: " << xstrerr(xerrno));
             return FALSE;
         }
     }
     if (ll->fd == -1) {
-        if (ENOENT == errno && fatal_flag) {
+        if (ENOENT == xerrno && fatal_flag) {
             fatalf("Cannot open '%s' because\n"
                    "\tthe parent directory does not exist.\n"
                    "\tPlease create the directory.\n", path);
-        } else if (EACCES == errno && fatal_flag) {
+        } else if (EACCES == xerrno && fatal_flag) {
             fatalf("Cannot open '%s' for writing.\n"
                    "\tThe parent directory must be writeable by the\n"
                    "\tuser '%s', which is the cache_effective_user\n"
                    "\tset in squid.conf.", path, Config.effectiveUser);
         } else {
-            debugs(50, DBG_IMPORTANT, "logfileOpen (UDP): " << lf->path << ": " << xstrerror());
+            debugs(50, DBG_IMPORTANT, "logfileOpen (UDP): " << lf->path << ": " << xstrerr(xerrno));
             return 0;
         }
     }
diff -u -r -N squid-4.0.8/src/main.cc squid-4.0.9/src/main.cc
--- squid-4.0.8/src/main.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/main.cc	2016-04-21 01:19:59.000000000 +1200
@@ -290,8 +290,10 @@
 #if KILL_PARENT_OPT
     if (!IamMasterProcess() && !parentKillNotified && ShutdownSignal > 0 && parentPid > 1) {
         debugs(1, DBG_IMPORTANT, "Killing master process, pid " << parentPid);
-        if (kill(parentPid, ShutdownSignal) < 0)
-            debugs(1, DBG_IMPORTANT, "kill " << parentPid << ": " << xstrerror());
+        if (kill(parentPid, ShutdownSignal) < 0) {
+            int xerrno = errno;
+            debugs(1, DBG_IMPORTANT, "kill " << parentPid << ": " << xstrerr(xerrno));
+        }
         parentKillNotified = true;
     }
 #endif
@@ -1058,8 +1060,9 @@
     if (chdir(dir) == 0)
         return true;
 
-    debugs(50, DBG_CRITICAL, "cannot change current directory to " << dir <<
-           ": " << xstrerror());
+    int xerrno = errno;
+    debugs(50, DBG_CRITICAL, "ERROR: cannot change current directory to " << dir <<
+           ": " << xstrerr(xerrno));
     return false;
 }
 
@@ -1071,8 +1074,10 @@
     if (Config.chroot_dir && !chrooted) {
         chrooted = true;
 
-        if (chroot(Config.chroot_dir) != 0)
-            fatalf("chroot to %s failed: %s", Config.chroot_dir, xstrerror());
+        if (chroot(Config.chroot_dir) != 0) {
+            int xerrno = errno;
+            fatalf("chroot to %s failed: %s", Config.chroot_dir, xstrerr(xerrno));
+        }
 
         if (!mainChangeDir("/"))
             fatalf("chdir to / after chroot to %s failed", Config.chroot_dir);
@@ -1090,7 +1095,8 @@
     if (getcwd(pathbuf, MAXPATHLEN)) {
         debugs(0, DBG_IMPORTANT, "Current Directory is " << pathbuf);
     } else {
-        debugs(50, DBG_CRITICAL, "WARNING: Can't find current directory, getcwd: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "WARNING: Can't find current directory, getcwd: " << xstrerr(xerrno));
     }
 }
 
@@ -1684,9 +1690,10 @@
         if (kill(pid, opt_send_signal) &&
                 /* ignore permissions if just running check */
                 !(opt_send_signal == 0 && errno == EPERM)) {
+            int xerrno = errno;
             fprintf(stderr, "%s: ERROR: Could not send ", APP_SHORTNAME);
             fprintf(stderr, "signal %d to process %d: %s\n",
-                    opt_send_signal, (int) pid, xstrerror());
+                    opt_send_signal, (int) pid, xstrerr(xerrno));
             exit(1);
         }
     } else {
@@ -1805,21 +1812,25 @@
 
     openlog(APP_SHORTNAME, LOG_PID | LOG_NDELAY | LOG_CONS, LOG_LOCAL4);
 
-    if ((pid = fork()) < 0)
-        syslog(LOG_ALERT, "fork failed: %s", xstrerror());
-    else if (pid > 0) {
+    if ((pid = fork()) < 0) {
+        int xerrno = errno;
+        syslog(LOG_ALERT, "fork failed: %s", xstrerr(xerrno));
+    } else if (pid > 0) {
         // parent
         if (opt_foreground) {
             if (WaitForAnyPid(status_f, 0) < 0) {
-                syslog(LOG_ALERT, "WaitForAnyPid failed: %s", xstrerror());
+                int xerrno = errno;
+                syslog(LOG_ALERT, "WaitForAnyPid failed: %s", xstrerr(xerrno));
             }
         }
 
         exit(0);
     }
 
-    if (setsid() < 0)
-        syslog(LOG_ALERT, "setsid failed: %s", xstrerror());
+    if (setsid() < 0) {
+        int xerrno = errno;
+        syslog(LOG_ALERT, "setsid failed: %s", xstrerr(xerrno));
+    }
 
     closelog();
 
@@ -1840,8 +1851,10 @@
     /* Connect stdio to /dev/null in daemon mode */
     nullfd = open(_PATH_DEVNULL, O_RDWR | O_TEXT);
 
-    if (nullfd < 0)
-        fatalf(_PATH_DEVNULL " %s\n", xstrerror());
+    if (nullfd < 0) {
+        int xerrno = errno;
+        fatalf(_PATH_DEVNULL " %s\n", xstrerr(xerrno));
+    }
 
     dup2(nullfd, 0);
 
@@ -1898,7 +1911,8 @@
                 prog = argv[0];
                 argv[0] = const_cast<char*>(kid.name().termedBuf());
                 execvp(prog, argv);
-                syslog(LOG_ALERT, "execvp failed: %s", xstrerror());
+                int xerrno = errno;
+                syslog(LOG_ALERT, "execvp failed: %s", xstrerr(xerrno));
             }
 
             kid.start(pid);
diff -u -r -N squid-4.0.8/src/mime.cc squid-4.0.9/src/mime.cc
--- squid-4.0.8/src/mime.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/mime.cc	2016-04-21 01:19:59.000000000 +1200
@@ -247,7 +247,8 @@
         return;
 
     if ((fp = fopen(filename, "r")) == NULL) {
-        debugs(25, DBG_IMPORTANT, "mimeInit: " << filename << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(25, DBG_IMPORTANT, "mimeInit: " << filename << ": " << xstrerr(xerrno));
         return;
     }
 
diff -u -r -N squid-4.0.8/src/multicast.cc squid-4.0.9/src/multicast.cc
--- squid-4.0.8/src/multicast.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/multicast.cc	2016-04-21 01:19:59.000000000 +1200
@@ -22,9 +22,10 @@
 #ifdef IP_MULTICAST_TTL
     char ttl = (char) mcast_ttl;
 
-    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, 1) < 0)
-        debugs(50, DBG_IMPORTANT, "comm_set_mcast_ttl: FD " << fd << ", TTL: " << mcast_ttl << ": " << xstrerror());
-
+    if (setsockopt(fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, 1) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "mcastSetTtl: FD " << fd << ", TTL: " << mcast_ttl << ": " << xstrerr(xerrno));
+    }
 #endif
 
     return 0;
@@ -58,8 +59,10 @@
             debugs(7, DBG_IMPORTANT, "ERROR: Join failed for " << icpIncomingConn << ", Multicast IP=" << ia->in_addrs[i]);
 
         char c = 0;
-        if (setsockopt(icpIncomingConn->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &c, 1) < 0)
-            debugs(7, DBG_IMPORTANT, "ERROR: " << icpIncomingConn << " can't disable multicast loopback: " << xstrerror());
+        if (setsockopt(icpIncomingConn->fd, IPPROTO_IP, IP_MULTICAST_LOOP, &c, 1) < 0) {
+            int xerrno = errno;
+            debugs(7, DBG_IMPORTANT, "ERROR: " << icpIncomingConn << " can't disable multicast loopback: " << xstrerr(xerrno));
+        }
     }
 
 #endif
diff -u -r -N squid-4.0.8/src/sbuf/DetailedStats.cc squid-4.0.9/src/sbuf/DetailedStats.cc
--- squid-4.0.8/src/sbuf/DetailedStats.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/sbuf/DetailedStats.cc	2016-04-21 01:19:59.000000000 +1200
@@ -15,42 +15,36 @@
  * external dependencies to the SBuf code
  */
 
-static StatHist sbufDestructTimeStats;
-static StatHist memblobDestructTimeStats;
-
-namespace SBufDetailedStatsHistInitializer
-{
-// run the post-instantiation initialization methods for StatHist objects
-struct Initializer {
-    Initializer() {
-        sbufDestructTimeStats.logInit(100,30.0,128000.0);
-        memblobDestructTimeStats.logInit(100,30.0,128000.0);
-    }
-};
-Initializer initializer;
+static StatHist *
+newStatHist() {
+    StatHist *stats = new StatHist;
+    stats->logInit(100, 30.0, 128000.0);
+    return stats;
 }
 
-void
-recordSBufSizeAtDestruct(SBuf::size_type sz)
+StatHist &
+collectSBufDestructTimeStats()
 {
-    sbufDestructTimeStats.count(static_cast<double>(sz));
+    static StatHist *stats = newStatHist();
+    return *stats;
 }
 
-const StatHist *
-collectSBufDestructTimeStats()
+StatHist &
+collectMemBlobDestructTimeStats()
 {
-    return &sbufDestructTimeStats;
+    static StatHist *stats = newStatHist();
+    return *stats;
 }
 
 void
-recordMemBlobSizeAtDestruct(SBuf::size_type sz)
+recordSBufSizeAtDestruct(SBuf::size_type sz)
 {
-    memblobDestructTimeStats.count(static_cast<double>(sz));
+    collectSBufDestructTimeStats().count(static_cast<double>(sz));
 }
 
-const StatHist *
-collectMemBlobDestructTimeStats()
+void
+recordMemBlobSizeAtDestruct(SBuf::size_type sz)
 {
-    return &memblobDestructTimeStats;
+    collectMemBlobDestructTimeStats().count(static_cast<double>(sz));
 }
 
diff -u -r -N squid-4.0.8/src/sbuf/DetailedStats.h squid-4.0.9/src/sbuf/DetailedStats.h
--- squid-4.0.8/src/sbuf/DetailedStats.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/sbuf/DetailedStats.h	2016-04-21 01:19:59.000000000 +1200
@@ -16,20 +16,14 @@
 /// Record the size a SBuf had when it was destructed
 void recordSBufSizeAtDestruct(SBuf::size_type sz);
 
-/** Collect the SBuf size-at-destruct-time histogram
- *
- * \note the returned StatHist object must not be freed
- */
-const StatHist * collectSBufDestructTimeStats();
+/// the SBuf size-at-destruct-time histogram
+StatHist &collectSBufDestructTimeStats();
 
 /// Record the size a MemBlob had when it was destructed
 void recordMemBlobSizeAtDestruct(MemBlob::size_type sz);
 
-/** Collect the MemBlob size-at-destruct-time histogram
- *
- * \note the returned StatHist object must not be freed
- */
-const StatHist * collectMemBlobDestructTimeStats();
+/// the MemBlob size-at-destruct-time histogram
+StatHist &collectMemBlobDestructTimeStats();
 
 #endif /* SQUID_SBUFDETAILEDSTATS_H */
 
diff -u -r -N squid-4.0.8/src/SBufStatsAction.cc squid-4.0.9/src/SBufStatsAction.cc
--- squid-4.0.8/src/SBufStatsAction.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/SBufStatsAction.cc	2016-04-21 01:19:59.000000000 +1200
@@ -38,8 +38,8 @@
 {
     sbdata = SBuf::GetStats();
     mbdata = MemBlob::GetStats();
-    sbsizesatdestruct = *collectSBufDestructTimeStats();
-    mbsizesatdestruct = *collectMemBlobDestructTimeStats();
+    sbsizesatdestruct = collectSBufDestructTimeStats();
+    mbsizesatdestruct = collectMemBlobDestructTimeStats();
 }
 
 static void
diff -u -r -N squid-4.0.8/src/security/cert_validators/fake/security_fake_certverify.8 squid-4.0.9/src/security/cert_validators/fake/security_fake_certverify.8
--- squid-4.0.8/src/security/cert_validators/fake/security_fake_certverify.8	2016-04-02 11:49:33.000000000 +1300
+++ squid-4.0.9/src/security/cert_validators/fake/security_fake_certverify.8	2016-04-21 02:18:12.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "SECURITY_FAKE_CERTVERIFY 8"
-.TH SECURITY_FAKE_CERTVERIFY 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH SECURITY_FAKE_CERTVERIFY 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/security/ServerOptions.cc squid-4.0.9/src/security/ServerOptions.cc
--- squid-4.0.8/src/security/ServerOptions.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/security/ServerOptions.cc	2016-04-21 01:19:59.000000000 +1200
@@ -21,14 +21,6 @@
 #include <openssl/x509.h>
 #endif
 
-Security::ServerOptions::ServerOptions(const Security::ServerOptions &s) :
-    dh(s.dh),
-    dhParamsFile(s.dhParamsFile),
-    eecdhCurve(s.eecdhCurve),
-    parsedDhParams(s.parsedDhParams)
-{
-}
-
 void
 Security::ServerOptions::parse(const char *token)
 {
diff -u -r -N squid-4.0.8/src/security/ServerOptions.h squid-4.0.9/src/security/ServerOptions.h
--- squid-4.0.8/src/security/ServerOptions.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/security/ServerOptions.h	2016-04-21 01:19:59.000000000 +1200
@@ -23,7 +23,6 @@
         // is more secure to have only a small set of trusted CA.
         flags.tlsDefaultCa.defaultTo(false);
     }
-    explicit ServerOptions(const Security::ServerOptions &);
     virtual ~ServerOptions() = default;
 
     /* Security::PeerOptions API */
diff -u -r -N squid-4.0.8/src/send-announce.cc squid-4.0.9/src/send-announce.cc
--- squid-4.0.8/src/send-announce.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/send-announce.cc	2016-04-21 01:19:59.000000000 +1200
@@ -87,7 +87,8 @@
             sndbuf[l] = '\0';
             file_close(fd);
         } else {
-            debugs(50, DBG_IMPORTANT, "send_announce: " << file << ": " << xstrerror());
+            int xerrno = errno;
+            debugs(50, DBG_IMPORTANT, "send_announce: " << file << ": " << xstrerr(xerrno));
         }
     }
 
@@ -95,7 +96,9 @@
     S.port(port);
     assert(Comm::IsConnOpen(icpOutgoingConn));
 
-    if (comm_udp_sendto(icpOutgoingConn->fd, S, sndbuf, strlen(sndbuf) + 1) < 0)
-        debugs(27, DBG_IMPORTANT, "ERROR: Failed to announce to " << S << " from " << icpOutgoingConn->local << ": " << xstrerror());
+    if (comm_udp_sendto(icpOutgoingConn->fd, S, sndbuf, strlen(sndbuf) + 1) < 0) {
+        int xerrno = errno;
+        debugs(27, DBG_IMPORTANT, "ERROR: Failed to announce to " << S << " from " << icpOutgoingConn->local << ": " << xstrerr(xerrno));
+    }
 }
 
diff -u -r -N squid-4.0.8/src/snmp_core.cc squid-4.0.9/src/snmp_core.cc
--- squid-4.0.8/src/snmp_core.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/snmp_core.cc	2016-04-21 01:19:59.000000000 +1200
@@ -368,7 +368,8 @@
         xfree(snmp_rq->outbuf);
         xfree(snmp_rq);
     } else {
-        debugs(49, DBG_IMPORTANT, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerror());
+        int xerrno = errno;
+        debugs(49, DBG_IMPORTANT, "snmpHandleUdp: FD " << sock << " recvfrom: " << xstrerr(xerrno));
     }
 }
 
diff -u -r -N squid-4.0.8/src/ssl/bio.cc squid-4.0.9/src/ssl/bio.cc
--- squid-4.0.8/src/ssl/bio.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ssl/bio.cc	2016-04-21 01:19:59.000000000 +1200
@@ -518,9 +518,7 @@
         return clientFeatures.sessionId == receivedHelloFeatures_.sessionId;
 
     // is this a session resuming attempt using TLS tickets?
-    if (clientFeatures.hasTlsTicket &&
-            receivedHelloFeatures_.tlsTicketsExtension &&
-            receivedHelloFeatures_.hasCcsOrNst)
+    if (clientFeatures.hasTlsTicket && receivedHelloFeatures_.hasCcsOrNst)
         return true;
 
     return false;
diff -u -r -N squid-4.0.8/src/ssl/support.cc squid-4.0.9/src/ssl/support.cc
--- squid-4.0.8/src/ssl/support.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ssl/support.cc	2016-04-21 01:19:59.000000000 +1200
@@ -969,6 +969,30 @@
     return createSSLContext(cert, pkey, port);
 }
 
+void
+Ssl::chainCertificatesToSSLContext(SSL_CTX *sslContext, AnyP::PortCfg &port)
+{
+    assert(sslContext != NULL);
+    // Add signing certificate to the certificates chain
+    X509 *signingCert = port.signingCert.get();
+    if (SSL_CTX_add_extra_chain_cert(sslContext, signingCert)) {
+        // increase the certificate lock
+        CRYPTO_add(&(signingCert->references),1,CRYPTO_LOCK_X509);
+    } else {
+        const int ssl_error = ERR_get_error();
+        debugs(33, DBG_IMPORTANT, "WARNING: can not add signing certificate to SSL context chain: " << ERR_error_string(ssl_error, NULL));
+    }
+    Ssl::addChainToSslContext(sslContext, port.certsToChain.get());
+}
+
+void
+Ssl::configureUnconfiguredSslContext(SSL_CTX *sslContext, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port)
+{
+    if (sslContext && signAlgorithm == Ssl::algSignTrusted) {
+        Ssl::chainCertificatesToSSLContext(sslContext, port);
+    }
+}
+
 bool
 Ssl::configureSSL(SSL *ssl, CertificateProperties const &properties, AnyP::PortCfg &port)
 {
diff -u -r -N squid-4.0.8/src/ssl/support.h squid-4.0.9/src/ssl/support.h
--- squid-4.0.8/src/ssl/support.h	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/ssl/support.h	2016-04-21 01:19:59.000000000 +1200
@@ -240,6 +240,18 @@
 Security::ContextPtr createSSLContext(Security::CertPointer & x509, Ssl::EVP_PKEY_Pointer & pkey, AnyP::PortCfg &port);
 
 /**
+ \ingroup ServerProtocolSSLAPI
+ * Chain signing certificate and chained certificates to an SSL Context
+ */
+void chainCertificatesToSSLContext(SSL_CTX *sslContext, AnyP::PortCfg &port);
+
+/**
+ \ingroup ServerProtocolSSLAPI
+ * Configure a previously unconfigured SSL context object.
+ */
+void configureUnconfiguredSslContext(SSL_CTX *sslContext, Ssl::CertSignAlgorithm signAlgorithm,AnyP::PortCfg &port);
+
+/**
   \ingroup ServerProtocolSSLAPI
   * Generates a certificate and a private key using provided properies and set it
   * to SSL object.
diff -u -r -N squid-4.0.8/src/store/id_rewriters/file/storeid_file_rewrite.8 squid-4.0.9/src/store/id_rewriters/file/storeid_file_rewrite.8
--- squid-4.0.8/src/store/id_rewriters/file/storeid_file_rewrite.8	2016-04-02 11:48:32.000000000 +1300
+++ squid-4.0.9/src/store/id_rewriters/file/storeid_file_rewrite.8	2016-04-21 02:17:10.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "STOREID_FILE_REWRITE 8"
-.TH STOREID_FILE_REWRITE 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH STOREID_FILE_REWRITE 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/src/store_client.cc squid-4.0.9/src/store_client.cc
--- squid-4.0.8/src/store_client.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/store_client.cc	2016-04-21 01:19:59.000000000 +1200
@@ -525,10 +525,11 @@
 bool
 store_client::unpackHeader(char const *buf, ssize_t len)
 {
+    int xerrno = errno; // FIXME: where does errno come from?
     debugs(90, 3, "store_client::unpackHeader: len " << len << "");
 
     if (len < 0) {
-        debugs(90, 3, "WARNING: unpack error: " << xstrerror());
+        debugs(90, 3, "WARNING: unpack error: " << xstrerr(xerrno));
         return false;
     }
 
diff -u -r -N squid-4.0.8/src/StoreMetaVary.cc squid-4.0.9/src/StoreMetaVary.cc
--- squid-4.0.8/src/StoreMetaVary.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/StoreMetaVary.cc	2016-04-21 01:19:59.000000000 +1200
@@ -22,6 +22,9 @@
         /* XXX separate this mutator from the query */
         /* Assume the object is OK.. remember the vary request headers */
         e->mem_obj->vary_headers.assign(static_cast<const char *>(value), length);
+        /* entries created before SBuf vary handling may include string terminator */
+        static const SBuf nul("\0", 1);
+        e->mem_obj->vary_headers.trim(nul);
         return true;
     }
 
diff -u -r -N squid-4.0.8/src/store_swapmeta.cc squid-4.0.9/src/store_swapmeta.cc
--- squid-4.0.8/src/store_swapmeta.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/store_swapmeta.cc	2016-04-21 01:19:59.000000000 +1200
@@ -89,9 +89,7 @@
     SBuf vary(e->mem_obj->vary_headers);
 
     if (!vary.isEmpty()) {
-        // TODO: do we still need +1 here? StoreMetaVary::checkConsistency
-        //       no longer relies on nul-termination, but other things might.
-        t = StoreMeta::Factory(STORE_META_VARY_HEADERS, vary.length() + 1, vary.c_str());
+        t = StoreMeta::Factory(STORE_META_VARY_HEADERS, vary.length(), vary.c_str());
 
         if (!t) {
             storeSwapTLVFree(TLV);
diff -u -r -N squid-4.0.8/src/tests/stub_cbdata.cc squid-4.0.9/src/tests/stub_cbdata.cc
--- squid-4.0.8/src/tests/stub_cbdata.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/tests/stub_cbdata.cc	2016-04-21 01:19:59.000000000 +1200
@@ -13,9 +13,14 @@
 #include "tests/STUB.h"
 
 void cbdataRegisterWithCacheManager(void) STUB
-
-void *cbdataInternalAlloc(cbdata_type type, const char *, int) STUB_RETVAL(NULL)
-void *cbdataInternalFree(void *p, const char *, int) STUB_RETVAL(NULL)
+void *cbdataInternalAlloc(cbdata_type type, const char *, int sz) {
+//STUB_RETVAL(NULL)
+    return xcalloc(1, sz);
+}
+void *cbdataInternalFree(void *p, const char *, int) {
+    xfree(p);
+    return nullptr;
+}
 #if USE_CBDATA_DEBUG
 void cbdataInternalLockDbg(const void *p, const char *, int) STUB
 void cbdataInternalUnlockDbg(const void *p, const char *, int) STUB
diff -u -r -N squid-4.0.8/src/tools.cc squid-4.0.9/src/tools.cc
--- squid-4.0.8/src/tools.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/tools.cc	2016-04-21 01:19:59.000000000 +1200
@@ -389,9 +389,11 @@
     }
 
 #if !HAVE_SIGACTION
-    if (signal(sig, sigusr2_handle) == SIG_ERR) /* reinstall */
-        debugs(50, DBG_CRITICAL, "signal: sig=" << sig << " func=sigusr2_handle: " << xstrerror());
-
+    /* reinstall */
+    if (signal(sig, sigusr2_handle) == SIG_ERR) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "signal: sig=" << sig << " func=sigusr2_handle: " << xstrerr(xerrno));
+    }
 #endif
 }
 
@@ -450,7 +452,8 @@
 
     // still no host. fallback to gethostname()
     if (gethostname(host, SQUIDHOSTNAMELEN) < 0) {
-        debugs(50, DBG_IMPORTANT, "WARNING: gethostname failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "WARNING: gethostname failed: " << xstrerr(xerrno));
     } else {
         /* Verify that the hostname given resolves properly */
         struct addrinfo hints;
@@ -469,10 +472,11 @@
 
             return host;
         }
+        int xerrno = errno;
 
         if (AI)
             freeaddrinfo(AI);
-        debugs(50, DBG_IMPORTANT, "WARNING: '" << host << "' rDNS test failed: " << xstrerror());
+        debugs(50, DBG_IMPORTANT, "WARNING: '" << host << "' rDNS test failed: " << xstrerr(xerrno));
     }
 
     /* throw a configuration error when the Host/IP given has bad DNS/rDNS. */
@@ -500,16 +504,14 @@
     debugs(21, 3, "leave_suid: PID " << getpid() << " called");
 
     if (Config.effectiveGroup) {
-
 #if HAVE_SETGROUPS
-
         setgroups(1, &Config2.effectiveGroupID);
-
 #endif
 
-        if (setgid(Config2.effectiveGroupID) < 0)
-            debugs(50, DBG_CRITICAL, "ALERT: setgid: " << xstrerror());
-
+        if (setgid(Config2.effectiveGroupID) < 0) {
+            int xerrno = errno;
+            debugs(50, DBG_CRITICAL, "ALERT: setgid: " << xstrerr(xerrno));
+        }
     }
 
     if (geteuid() != 0)
@@ -523,8 +525,10 @@
 
     if (!Config.effectiveGroup) {
 
-        if (setgid(Config2.effectiveGroupID) < 0)
-            debugs(50, DBG_CRITICAL, "ALERT: setgid: " << xstrerror());
+        if (setgid(Config2.effectiveGroupID) < 0) {
+            int xerrno = errno;
+            debugs(50, DBG_CRITICAL, "ALERT: setgid: " << xstrerr(xerrno));
+        }
 
         if (initgroups(Config.effectiveUser, Config2.effectiveGroupID) < 0) {
             debugs(50, DBG_CRITICAL, "ALERT: initgroups: unable to set groups for User " <<
@@ -557,9 +561,10 @@
 
 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
     /* Set Linux DUMPABLE flag */
-    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0)
-        debugs(50, 2, "ALERT: prctl: " << xstrerror());
-
+    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) {
+        int xerrno = errno;
+        debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno));
+    }
 #endif
 }
 
@@ -580,9 +585,10 @@
 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
     /* Set Linux DUMPABLE flag */
 
-    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0)
-        debugs(50, 2, "ALERT: prctl: " << xstrerror());
-
+    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) {
+        int xerrno = errno;
+        debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno));
+    }
 #endif
 }
 
@@ -597,19 +603,24 @@
     uid = geteuid();
     debugs(21, 3, "no_suid: PID " << getpid() << " giving up root priveleges forever");
 
-    if (setuid(0) < 0)
-        debugs(50, DBG_IMPORTANT, "WARNING: no_suid: setuid(0): " << xstrerror());
+    if (setuid(0) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "WARNING: no_suid: setuid(0): " << xstrerr(xerrno));
+    }
 
-    if (setuid(uid) < 0)
-        debugs(50, DBG_IMPORTANT, "ERROR: no_suid: setuid(" << uid << "): " << xstrerror());
+    if (setuid(uid) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_IMPORTANT, "ERROR: no_suid: setuid(" << uid << "): " << xstrerr(xerrno));
+    }
 
     restoreCapabilities(false);
 
 #if HAVE_PRCTL && defined(PR_SET_DUMPABLE)
     /* Set Linux DUMPABLE flag */
-    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0)
-        debugs(50, 2, "ALERT: prctl: " << xstrerror());
-
+    if (Config.coredump_dir && prctl(PR_SET_DUMPABLE, 1) != 0) {
+        int xerrno = errno;
+        debugs(50, 2, "ALERT: prctl: " << xstrerr(xerrno));
+    }
 #endif
 }
 
@@ -718,14 +729,15 @@
     old_umask = umask(022);
 
     fd = open(f, O_WRONLY | O_CREAT | O_TRUNC | O_TEXT, 0644);
+    int xerrno = errno;
 
     umask(old_umask);
 
     leave_suid();
 
     if (fd < 0) {
-        debugs(50, DBG_CRITICAL, "" << f << ": " << xstrerror());
-        debug_trap("Could not write pid file");
+        debugs(50, DBG_CRITICAL, "" << f << ": " << xstrerr(xerrno));
+        debug_trap("Could not open PID file for write");
         return;
     }
 
@@ -755,7 +767,7 @@
     int i;
 
     if (f == NULL || !strcmp(Config.pidFilename, "none")) {
-        fprintf(stderr, APP_SHORTNAME ": ERROR: No pid file name defined\n");
+        fprintf(stderr, APP_SHORTNAME ": ERROR: No PID file name defined\n");
         exit(1);
     }
 
@@ -766,9 +778,7 @@
         f = chroot_f;
     }
 
-    pid_fp = fopen(f, "r");
-
-    if (pid_fp != NULL) {
+    if ((pid_fp = fopen(f, "r"))) {
         pid = 0;
 
         if (fscanf(pid_fp, "%d", &i) == 1)
@@ -776,9 +786,10 @@
 
         fclose(pid_fp);
     } else {
-        if (errno != ENOENT) {
-            fprintf(stderr, APP_SHORTNAME ": ERROR: Could not read pid file\n");
-            fprintf(stderr, "\t%s: %s\n", f, xstrerror());
+        int xerrno = errno;
+        if (xerrno != ENOENT) {
+            fprintf(stderr, APP_SHORTNAME ": ERROR: Could not open PID file for read\n");
+            fprintf(stderr, "\t%s: %s\n", f, xstrerr(xerrno));
             exit(1);
         }
     }
@@ -810,7 +821,8 @@
 #endif
 
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_NOFILE: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
     } else if (Config.max_filedescriptors > 0) {
 #if USE_SELECT || USE_SELECT_WIN32
         /* select() breaks if this gets set too big */
@@ -823,16 +835,19 @@
         if (rl.rlim_cur > rl.rlim_max)
             rl.rlim_max = rl.rlim_cur;
         if (setrlimit(RLIMIT_NOFILE, &rl)) {
-            debugs(50, DBG_CRITICAL, "ERROR: setrlimit: RLIMIT_NOFILE: " << xstrerror());
+            int xerrno = errno;
+            debugs(50, DBG_CRITICAL, "ERROR: setrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
             getrlimit(RLIMIT_NOFILE, &rl);
             rl.rlim_cur = rl.rlim_max;
             if (setrlimit(RLIMIT_NOFILE, &rl)) {
-                debugs(50, DBG_CRITICAL, "ERROR: setrlimit: RLIMIT_NOFILE: " << xstrerror());
+                xerrno = errno;
+                debugs(50, DBG_CRITICAL, "ERROR: setrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
             }
         }
     }
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-        debugs(50, DBG_CRITICAL, "ERROR: getrlimit: RLIMIT_NOFILE: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "ERROR: getrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
     } else {
         Squid_MaxFD = rl.rlim_cur;
     }
@@ -856,11 +871,13 @@
 #endif
 
     if (getrlimit(RLIMIT_NOFILE, &rl) < 0) {
-        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_NOFILE: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_NOFILE: " << xstrerr(xerrno));
     } else {
         rl.rlim_cur = Squid_MaxFD;
         if (setrlimit(RLIMIT_NOFILE, &rl) < 0) {
-            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_NOFILE: %s", xstrerror());
+            int xerrno = errno;
+            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_NOFILE: %s", xstrerr(xerrno));
             fatal_dump(tmp_error_buf);
         }
     }
@@ -868,12 +885,14 @@
 
 #if HAVE_SETRLIMIT && defined(RLIMIT_DATA) && !_SQUID_CYGWIN_
     if (getrlimit(RLIMIT_DATA, &rl) < 0) {
-        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_DATA: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_DATA: " << xstrerr(xerrno));
     } else if (rl.rlim_max > rl.rlim_cur) {
         rl.rlim_cur = rl.rlim_max;  /* set it to the max */
 
         if (setrlimit(RLIMIT_DATA, &rl) < 0) {
-            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_DATA: %s", xstrerror());
+            int xerrno = errno;
+            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_DATA: %s", xstrerr(xerrno));
             fatal_dump(tmp_error_buf);
         }
     }
@@ -884,12 +903,14 @@
 
 #if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) && !_SQUID_CYGWIN_
     if (getrlimit(RLIMIT_VMEM, &rl) < 0) {
-        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_VMEM: " << xstrerror());
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "getrlimit: RLIMIT_VMEM: " << xstrerr(xerrno));
     } else if (rl.rlim_max > rl.rlim_cur) {
         rl.rlim_cur = rl.rlim_max;  /* set it to the max */
 
         if (setrlimit(RLIMIT_VMEM, &rl) < 0) {
-            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_VMEM: %s", xstrerror());
+            int xerrno = errno;
+            snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_VMEM: %s", xstrerr(xerrno));
             fatal_dump(tmp_error_buf);
         }
     }
@@ -906,9 +927,10 @@
     sa.sa_flags = flags;
     sigemptyset(&sa.sa_mask);
 
-    if (sigaction(sig, &sa, NULL) < 0)
-        debugs(50, DBG_CRITICAL, "sigaction: sig=" << sig << " func=" << func << ": " << xstrerror());
-
+    if (sigaction(sig, &sa, NULL) < 0) {
+        int xerrno = errno;
+        debugs(50, DBG_CRITICAL, "sigaction: sig=" << sig << " func=" << func << ": " << xstrerr(xerrno));
+    }
 #else
 #if _SQUID_WINDOWS_
     /*
@@ -974,22 +996,22 @@
 void
 parseEtcHosts(void)
 {
-    FILE *fp;
     char buf[1024];
     char buf2[512];
     char *nt = buf;
     char *lt = buf;
 
-    if (NULL == Config.etcHostsPath)
+    if (!Config.etcHostsPath)
         return;
 
     if (0 == strcmp(Config.etcHostsPath, "none"))
         return;
 
-    fp = fopen(Config.etcHostsPath, "r");
+    FILE *fp = fopen(Config.etcHostsPath, "r");
 
-    if (fp == NULL) {
-        debugs(1, DBG_IMPORTANT, "parseEtcHosts: " << Config.etcHostsPath << ": " << xstrerror());
+    if (!fp) {
+        int xerrno = errno;
+        debugs(1, DBG_IMPORTANT, "parseEtcHosts: " << Config.etcHostsPath << ": " << xstrerr(xerrno));
         return;
     }
 
diff -u -r -N squid-4.0.8/src/tunnel.cc squid-4.0.9/src/tunnel.cc
--- squid-4.0.8/src/tunnel.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/tunnel.cc	2016-04-21 01:19:59.000000000 +1200
@@ -526,10 +526,7 @@
 void
 TunnelStateData::Connection::error(int const xerrno)
 {
-    /* XXX fixme xstrerror and xerrno... */
-    errno = xerrno;
-
-    debugs(50, debugLevelForError(xerrno), HERE << conn << ": read/write failure: " << xstrerror());
+    debugs(50, debugLevelForError(xerrno), HERE << conn << ": read/write failure: " << xstrerr(xerrno));
 
     if (!ignoreErrno(xerrno))
         conn->close();
diff -u -r -N squid-4.0.8/src/unlinkd.cc squid-4.0.9/src/unlinkd.cc
--- squid-4.0.8/src/unlinkd.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/unlinkd.cc	2016-04-21 01:19:59.000000000 +1200
@@ -107,7 +107,8 @@
     bytes_written = write(unlinkd_wfd, buf, l);
 
     if (bytes_written < 0) {
-        debugs(2, DBG_IMPORTANT, "unlinkdUnlink: write FD " << unlinkd_wfd << " failed: " << xstrerror());
+        int xerrno = errno;
+        debugs(2, DBG_IMPORTANT, "unlinkdUnlink: write FD " << unlinkd_wfd << " failed: " << xstrerr(xerrno));
         safeunlink(path, 0);
         return;
     } else if (bytes_written != l) {
diff -u -r -N squid-4.0.8/src/wccp2.cc squid-4.0.9/src/wccp2.cc
--- squid-4.0.8/src/wccp2.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/wccp2.cc	2016-04-21 01:19:59.000000000 +1200
@@ -979,8 +979,10 @@
 #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
     {
         int i = IP_PMTUDISC_DONT;
-        if (setsockopt(theWccp2Connection, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i) < 0)
-            debugs(80, 2, "WARNING: Path MTU discovery could not be disabled on FD " << theWccp2Connection << ": " << xstrerror());
+        if (setsockopt(theWccp2Connection, SOL_IP, IP_MTU_DISCOVER, &i, sizeof i) < 0) {
+            int xerrno = errno;
+            debugs(80, 2, "WARNING: Path MTU discovery could not be disabled on FD " << theWccp2Connection << ": " << xstrerr(xerrno));
+        }
     }
 
 #endif
@@ -1584,9 +1586,10 @@
                                 &service_list_ptr->wccp_packet,
                                 service_list_ptr->wccp_packet_size);
             } else {
-                errno = 0;
-                if (send(theWccp2Connection, &service_list_ptr->wccp_packet, service_list_ptr->wccp_packet_size, 0) < static_cast<int>(service_list_ptr->wccp_packet_size))
-                    debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << router << " : " << xstrerror());
+                if (send(theWccp2Connection, &service_list_ptr->wccp_packet, service_list_ptr->wccp_packet_size, 0) < static_cast<int>(service_list_ptr->wccp_packet_size)) {
+                    int xerrno = errno;
+                    debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << router << " : " << xstrerr(xerrno));
+                }
             }
         }
 
@@ -1968,9 +1971,10 @@
                                     &wccp_packet,
                                     offset);
                 } else {
-                    errno = 0;
-                    if (send(theWccp2Connection, &wccp_packet, offset, 0) < static_cast<int>(offset))
-                        debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << tmp_rtr << " : " << xstrerror());
+                    if (send(theWccp2Connection, &wccp_packet, offset, 0) < static_cast<int>(offset)) {
+                        int xerrno = errno;
+                        debugs(80, 2, "ERROR: failed to send WCCPv2 HERE_I_AM packet to " << tmp_rtr << " : " << xstrerr(xerrno));
+                    }
                 }
             }
             safe_free(weight);
diff -u -r -N squid-4.0.8/src/wccp.cc squid-4.0.9/src/wccp.cc
--- squid-4.0.8/src/wccp.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/wccp.cc	2016-04-21 01:19:59.000000000 +1200
@@ -277,12 +277,12 @@
 
     wccp_here_i_am.id = last_id;
     double interval = 10.0; // TODO: make this configurable, possibly negotiate with the router.
-    errno = 0;
     ssize_t sent = comm_udp_send(theWccpConnection, &wccp_here_i_am, sizeof(wccp_here_i_am), 0);
 
     // if we failed to send the whole lot, try again at a shorter interval (20%)
     if (sent != sizeof(wccp_here_i_am)) {
-        debugs(80, 2, "ERROR: failed to send WCCP HERE_I_AM packet: " << xstrerror());
+        int xerrno = errno;
+        debugs(80, 2, "ERROR: failed to send WCCP HERE_I_AM packet: " << xstrerr(xerrno));
         interval = 2.0;
     }
 
diff -u -r -N squid-4.0.8/src/whois.cc squid-4.0.9/src/whois.cc
--- squid-4.0.8/src/whois.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/src/whois.cc	2016-04-21 01:19:59.000000000 +1200
@@ -121,9 +121,9 @@
     debugs(75, 5, "{" << aBuffer << "}");
 
     if (flag != Comm::OK) {
-        debugs(50, 2, HERE  << conn << ": read failure: " << xstrerror() << ".");
+        debugs(50, 2, conn << ": read failure: " << xstrerr(xerrno));
 
-        if (ignoreErrno(errno)) {
+        if (ignoreErrno(xerrno)) {
             AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
                                                  CommIoCbPtrFun(whoisReadReply, this));
             comm_read(conn, aBuffer, BUFSIZ, call);
diff -u -r -N squid-4.0.8/test-suite/stub_cbdata.cc squid-4.0.9/test-suite/stub_cbdata.cc
--- squid-4.0.8/test-suite/stub_cbdata.cc	2016-04-02 11:49:42.000000000 +1300
+++ squid-4.0.9/test-suite/stub_cbdata.cc	2016-04-21 02:18:21.000000000 +1200
@@ -13,9 +13,14 @@
 #include "tests/STUB.h"
 
 void cbdataRegisterWithCacheManager(void) STUB
-
-void *cbdataInternalAlloc(cbdata_type type, const char *, int) STUB_RETVAL(NULL)
-void *cbdataInternalFree(void *p, const char *, int) STUB_RETVAL(NULL)
+void *cbdataInternalAlloc(cbdata_type type, const char *, int sz) {
+//STUB_RETVAL(NULL)
+    return xcalloc(1, sz);
+}
+void *cbdataInternalFree(void *p, const char *, int) {
+    xfree(p);
+    return nullptr;
+}
 #if USE_CBDATA_DEBUG
 void cbdataInternalLockDbg(const void *p, const char *, int) STUB
 void cbdataInternalUnlockDbg(const void *p, const char *, int) STUB
diff -u -r -N squid-4.0.8/tools/cachemgr.cc squid-4.0.9/tools/cachemgr.cc
--- squid-4.0.8/tools/cachemgr.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/tools/cachemgr.cc	2016-04-21 01:19:59.000000000 +1200
@@ -11,6 +11,7 @@
 #include "getfullhostname.h"
 #include "html_quote.h"
 #include "ip/Address.h"
+#include "MemBuf.h"
 #include "rfc1123.h"
 #include "rfc1738.h"
 #include "util.h"
@@ -423,8 +424,8 @@
     return url;
 }
 
-static const char *
-munge_menu_line(const char *buf, cachemgr_request * req)
+static void
+munge_menu_line(MemBuf &out, const char *buf, cachemgr_request * req)
 {
     char *x;
     const char *a;
@@ -432,15 +433,14 @@
     const char *p;
     char *a_url;
     char *buf_copy;
-    static char html[2 * 1024];
-
-    if (strlen(buf) < 1)
-        return buf;
 
-    if (*buf != ' ')
-        return buf;
+    const char bufLen = strlen(buf);
+    if (bufLen < 1 || *buf != ' ') {
+        out.append(buf, bufLen);
+        return;
+    }
 
-    buf_copy = x = xstrdup(buf);
+    buf_copy = x = xstrndup(buf, bufLen);
 
     a = xstrtok(&x, '\t');
 
@@ -452,59 +452,56 @@
 
     /* no reason to give a url for a disabled action */
     if (!strcmp(p, "disabled"))
-        snprintf(html, sizeof(html), "<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
+        out.appendf("<LI type=\"circle\">%s (disabled)<A HREF=\"%s\">.</A>\n", d, a_url);
     else
         /* disable a hidden action (requires a password, but password is not in squid.conf) */
         if (!strcmp(p, "hidden"))
-            snprintf(html, sizeof(html), "<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
+            out.appendf("<LI type=\"circle\">%s (hidden)<A HREF=\"%s\">.</A>\n", d, a_url);
         else
             /* disable link if authentication is required and we have no password */
             if (!strcmp(p, "protected") && !req->passwd)
-                snprintf(html, sizeof(html), "<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
-                         d, menu_url(req, "authenticate"), a_url);
+                out.appendf("<LI type=\"circle\">%s (requires <a href=\"%s\">authentication</a>)<A HREF=\"%s\">.</A>\n",
+                            d, menu_url(req, "authenticate"), a_url);
             else
                 /* highlight protected but probably available entries */
                 if (!strcmp(p, "protected"))
-                    snprintf(html, sizeof(html), "<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
-                             a_url, d);
+                    out.appendf("<LI type=\"square\"><A HREF=\"%s\"><font color=\"#FF0000\">%s</font></A>\n",
+                                a_url, d);
 
     /* public entry or unknown type of protection */
                 else
-                    snprintf(html, sizeof(html), "<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
+                    out.appendf("<LI type=\"disk\"><A HREF=\"%s\">%s</A>\n", a_url, d);
 
     xfree(a_url);
 
     xfree(buf_copy);
-
-    return html;
 }
 
-static const char *
-munge_other_line(const char *buf, cachemgr_request *)
+static void
+munge_other_line(MemBuf &out, const char *buf, cachemgr_request *)
 {
     static const char *ttags[] = {"td", "th"};
 
-    static char html[4096];
     static int table_line_num = 0;
     static int next_is_header = 0;
     int is_header = 0;
     const char *ttag;
     char *buf_copy;
     char *x, *p;
-    int l = 0;
     /* does it look like a table? */
 
     if (!strchr(buf, '\t') || *buf == '\t') {
         /* nope, just text */
-        snprintf(html, sizeof(html), "%s%s",
-                 table_line_num ? "</table>\n<pre>" : "", html_quote(buf));
+        if (table_line_num)
+            out.append("</table>\n<pre>", 14);
+        out.appendf("%s", html_quote(buf));
         table_line_num = 0;
-        return html;
+        return;
     }
 
     /* start html table */
     if (!table_line_num) {
-        l += snprintf(html + l, sizeof(html) - l, "</pre><table cellpadding=\"2\" cellspacing=\"1\">\n");
+        out.append("</pre><table cellpadding=\"2\" cellspacing=\"1\">\n", 46);
         next_is_header = 0;
     }
 
@@ -514,7 +511,7 @@
     ttag = ttags[is_header];
 
     /* record starts */
-    l += snprintf(html + l, sizeof(html) - l, "<tr>");
+    out.append("<tr>", 4);
 
     /* substitute '\t' */
     buf_copy = x = xstrdup(buf);
@@ -531,18 +528,17 @@
             ++x;
         }
 
-        l += snprintf(html + l, sizeof(html) - l, "<%s colspan=\"%d\" align=\"%s\">%s</%s>",
-                      ttag, column_span,
-                      is_header ? "center" : is_number(cell) ? "right" : "left",
-                      html_quote(cell), ttag);
+        out.appendf("<%s colspan=\"%d\" align=\"%s\">%s</%s>",
+                    ttag, column_span,
+                    is_header ? "center" : is_number(cell) ? "right" : "left",
+                    html_quote(cell), ttag);
     }
 
     xfree(buf_copy);
     /* record ends */
-    snprintf(html + l, sizeof(html) - l, "</tr>\n");
+    out.append("</tr>\n", 6);
     next_is_header = is_header && strstr(buf, "\t\t");
     ++table_line_num;
-    return html;
 }
 
 static const char *
@@ -699,14 +695,18 @@
         /* yes, fall through, we do not want to loose the first line */
 
         case isBody:
+        {
             /* interpret [and reformat] cache response */
-
+            MemBuf out;
+            out.init();
             if (parse_menu)
-                fputs(munge_menu_line(buf, req), stdout);
+                munge_menu_line(out, buf, req);
             else
-                fputs(munge_other_line(buf, req), stdout);
+                munge_other_line(out, buf, req);
 
-            break;
+            fputs(out.buf, stdout);
+        }
+        break;
 
         case isForward:
             /* forward: no modifications allowed */
@@ -820,16 +820,16 @@
 #else
     if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
 #endif
-        snprintf(buf, sizeof(buf), "socket: %s\n", xstrerror());
+        int xerrno = errno;
+        snprintf(buf, sizeof(buf), "socket: %s\n", xstrerr(xerrno));
         error_html(buf);
         Ip::Address::FreeAddr(AI);
         return 1;
     }
 
     if (connect(s, AI->ai_addr, AI->ai_addrlen) < 0) {
-        snprintf(buf, sizeof(buf), "connect %s: %s\n",
-                 S.toUrl(ipbuf,MAX_IPSTRLEN),
-                 xstrerror());
+        int xerrno = errno;
+        snprintf(buf, sizeof(buf), "connect %s: %s\n", S.toUrl(ipbuf,MAX_IPSTRLEN), xstrerr(xerrno));
         error_html(buf);
         Ip::Address::FreeAddr(AI);
         close(s);
diff -u -r -N squid-4.0.8/tools/helper-mux/helper-mux.8 squid-4.0.9/tools/helper-mux/helper-mux.8
--- squid-4.0.8/tools/helper-mux/helper-mux.8	2016-04-02 11:49:46.000000000 +1300
+++ squid-4.0.9/tools/helper-mux/helper-mux.8	2016-04-21 02:18:25.000000000 +1200
@@ -133,7 +133,7 @@
 .\" ========================================================================
 .\"
 .IX Title "HELPER-MUX 8"
-.TH HELPER-MUX 8 "2016-04-01" "perl v5.22.1" "User Contributed Perl Documentation"
+.TH HELPER-MUX 8 "2016-04-20" "perl v5.22.1" "User Contributed Perl Documentation"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
diff -u -r -N squid-4.0.8/tools/Makefile.am squid-4.0.9/tools/Makefile.am
--- squid-4.0.8/tools/Makefile.am	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/tools/Makefile.am	2016-04-21 01:19:59.000000000 +1200
@@ -34,9 +34,15 @@
 stub_debug.cc: $(top_srcdir)/src/tests/stub_debug.cc
 	cp $(top_srcdir)/src/tests/stub_debug.cc $@
 
+MemBuf.cc: $(top_srcdir)/src/MemBuf.cc
+	cp $(top_srcdir)/src/MemBuf.cc $@
+
 time.cc: $(top_srcdir)/src/time.cc
 	cp $(top_srcdir)/src/time.cc $@
 
+stub_cbdata.cc: $(top_srcdir)/src/tests/stub_cbdata.cc
+	cp $(top_srcdir)/src/tests/stub_cbdata.cc $@
+
 stub_libmem.cc: $(top_srcdir)/src/tests/stub_libmem.cc STUB.h
 	cp $(top_srcdir)/src/tests/stub_libmem.cc $@
 	
@@ -48,7 +54,7 @@
 # globals.cc is needed by test_tools.cc.
 # Neither of these should be disted from here.
 TESTSOURCES= test_tools.cc
-CLEANFILES += test_tools.cc stub_debug.cc time.cc stub_libmem.cc STUB.h
+CLEANFILES += test_tools.cc MemBuf.cc stub_debug.cc time.cc stub_cbdata.cc stub_libmem.cc STUB.h
 
 ## Test Scripts
 EXTRA_DIST += helper-ok-dying.pl helper-ok.pl
@@ -60,6 +66,8 @@
 libexec_PROGRAMS = cachemgr$(CGIEXT)
 
 cachemgr__CGIEXT__SOURCES = cachemgr.cc \
+	MemBuf.cc \
+	stub_cbdata.cc \
 	stub_debug.cc \
 	stub_libmem.cc \
 	test_tools.cc \
diff -u -r -N squid-4.0.8/tools/Makefile.in squid-4.0.9/tools/Makefile.in
--- squid-4.0.8/tools/Makefile.in	2016-04-02 10:08:10.000000000 +1300
+++ squid-4.0.9/tools/Makefile.in	2016-04-21 01:21:52.000000000 +1200
@@ -166,6 +166,8 @@
 am__installdirs = "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man8dir)"
 PROGRAMS = $(libexec_PROGRAMS)
 am_cachemgr__CGIEXT__OBJECTS = cachemgr__CGIEXT_-cachemgr.$(OBJEXT) \
+	cachemgr__CGIEXT_-MemBuf.$(OBJEXT) \
+	cachemgr__CGIEXT_-stub_cbdata.$(OBJEXT) \
 	cachemgr__CGIEXT_-stub_debug.$(OBJEXT) \
 	cachemgr__CGIEXT_-stub_libmem.$(OBJEXT) \
 	cachemgr__CGIEXT_-test_tools.$(OBJEXT) \
@@ -769,8 +771,8 @@
 DEFAULT_ERROR_DIR = $(datadir)/errors
 AM_CFLAGS = $(SQUID_CFLAGS)
 AM_CXXFLAGS = $(SQUID_CXXFLAGS)
-CLEANFILES = test_tools.cc stub_debug.cc time.cc stub_libmem.cc STUB.h \
-	cachemgr.cgi.8
+CLEANFILES = test_tools.cc MemBuf.cc stub_debug.cc time.cc \
+	stub_cbdata.cc stub_libmem.cc STUB.h cachemgr.cgi.8
 AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/include \
 	-I$(top_srcdir)/lib -I$(top_srcdir)/src \
 	-I$(top_builddir)/include $(SQUID_CPPUNIT_INC) $(KRB5INCS) \
@@ -810,6 +812,8 @@
 TESTSOURCES = test_tools.cc
 DEFAULT_CACHEMGR_CONFIG = $(sysconfdir)/cachemgr.conf
 cachemgr__CGIEXT__SOURCES = cachemgr.cc \
+	MemBuf.cc \
+	stub_cbdata.cc \
 	stub_debug.cc \
 	stub_libmem.cc \
 	test_tools.cc \
@@ -920,7 +924,9 @@
 distclean-compile:
 	-rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-cachemgr.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-stub_debug.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-stub_libmem.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cachemgr__CGIEXT_-test_tools.Po@am__quote@
@@ -964,6 +970,34 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -c -o cachemgr__CGIEXT_-cachemgr.obj `if test -f 'cachemgr.cc'; then $(CYGPATH_W) 'cachemgr.cc'; else $(CYGPATH_W) '$(srcdir)/cachemgr.cc'; fi`
 
+cachemgr__CGIEXT_-MemBuf.o: MemBuf.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -MT cachemgr__CGIEXT_-MemBuf.o -MD -MP -MF $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Tpo -c -o cachemgr__CGIEXT_-MemBuf.o `test -f 'MemBuf.cc' || echo '$(srcdir)/'`MemBuf.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Tpo $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='MemBuf.cc' object='cachemgr__CGIEXT_-MemBuf.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -c -o cachemgr__CGIEXT_-MemBuf.o `test -f 'MemBuf.cc' || echo '$(srcdir)/'`MemBuf.cc
+
+cachemgr__CGIEXT_-MemBuf.obj: MemBuf.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -MT cachemgr__CGIEXT_-MemBuf.obj -MD -MP -MF $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Tpo -c -o cachemgr__CGIEXT_-MemBuf.obj `if test -f 'MemBuf.cc'; then $(CYGPATH_W) 'MemBuf.cc'; else $(CYGPATH_W) '$(srcdir)/MemBuf.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Tpo $(DEPDIR)/cachemgr__CGIEXT_-MemBuf.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='MemBuf.cc' object='cachemgr__CGIEXT_-MemBuf.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -c -o cachemgr__CGIEXT_-MemBuf.obj `if test -f 'MemBuf.cc'; then $(CYGPATH_W) 'MemBuf.cc'; else $(CYGPATH_W) '$(srcdir)/MemBuf.cc'; fi`
+
+cachemgr__CGIEXT_-stub_cbdata.o: stub_cbdata.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -MT cachemgr__CGIEXT_-stub_cbdata.o -MD -MP -MF $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Tpo -c -o cachemgr__CGIEXT_-stub_cbdata.o `test -f 'stub_cbdata.cc' || echo '$(srcdir)/'`stub_cbdata.cc
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Tpo $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='stub_cbdata.cc' object='cachemgr__CGIEXT_-stub_cbdata.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -c -o cachemgr__CGIEXT_-stub_cbdata.o `test -f 'stub_cbdata.cc' || echo '$(srcdir)/'`stub_cbdata.cc
+
+cachemgr__CGIEXT_-stub_cbdata.obj: stub_cbdata.cc
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -MT cachemgr__CGIEXT_-stub_cbdata.obj -MD -MP -MF $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Tpo -c -o cachemgr__CGIEXT_-stub_cbdata.obj `if test -f 'stub_cbdata.cc'; then $(CYGPATH_W) 'stub_cbdata.cc'; else $(CYGPATH_W) '$(srcdir)/stub_cbdata.cc'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Tpo $(DEPDIR)/cachemgr__CGIEXT_-stub_cbdata.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	$(AM_V_CXX)source='stub_cbdata.cc' object='cachemgr__CGIEXT_-stub_cbdata.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -c -o cachemgr__CGIEXT_-stub_cbdata.obj `if test -f 'stub_cbdata.cc'; then $(CYGPATH_W) 'stub_cbdata.cc'; else $(CYGPATH_W) '$(srcdir)/stub_cbdata.cc'; fi`
+
 cachemgr__CGIEXT_-stub_debug.o: stub_debug.cc
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(cachemgr__CGIEXT__CXXFLAGS) $(CXXFLAGS) -MT cachemgr__CGIEXT_-stub_debug.o -MD -MP -MF $(DEPDIR)/cachemgr__CGIEXT_-stub_debug.Tpo -c -o cachemgr__CGIEXT_-stub_debug.o `test -f 'stub_debug.cc' || echo '$(srcdir)/'`stub_debug.cc
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/cachemgr__CGIEXT_-stub_debug.Tpo $(DEPDIR)/cachemgr__CGIEXT_-stub_debug.Po
@@ -1528,9 +1562,15 @@
 stub_debug.cc: $(top_srcdir)/src/tests/stub_debug.cc
 	cp $(top_srcdir)/src/tests/stub_debug.cc $@
 
+MemBuf.cc: $(top_srcdir)/src/MemBuf.cc
+	cp $(top_srcdir)/src/MemBuf.cc $@
+
 time.cc: $(top_srcdir)/src/time.cc
 	cp $(top_srcdir)/src/time.cc $@
 
+stub_cbdata.cc: $(top_srcdir)/src/tests/stub_cbdata.cc
+	cp $(top_srcdir)/src/tests/stub_cbdata.cc $@
+
 stub_libmem.cc: $(top_srcdir)/src/tests/stub_libmem.cc STUB.h
 	cp $(top_srcdir)/src/tests/stub_libmem.cc $@
 
diff -u -r -N squid-4.0.8/tools/MemBuf.cc squid-4.0.9/tools/MemBuf.cc
--- squid-4.0.8/tools/MemBuf.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-4.0.9/tools/MemBuf.cc	2016-04-21 02:18:23.000000000 +1200
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+/* DEBUG: section 59    auto-growing Memory Buffer with printf */
+
+/**
+ \verbatim
+ * Rationale:
+ * ----------
+ *
+ * Here is how one would Comm::Write an object without MemBuffer:
+ *
+ * {
+ * -- allocate:
+ * buf = malloc(big_enough);
+ *
+ * -- "pack":
+ * snprintf object(s) piece-by-piece constantly checking for overflows
+ * and maintaining (buf+offset);
+ * ...
+ *
+ * -- write
+ * Comm::Write(buf, free, ...);
+ * }
+ *
+ * The whole "packing" idea is quite messy: We are given a buffer of fixed
+ * size and we have to check all the time that we still fit. Sounds logical.
+ *
+ * However, what happens if we have more data? If we are lucky to stop before
+ * we overrun any buffers, we still may have garbage (e.g. half of ETag) in
+ * the buffer.
+ *
+ * MemBuffer:
+ * ----------
+ *
+ * MemBuffer is a memory-resident buffer with printf()-like interface. It
+ * hides all offest handling and overflow checking. Moreover, it has a
+ * build-in control that no partial data has been written.
+ *
+ * MemBuffer is designed to handle relatively small data. It starts with a
+ * small buffer of configurable size to avoid allocating huge buffers all the
+ * time.  MemBuffer doubles the buffer when needed. It assert()s that it will
+ * not grow larger than a configurable limit. MemBuffer has virtually no
+ * overhead (and can even reduce memory consumption) compared to old
+ * "packing" approach.
+ *
+ * MemBuffer eliminates both "packing" mess and truncated data:
+ *
+ * {
+ * -- setup
+ * MemBuf buf;
+ *
+ * -- required init with optional size tuning (see #defines for defaults)
+ * buf.init(initial-size, absolute-maximum);
+ *
+ * -- "pack" (no need to handle offsets or check for overflows)
+ * buf.Printf(...);
+ * ...
+ *
+ * -- write
+ * Comm::Write(fd, buf, callback);
+ *
+ * -- *iff* you did not give the buffer away, free it yourself
+ * -- buf.clean();
+ * }
+ \endverbatim
+ */
+
+#include "squid.h"
+#include "mem/forward.h"
+#include "MemBuf.h"
+#include "profiler/Profiler.h"
+
+#ifdef VA_COPY
+#undef VA_COPY
+#endif
+#if defined HAVE_VA_COPY
+#define VA_COPY va_copy
+#elif defined HAVE___VA_COPY
+#define VA_COPY __va_copy
+#endif
+
+/* local constants */
+
+/* default values for buffer sizes, used by memBufDefInit */
+#define MEM_BUF_INIT_SIZE   (2*1024)
+#define MEM_BUF_MAX_SIZE    (2*1000*1024*1024)
+
+CBDATA_CLASS_INIT(MemBuf);
+
+/** init with defaults */
+void
+MemBuf::init()
+{
+    init(MEM_BUF_INIT_SIZE, MEM_BUF_MAX_SIZE);
+}
+
+/** init with specific sizes */
+void
+MemBuf::init(mb_size_t szInit, mb_size_t szMax)
+{
+    assert(szInit > 0 && szMax > 0);
+    buf = NULL;
+    size = 0;
+    max_capacity = szMax;
+    capacity = 0;
+    stolen = 0;
+    grow(szInit);
+    terminate();
+}
+
+/**
+ * cleans the mb; last function to call if you do not give .buf away with
+ * memBufFreeFunc
+ */
+void
+MemBuf::clean()
+{
+    if (isNull()) {
+        // nothing to do
+    } else {
+        assert(buf);
+        assert(!stolen);    /* not frozen */
+
+        memFreeBuf(capacity, buf);
+        buf = NULL;
+        size = capacity = max_capacity = 0;
+    }
+}
+
+/**
+ * Cleans the buffer without changing its capacity
+ * if called with a Null buffer, calls memBufDefInit()
+ */
+void
+MemBuf::reset()
+{
+    if (isNull()) {
+        init();
+    } else {
+        assert(!stolen);    /* not frozen */
+        /* reset */
+        memset(buf, 0, capacity);
+        size = 0;
+    }
+}
+
+/**
+ * Unfortunate hack to test if the buffer has been Init()ialized
+ */
+int
+MemBuf::isNull()
+{
+    if (!buf && !max_capacity && !capacity && !size)
+        return 1;       /* is null (not initialized) */
+
+    assert(buf && max_capacity && capacity);    /* paranoid */
+
+    return 0;
+}
+
+mb_size_t MemBuf::spaceSize() const
+{
+    const mb_size_t terminatedSize = size + 1;
+    return (terminatedSize < capacity) ? capacity - terminatedSize : 0;
+}
+
+mb_size_t MemBuf::potentialSpaceSize() const
+{
+    const mb_size_t terminatedSize = size + 1;
+    return (terminatedSize < max_capacity) ? max_capacity - terminatedSize : 0;
+}
+
+/// removes sz bytes and "packs" by moving content left
+void MemBuf::consume(mb_size_t shiftSize)
+{
+    const mb_size_t cSize = contentSize();
+    assert(0 <= shiftSize && shiftSize <= cSize);
+    assert(!stolen); /* not frozen */
+
+    PROF_start(MemBuf_consume);
+    if (shiftSize > 0) {
+        if (shiftSize < cSize)
+            memmove(buf, buf + shiftSize, cSize - shiftSize);
+
+        size -= shiftSize;
+
+        terminate();
+    }
+    PROF_stop(MemBuf_consume);
+}
+
+/// removes all whitespace prefix bytes and "packs" by moving content left
+void MemBuf::consumeWhitespacePrefix()
+{
+    PROF_start(MemBuf_consumeWhitespace);
+    if (contentSize() > 0) {
+        const char *end = buf + contentSize();
+        const char *p = buf;
+        for (; p<end && xisspace(*p); ++p);
+        if (p-buf > 0)
+            consume(p-buf);
+    }
+    PROF_stop(MemBuf_consumeWhitespace);
+}
+
+// removes last tailSize bytes
+void MemBuf::truncate(mb_size_t tailSize)
+{
+    const mb_size_t cSize = contentSize();
+    assert(0 <= tailSize && tailSize <= cSize);
+    assert(!stolen); /* not frozen */
+    size -= tailSize;
+}
+
+/**
+ * calls memcpy, appends exactly size bytes,
+ * extends buffer or creates buffer if needed.
+ */
+void MemBuf::append(const char *newContent, int sz)
+{
+    assert(sz >= 0);
+    assert(buf || (0==capacity && 0==size));
+    assert(!stolen); /* not frozen */
+
+    PROF_start(MemBuf_append);
+    if (sz > 0) {
+        if (size + sz + 1 > capacity)
+            grow(size + sz + 1);
+
+        assert(size + sz <= capacity); /* paranoid */
+        memcpy(space(), newContent, sz);
+        appended(sz);
+    }
+    PROF_stop(MemBuf_append);
+}
+
+/// updates content size after external append
+void MemBuf::appended(mb_size_t sz)
+{
+    assert(size + sz <= capacity);
+    size += sz;
+    terminate();
+}
+
+/**
+ * Null-terminate in case we are used as a string.
+ * Extra octet is not counted in the content size (or space size)
+ *
+ \note XXX: but the extra octet is counted when growth decisions are made!
+ *     This will cause the buffer to grow when spaceSize() == 1 on append,
+ *     which will assert() if the buffer cannot grow any more.
+ */
+void MemBuf::terminate()
+{
+    assert(size < capacity);
+    *space() = '\0';
+}
+
+/**
+ * vappendf for other printf()'s to use; calls vsnprintf, extends buf if needed
+ */
+void
+MemBuf::vappendf(const char *fmt, va_list vargs)
+{
+#ifdef VA_COPY
+    va_list ap;
+#endif
+
+    int sz = 0;
+    assert(fmt);
+    assert(buf);
+    assert(!stolen);    /* not frozen */
+    /* assert in Grow should quit first, but we do not want to have a scary infinite loop */
+
+    while (capacity <= max_capacity) {
+        mb_size_t free_space = capacity - size;
+        /* put as much as we can */
+
+#ifdef VA_COPY
+        /* Fix of bug 753r. The value of vargs is undefined
+         * after vsnprintf() returns. Make a copy of vargs
+         * incase we loop around and call vsnprintf() again.
+         */
+        VA_COPY(ap,vargs);
+        sz = vsnprintf(buf + size, free_space, fmt, ap);
+        va_end(ap);
+#else /* VA_COPY */
+
+        sz = vsnprintf(buf + size, free_space, fmt, vargs);
+#endif /*VA_COPY*/
+        /* check for possible overflow */
+        /* snprintf on Linuz returns -1 on overflows */
+        /* snprintf on FreeBSD returns at least free_space on overflows */
+
+        if (sz < 0 || sz >= free_space)
+            grow(capacity + 1);
+        else
+            break;
+    }
+
+    size += sz;
+    /* on Linux and FreeBSD, '\0' is not counted in return value */
+    /* on XXX it might be counted */
+    /* check that '\0' is appended and not counted */
+
+    if (!size || buf[size - 1]) {
+        assert(!buf[size]);
+    } else {
+        --size;
+    }
+}
+
+/**
+ * Important:
+ *   calling this function "freezes" mb,
+ *   do not _update_ mb after that in any way
+ *   (you still can read-access .buf and .size)
+ *
+ \retval free() function to be used.
+ */
+FREE *
+MemBuf::freeFunc()
+{
+    FREE *ff;
+    assert(buf);
+    assert(!stolen);    /* not frozen */
+
+    ff = memFreeBufFunc((size_t) capacity);
+    stolen = 1;     /* freeze */
+    return ff;
+}
+
+/**
+ * Grows (doubles) internal buffer to satisfy required minimal capacity
+ */
+void
+MemBuf::grow(mb_size_t min_cap)
+{
+    size_t new_cap;
+    size_t buf_cap;
+
+    assert(!stolen);
+    assert(capacity < min_cap);
+
+    PROF_start(MemBuf_grow);
+
+    /* determine next capacity */
+
+    if (min_cap > 64 * 1024) {
+        new_cap = 64 * 1024;
+
+        while (new_cap < (size_t) min_cap)
+            new_cap += 64 * 1024;   /* increase in reasonable steps */
+    } else {
+        new_cap = (size_t) min_cap;
+    }
+
+    /* last chance to fit before we assert(!overflow) */
+    if (new_cap > (size_t) max_capacity)
+        new_cap = (size_t) max_capacity;
+
+    assert(new_cap <= (size_t) max_capacity);   /* no overflow */
+
+    assert(new_cap > (size_t) capacity);    /* progress */
+
+    buf_cap = (size_t) capacity;
+
+    buf = (char *)memReallocBuf(buf, new_cap, &buf_cap);
+
+    /* done */
+    capacity = (mb_size_t) buf_cap;
+    PROF_stop(MemBuf_grow);
+}
+
+/* Reports */
+
+/**
+ * Puts report on MemBuf _module_ usage into mb
+ */
+void
+memBufReport(MemBuf * mb)
+{
+    assert(mb);
+    mb->appendf("memBufReport is not yet implemented @?@\n");
+}
+
diff -u -r -N squid-4.0.8/tools/squidclient/squidclient.cc squid-4.0.9/tools/squidclient/squidclient.cc
--- squid-4.0.8/tools/squidclient/squidclient.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/tools/squidclient/squidclient.cc	2016-04-21 01:19:59.000000000 +1200
@@ -347,7 +347,8 @@
         set_our_signal();
 
         if (put_fd < 0) {
-            std::cerr << "ERROR: can't open file (" << xstrerror() << ")" << std::endl;
+            int xerrno = errno;
+            std::cerr << "ERROR: can't open file (" << xstrerr(xerrno) << ")" << std::endl;
             exit(-1);
         }
 #if _SQUID_WINDOWS_
@@ -355,7 +356,8 @@
 #endif
 
         if (fstat(put_fd, &sb) < 0) {
-            std::cerr << "ERROR: can't identify length of file (" << xstrerror() << ")" << std::endl;
+            int xerrno = errno;
+            std::cerr << "ERROR: can't identify length of file (" << xstrerr(xerrno) << ")" << std::endl;
         }
     }
 
@@ -544,8 +546,10 @@
         while ((len = Transport::Read(buf, sizeof(buf))) > 0) {
             fsize += len;
 
-            if (to_stdout && fwrite(buf, len, 1, stdout) != 1)
-                std::cerr << "ERROR: writing to stdout: " << xstrerror() << std::endl;
+            if (to_stdout && fwrite(buf, len, 1, stdout) != 1) {
+                int xerrno = errno;
+                std::cerr << "ERROR: writing to stdout: " << xstrerr(xerrno) << std::endl;
+            }
         }
 
 #if USE_GNUTLS
diff -u -r -N squid-4.0.8/tools/squidclient/Transport.cc squid-4.0.9/tools/squidclient/Transport.cc
--- squid-4.0.8/tools/squidclient/Transport.cc	2016-04-02 10:04:07.000000000 +1300
+++ squid-4.0.9/tools/squidclient/Transport.cc	2016-04-21 01:19:59.000000000 +1200
@@ -348,7 +348,8 @@
     debugVerbose(3, "Initializing TLS library...");
     // NP: gnutls init is re-entrant and lock-counted with deinit but not thread safe.
     if (gnutls_global_init() != GNUTLS_E_SUCCESS) {
-        std::cerr << "FATAL ERROR: TLS Initialize failed: " << xstrerror() << std::endl;
+        int xerrno = errno;
+        std::cerr << "FATAL ERROR: TLS Initialize failed: " << xstrerr(xerrno) << std::endl;
         exit(1);
     }
 
diff -u -r -N squid-4.0.8/tools/stub_cbdata.cc squid-4.0.9/tools/stub_cbdata.cc
--- squid-4.0.8/tools/stub_cbdata.cc	1970-01-01 12:00:00.000000000 +1200
+++ squid-4.0.9/tools/stub_cbdata.cc	2016-04-21 02:18:23.000000000 +1200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
+#include "squid.h"
+#include "cbdata.h"
+
+#define STUB_API "cbdata.cc"
+#include "tests/STUB.h"
+
+void cbdataRegisterWithCacheManager(void) STUB
+void *cbdataInternalAlloc(cbdata_type type, const char *, int sz) {
+//STUB_RETVAL(NULL)
+    return xcalloc(1, sz);
+}
+void *cbdataInternalFree(void *p, const char *, int) {
+    xfree(p);
+    return nullptr;
+}
+#if USE_CBDATA_DEBUG
+void cbdataInternalLockDbg(const void *p, const char *, int) STUB
+void cbdataInternalUnlockDbg(const void *p, const char *, int) STUB
+int cbdataInternalReferenceDoneValidDbg(void **p, void **tp, const char *, int) STUB_RETVAL(0)
+#else
+void cbdataInternalLock(const void *p) STUB
+void cbdataInternalUnlock(const void *p) STUB
+int cbdataInternalReferenceDoneValid(void **p, void **tp) STUB_RETVAL(0)
+#endif
+
+int cbdataReferenceValid(const void *p) STUB_RETVAL(0)
+cbdata_type cbdataInternalAddType(cbdata_type, const char *, int) STUB_RETVAL(CBDATA_UNKNOWN)
+
