]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ipc_win32.cc
Source Format Enforcement (#1234)
[thirdparty/squid.git] / src / ipc_win32.cc
index bb97d1a1b95cdb6b170bec3aa497bb2d6ce6a118..04a0c8d31f1351904cdb5173c16b53d96f4f9413 100644 (file)
@@ -1,55 +1,31 @@
 /*
- * DEBUG: section 54    Windows Interprocess Communication
- * AUTHOR: Andrey Shorin <tolsty@tushino.com>
- * AUTHOR: Guido Serassio <serassio@squid-cache.org>
- *
- * SQUID Web Proxy Cache          http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- *  Squid is the result of efforts by numerous individuals from
- *  the Internet community; see the CONTRIBUTORS file for full
- *  details.   Many organizations have provided support for Squid's
- *  development; see the SPONSORS file for full details.  Squid is
- *  Copyrighted (C) 2001 by the Regents of the University of
- *  California; see the COPYRIGHT file for full details.  Squid
- *  incorporates software developed and/or copyrighted by other
- *  sources; see the CREDITS file for full details.
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ * Copyright (C) 1996-2023 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 54    Windows Interprocess Communication */
+
 #include "squid.h"
 #include "cache_cf.h"
 #include "comm.h"
+#include "comm/Connection.h"
 #include "fd.h"
 #include "fde.h"
+#include "globals.h"
 #include "ip/Address.h"
 #include "rfc1738.h"
 #include "SquidConfig.h"
 #include "SquidIpc.h"
-#include "SquidTime.h"
 #include "tools.h"
 
-#ifndef _MSWSOCK_
+#include <cerrno>
+#if HAVE_MSWSOCK_H
 #include <mswsock.h>
 #endif
 #include <process.h>
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
 
 struct ipc_params {
     int type;
@@ -151,15 +127,15 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     }
 
     if (type == IPC_TCP_SOCKET) {
-        crfd = cwfd = comm_open(SOCK_STREAM,
-                                IPPROTO_TCP,
-                                local_addr,
-                                COMM_NOCLOEXEC,
-                                name);
+        crfd = cwfd = comm_open_listener(SOCK_STREAM,
+                                         IPPROTO_TCP,
+                                         local_addr,
+                                         COMM_NOCLOEXEC,
+                                         name);
         prfd = pwfd = comm_open(SOCK_STREAM,
-                                IPPROTO_TCP,   /* protocol */
+                                IPPROTO_TCP,    /* protocol */
                                 local_addr,
-                                0,                     /* blocking */
+                                0,          /* blocking */
                                 name);
     } else if (type == IPC_UDP_SOCKET) {
         crfd = cwfd = comm_open(SOCK_DGRAM,
@@ -191,45 +167,52 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     }
 
     if (crfd < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: Failed to create child FD.");
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: Failed to create child FD.");
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
     if (pwfd < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: Failed to create server FD.");
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: Failed to create server FD.");
         return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
 // AYJ: these flags should be neutral, but if not IPv6 version needs adding
     if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
 
-        tmp_addr.InitAddrInfo(aiPS);
+        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);
         }
 
         tmp_addr = *aiPS;
+        Ip::Address::FreeAddr(aiPS);
 
         debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << tmp_addr );
 
-        tmp_addr.InitAddrInfo(aiCS);
+        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);
         }
 
-        tmp_addr.SetEmpty();
+        tmp_addr.setEmpty();
         tmp_addr = *aiCS;
+        Ip::Address::FreeAddr(aiCS);
 
         debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << tmp_addr );
     }
 
     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);
         }
 
@@ -256,12 +239,13 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     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);
     }
 
     /* NP: tmp_addr was left with eiether empty or aiCS in Ip::Address format */
-    if (comm_connect_addr(pwfd, tmp_addr) == COMM_ERROR) {
+    if (comm_connect_addr(pwfd, tmp_addr) == Comm::COMM_ERROR) {
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     }
@@ -270,12 +254,13 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     x = recv(prfd, (void *)hello_buf, HELLO_BUF_SZ - 1, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: hello read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: PARENT: hello read test failed");
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     } else if (strcmp(hello_buf, hello_string)) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: hello read test failed");
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: PARENT: hello read test failed");
         debugs(54, DBG_CRITICAL, "--> read returned " << x);
         debugs(54, DBG_CRITICAL, "--> got '" << rfc1738_escape(hello_buf) << "'");
         CloseHandle((HANDLE) thread);
@@ -285,8 +270,9 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     x = send(pwfd, (const void *)ok_string, strlen(ok_string), 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: OK write test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: PARENT: OK write test failed");
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     }
@@ -295,12 +281,13 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     x = recv(prfd, (void *)hello_buf, HELLO_BUF_SZ - 1, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: OK read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: PARENT: OK read test failed");
+        debugs(54, DBG_CRITICAL, "--> read: " << xstrerr(xerrno));
         CloseHandle((HANDLE) thread);
         return ipcCloseAllFD(prfd, pwfd, -1, -1);
     } else if (!strcmp(hello_buf, err_string)) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: PARENT: OK read test failed");
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: PARENT: OK read test failed");
         debugs(54, DBG_CRITICAL, "--> read returned " << x);
         debugs(54, DBG_CRITICAL, "--> got '" << rfc1738_escape(hello_buf) << "'");
         CloseHandle((HANDLE) thread);
@@ -321,13 +308,10 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
     if (wfd)
         *wfd = pwfd;
 
-    fd_table[prfd].flags.ipc = 1;
-
-    fd_table[pwfd].flags.ipc = 1;
-
-    fd_table[crfd].flags.ipc = 1;
-
-    fd_table[cwfd].flags.ipc = 1;
+    fd_table[prfd].flags.ipc = true;
+    fd_table[pwfd].flags.ipc = true;
+    fd_table[crfd].flags.ipc = true;
+    fd_table[cwfd].flags.ipc = true;
 
     if (Config.sleep_after_fork) {
         /* XXX emulation of usleep() */
@@ -354,13 +338,12 @@ ipcCreate(int type, const char *prog, const char *const args[], const char *name
 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());
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerr(xerrno));
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: hello write test failed");
     }
 
     return x;
@@ -399,7 +382,8 @@ ipc_thread_1(void *in_params)
     Ip::Address PS = params->PS;
     Ip::Address local_addr = params->local_addr;
 
-    buf1 = (char *)xcalloc(1, 8192);
+    const size_t bufSz = 8192;
+    buf1 = (char *)xcalloc(1, bufSz);
     strcpy(buf1, params->prog);
     prog = strtok(buf1, w_space);
 
@@ -415,39 +399,42 @@ ipc_thread_1(void *in_params)
         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;
         }
 
         debugs(54, 3, "ipcCreate: CHILD accepted new FD " << fd);
         comm_close(crfd);
-        snprintf(buf1, 8191, "%s CHILD socket", prog);
+        snprintf(buf1, bufSz-1, "%s CHILD socket", prog);
         fd_open(fd, FD_SOCKET, buf1);
         fd_table[fd].flags.ipc = 1;
         cwfd = crfd = fd;
     } else if (type == IPC_UDP_SOCKET) {
-        if (comm_connect_addr(crfd, params->PS) == COMM_ERROR)
+        if (comm_connect_addr(crfd, params->PS) == Comm::COMM_ERROR)
             goto cleanup;
     }
 
     x = send(cwfd, (const void *)hello_string, strlen(hello_string) + 1, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerror());
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: hello write test failed");
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "sendto FD " << cwfd << ": " << xstrerr(xerrno));
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: hello write test failed");
         goto cleanup;
     }
 
     PutEnvironment();
-    memset(buf1, '\0', sizeof(buf1));
-    x = recv(crfd, (void *)buf1, 8191, 0);
+    memset(buf1, '\0', bufSz);
+    x = recv(crfd, (void *)buf1, bufSz-1, 0);
 
     if (x < 0) {
-        debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: OK read test failed");
-        debugs(54, DBG_CRITICAL, "--> read: " << xstrerror());
+        int xerrno = errno;
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: OK read test failed");
+        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");
+        debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: OK read test failed");
         debugs(54, DBG_CRITICAL, "--> read returned " << x);
         debugs(54, DBG_CRITICAL, "--> got '" << rfc1738_escape(hello_buf) << "'");
         goto cleanup;
@@ -455,72 +442,80 @@ ipc_thread_1(void *in_params)
 
     /* 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;
     }
 
     if (type == IPC_UDP_SOCKET) {
-        snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
+        snprintf(buf1, bufSz, "%s(%ld) <-> ipc CHILD socket", prog, -1L);
         crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
 
         if (crfd_ipc < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: Failed to create child FD for " << prog << ".");
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: Failed to create child FD for " << prog << ".");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
+        snprintf(buf1, bufSz, "%s(%ld) <-> ipc PARENT socket", prog, -1L);
         prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, buf1);
 
         if (pwfd_ipc < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: Failed to create server FD for " << prog << ".");
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: Failed to create server FD for " << prog << ".");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        PS_ipc.InitAddrInfo(aiPS_ipc);
+        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;
         }
 
         PS_ipc = *aiPS_ipc;
+        Ip::Address::FreeAddr(aiPS_ipc);
 
         debugs(54, 3, "ipcCreate: FD " << pwfd_ipc << " sockaddr " << PS_ipc);
 
-        CS_ipc.InitAddrInfo(aiCS_ipc);
+        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;
         }
 
         CS_ipc = *aiCS_ipc;
+        Ip::Address::FreeAddr(aiCS_ipc);
 
         debugs(54, 3, "ipcCreate: FD " << crfd_ipc << " sockaddr " << CS_ipc);
 
-        if (comm_connect_addr(pwfd_ipc, CS_ipc) == COMM_ERROR) {
+        if (comm_connect_addr(pwfd_ipc, CS_ipc) == Comm::COMM_ERROR) {
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
         fd = crfd;
 
-        if (comm_connect_addr(crfd_ipc, PS_ipc) == COMM_ERROR) {
+        if (comm_connect_addr(crfd_ipc, PS_ipc) == Comm::COMM_ERROR) {
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
-    }                          /* IPC_UDP_SOCKET */
+    }               /* IPC_UDP_SOCKET */
 
     t1 = dup(0);
 
@@ -594,8 +589,7 @@ ipc_thread_1(void *in_params)
     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;
@@ -607,8 +601,8 @@ ipc_thread_1(void *in_params)
         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;
         }
@@ -616,23 +610,23 @@ ipc_thread_1(void *in_params)
         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());
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerr(xerrno));
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        x = read(p2c[0], buf1, 8192);
+        x = read(p2c[0], buf1, bufSz-1);
 
         if (x < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerror());
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerr(xerrno));
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         } else if (strncmp(buf1, ok_string, strlen(ok_string))) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             debugs(54, DBG_CRITICAL, "--> read returned " << x);
             buf1[x] = '\0';
             debugs(54, DBG_CRITICAL, "--> got '" << rfc1738_escape(buf1) << "'");
@@ -643,23 +637,23 @@ ipc_thread_1(void *in_params)
         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());
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: write FD " << c2p[1] << ": " << xstrerr(xerrno));
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         }
 
-        x = read(p2c[0], buf1, 8192);
+        x = read(p2c[0], buf1, bufSz-1);
 
         if (x < 0) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerror());
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
-
+            int xerrno = errno;
+            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: read FD " << p2c[0] << ": " << xstrerr(xerrno));
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             ipcSend(cwfd, err_string, strlen(err_string));
             goto cleanup;
         } else if (strncmp(buf1, ok_string, strlen(ok_string))) {
-            debugs(54, DBG_CRITICAL, "ipcCreate: CHILD: " << prog << ": socket exchange failed");
+            debugs(54, DBG_CRITICAL, "ERROR: ipcCreate: CHILD: " << prog << ": socket exchange failed");
             debugs(54, DBG_CRITICAL, "--> read returned " << x);
             buf1[x] = '\0';
             debugs(54, DBG_CRITICAL, "--> got '" << rfc1738_escape(buf1) << "'");
@@ -668,19 +662,19 @@ ipc_thread_1(void *in_params)
         }
 
         x = send(pwfd_ipc, (const void *)ok_string, strlen(ok_string), 0);
-        x = recv(prfd_ipc, (void *)(buf1 + 200), 8191 - 200, 0);
+        x = recv(prfd_ipc, (void *)(buf1 + 200), bufSz -1 - 200, 0);
         assert((size_t) x == strlen(ok_string)
                && !strncmp(ok_string, buf1 + 200, strlen(ok_string)));
-    }                          /* IPC_UDP_SOCKET */
+    }               /* IPC_UDP_SOCKET */
 
-    snprintf(buf1, 8191, "%s(%ld) CHILD socket", prog, (long int) pid);
+    snprintf(buf1, bufSz-1, "%s(%ld) CHILD socket", prog, (long int) pid);
 
     fd_note(fd, buf1);
 
     if (prfd_ipc != -1) {
-        snprintf(buf1, 8191, "%s(%ld) <-> ipc CHILD socket", prog, (long int) pid);
+        snprintf(buf1, bufSz-1, "%s(%ld) <-> ipc CHILD socket", prog, (long int) pid);
         fd_note(crfd_ipc, buf1);
-        snprintf(buf1, 8191, "%s(%ld) <-> ipc PARENT socket", prog, (long int) pid);
+        snprintf(buf1, bufSz-1, "%s(%ld) <-> ipc PARENT socket", prog, (long int) pid);
         fd_note(prfd_ipc, buf1);
     }
 
@@ -701,12 +695,13 @@ ipc_thread_1(void *in_params)
     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;
     }
 
-    snprintf(buf1, 8191, "%ld\n", (long int) pid);
+    snprintf(buf1, bufSz-1, "%ld\n", (long int) pid);
 
     if (-1 == ipcSend(cwfd, buf1, strlen(buf1)))
         goto cleanup;
@@ -715,7 +710,7 @@ ipc_thread_1(void *in_params)
 
     /* cycle */
     for (;;) {
-        x = recv(crfd, (void *)buf1, 8192, 0);
+        x = recv(crfd, (void *)buf1, bufSz-1, 0);
 
         if (x <= 0) {
             debugs(54, 3, "ipc(" << prog << "," << pid << "): " << x << " bytes received from parent. Exiting...");
@@ -783,11 +778,8 @@ cleanup:
     if (!retval)
         debugs(54, 2, "ipc(" << prog << "," << pid << "): normal exit");
 
-    if (buf1)
-        xfree(buf1);
-
-    if (prog)
-        xfree(prog);
+    xfree(buf1);
+    xfree(prog);
 
     if (thread)
         CloseHandle(thread);
@@ -812,13 +804,14 @@ ipc_thread_2(void *in_params)
     int send_fd = params->send_fd;
     char *prog = xstrdup(params->prog);
     pid_t pid = params->pid;
-    char *buf2 = (char *)xcalloc(1, 8192);
+    const size_t bufSz = 8192;
+    char *buf2 = (char *)xcalloc(1, bufSz);
 
     for (;;) {
         if (type == IPC_TCP_SOCKET)
-            x = read(rfd, buf2, 8192);
+            x = read(rfd, buf2, bufSz-1);
         else
-            x = recv(rfd, (void *)buf2, 8192, 0);
+            x = recv(rfd, (void *)buf2, bufSz-1, 0);
 
         if ((x <= 0 && type == IPC_TCP_SOCKET) ||
                 (x < 0 && type == IPC_UDP_SOCKET)) {
@@ -831,7 +824,6 @@ ipc_thread_2(void *in_params)
 
         if (type == IPC_UDP_SOCKET && !strcmp(buf2, shutdown_string)) {
             debugs(54, 3, "ipc(" << prog << "," << pid << "): request for shutdown received. Exiting...");
-
             break;
         }
 
@@ -859,3 +851,4 @@ ipc_thread_2(void *in_params)
     xfree(buf2);
     return 0;
 }
+