From 5be401dca3e17af97534795551b9ba7c95db05c5 Mon Sep 17 00:00:00 2001 From: Francesco Chemolli <5175948+kinkie@users.noreply.github.com> Date: Thu, 31 Jul 2025 18:01:47 +0000 Subject: [PATCH] Enhance and use POSIX socket compatibility layer (#2046) Implement portable wrappers around most socket-related functions, named x[function], and use them in all callsites. winsock's socket-related functions are very similar but not identical to the POSIX standard. Make the mswindows compatibility layer available to MinGW, and modernize it. Error highlighting the issue: ``` TcpAcceptor.cc: In member function 'bool Comm::TcpAcceptor::acceptInto(Comm::ConnectionPointer&)': TcpAcceptor.cc:352:17: error: comparison of unsigned expression in '< 0' is always false [-Werror=type-limits] 352 | if (rawSock < 0) { ``` --- compat/Makefile.am | 10 + compat/mswindows.cc | 5 +- compat/netdb.cc | 34 ++ compat/netdb.h | 37 +++ compat/os/mswindows.h | 298 ------------------ compat/select.cc | 24 ++ compat/select.h | 29 ++ compat/socket.cc | 233 ++++++++++++++ compat/socket.h | 145 +++++++++ compat/unistd.cc | 114 +++++++ compat/unistd.h | 73 +++++ compat/wserrno.cc | 44 +++ compat/wserrno.h | 22 ++ src/DiskIO/DiskDaemon/DiskdIOStrategy.cc | 3 +- src/DiskIO/DiskDaemon/diskd.cc | 15 +- src/DiskIO/DiskThreads/CommIO.cc | 5 +- src/DiskIO/DiskThreads/aiops.cc | 12 +- src/DiskIO/DiskThreads/aiops_win32.cc | 9 +- src/adaptation/icap/ServiceRep.cc | 5 +- src/auth/basic/RADIUS/basic_radius_auth.cc | 35 +- src/auth/basic/RADIUS/radius-util.cc | 10 +- .../kerberos/negotiate_kerberos_auth.cc | 6 +- .../negotiate/wrapper/negotiate_wrapper.cc | 31 +- src/base/File.cc | 13 +- src/cache_cf.cc | 7 +- src/client_side.cc | 3 +- src/clients/FtpGateway.cc | 5 +- src/comm.cc | 45 +-- src/comm/ConnOpener.cc | 3 +- src/comm/ModDevPoll.cc | 14 +- src/comm/ModSelect.cc | 5 +- src/comm/Tcp.cc | 8 +- src/comm/TcpAcceptor.cc | 11 +- src/eui/Eui48.cc | 20 +- src/fd.cc | 17 +- src/fs/rock/RockRebuild.cc | 3 +- src/fs/rock/RockSwapDir.cc | 10 +- src/fs_io.cc | 7 +- src/icmp/Icmp.cc | 3 +- src/icmp/Icmp4.cc | 27 +- src/icmp/Icmp6.cc | 27 +- src/icmp/IcmpPinger.cc | 32 +- src/icmp/IcmpSquid.cc | 3 +- src/icmp/pinger.cc | 9 +- src/ip/Intercept.cc | 43 +-- src/ip/QosConfig.cc | 11 +- src/ip/tools.cc | 16 +- src/ipc.cc | 48 ++- src/ipc/Coordinator.cc | 7 +- src/ipc/UdsOp.cc | 3 +- src/ipc/mem/Segment.cc | 6 +- src/ipc_win32.cc | 52 +-- src/log/ModUdp.cc | 4 +- src/log/file/log_file_daemon.cc | 9 +- src/main.cc | 8 +- src/mgr/Action.cc | 3 +- src/multicast.cc | 7 +- src/neighbors.cc | 4 +- .../cert_generators/file/certificate_db.cc | 5 +- src/tests/testIpAddress.cc | 7 +- src/tools.cc | 3 +- src/unlinkd.cc | 10 +- src/unlinkd_daemon.cc | 4 +- src/wccp.cc | 5 +- src/wccp2.cc | 17 +- 65 files changed, 1103 insertions(+), 640 deletions(-) create mode 100644 compat/netdb.cc create mode 100644 compat/netdb.h create mode 100644 compat/select.cc create mode 100644 compat/select.h create mode 100644 compat/socket.cc create mode 100644 compat/socket.h create mode 100644 compat/unistd.cc create mode 100644 compat/unistd.h create mode 100644 compat/wserrno.cc create mode 100644 compat/wserrno.h diff --git a/compat/Makefile.am b/compat/Makefile.am index 2581e81a3a..f7875117d0 100644 --- a/compat/Makefile.am +++ b/compat/Makefile.am @@ -45,6 +45,8 @@ libcompatsquid_la_SOURCES = \ memrchr.cc \ memrchr.h \ mswindows.cc \ + netdb.cc \ + netdb.h \ os/aix.h \ os/android.h \ os/dragonfly.h \ @@ -63,8 +65,12 @@ libcompatsquid_la_SOURCES = \ os/sunos.h \ osdetect.h \ pipe.h \ + select.cc \ + select.h \ shm.cc \ shm.h \ + socket.cc \ + socket.h \ statvfs.cc \ statvfs.h \ stdio.h \ @@ -72,9 +78,13 @@ libcompatsquid_la_SOURCES = \ strtoll.h \ tempnam.h \ types.h \ + unistd.cc \ + unistd.h \ valgrind.h \ win32_maperror.cc \ win32_maperror.h \ + wserrno.cc \ + wserrno.h \ xalloc.cc \ xalloc.h \ xis.h \ diff --git a/compat/mswindows.cc b/compat/mswindows.cc index 4d04023e65..5d24b04a96 100644 --- a/compat/mswindows.cc +++ b/compat/mswindows.cc @@ -11,6 +11,8 @@ #include "squid.h" +#include "compat/unistd.h" + // The following code section is part of an EXPERIMENTAL native Windows NT/2000 Squid port. // Compiles only on MS Visual C++ // CygWin appears not to need any of these @@ -156,10 +158,9 @@ WIN32_ftruncate(int fd, off_t size) int WIN32_truncate(const char *pathname, off_t length) { - int fd; int res = -1; - fd = open(pathname, O_RDWR); + const auto fd = xopen(pathname, O_RDWR); if (fd == -1) errno = EBADF; diff --git a/compat/netdb.cc b/compat/netdb.cc new file mode 100644 index 0000000000..9f0aa28f06 --- /dev/null +++ b/compat/netdb.cc @@ -0,0 +1,34 @@ +/* + * Copyright (C) 1996-2025 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" + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +#include "compat/netdb.h" +#include "compat/wserrno.h" + +struct hostent * +xgethostbyname(const char * const name) +{ + const auto result = gethostbyname(name); + if (!result) + SetErrnoFromWsaError(); + return result; +} + +struct servent * +xgetservbyname(const char * const name, const char * const proto) +{ + const auto result = getservbyname(name, proto); + if (!result) + SetErrnoFromWsaError(); + return result; +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ diff --git a/compat/netdb.h b/compat/netdb.h new file mode 100644 index 0000000000..fa912d5924 --- /dev/null +++ b/compat/netdb.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 1996-2025 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. + */ + +#ifndef SQUID_COMPAT_NETDB_H +#define SQUID_COMPAT_NETDB_H + +#if HAVE_NETDB_H +#include +#endif + +/// POSIX gethostbyname(3) equivalent +struct hostent * xgethostbyname(const char * name); + +/// POSIX getservbyname(3) equivalent +struct servent * xgetservbyname(const char * name, const char * proto); + +#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) + +inline struct hostent * +xgethostbyname(const char *name) +{ + return gethostbyname(name); +} + +inline struct servent * +xgetservbyname(const char *name, const char *proto) +{ + return getservbyname(name, proto); +} + +#endif /* !(_SQUID_WINDOWS_ || _SQUID_MINGW_) */ +#endif /* SQUID_COMPAT_NETDB_H */ diff --git a/compat/os/mswindows.h b/compat/os/mswindows.h index 1c584855bd..9770d9bad0 100644 --- a/compat/os/mswindows.h +++ b/compat/os/mswindows.h @@ -280,10 +280,6 @@ struct timezone { #include -#ifndef _PATH_DEVNULL -#define _PATH_DEVNULL "NUL" -#endif - #ifndef EISCONN #define EISCONN WSAEISCONN #endif @@ -392,69 +388,10 @@ SQUIDCEXTERN THREADLOCAL int ws32_result; #if defined(__cplusplus) -inline int -close(int fd) -{ - char l_so_type[sizeof(int)]; - int l_so_type_siz = sizeof(l_so_type); - SOCKET sock = _get_osfhandle(fd); - - if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0) { - int result = 0; - if (closesocket(sock) == SOCKET_ERROR) { - errno = WSAGetLastError(); - result = 1; - } - _free_osfhnd(fd); - _osfile(fd) = 0; - return result; - } else - return _close(fd); -} - #if defined(_MSC_VER) /* Microsoft C Compiler ONLY */ -#ifndef _S_IREAD -#define _S_IREAD 0x0100 #endif -#ifndef _S_IWRITE -#define _S_IWRITE 0x0080 -#endif - -inline int -open(const char *filename, int oflag, int pmode = 0) -{ - return _open(filename, oflag, pmode & (_S_IREAD | _S_IWRITE)); -} -#endif - -inline int -read(int fd, void * buf, size_t siz) -{ - char l_so_type[sizeof(int)]; - int l_so_type_siz = sizeof(l_so_type); - SOCKET sock = _get_osfhandle(fd); - - if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0) - return ::recv(sock, (char FAR *) buf, (int)siz, 0); - else - return _read(fd, buf, (unsigned int)siz); -} - -inline int -write(int fd, const void * buf, size_t siz) -{ - char l_so_type[sizeof(int)]; - int l_so_type_siz = sizeof(l_so_type); - SOCKET sock = _get_osfhandle(fd); - - if (::getsockopt(sock, SOL_SOCKET, SO_TYPE, l_so_type, &l_so_type_siz) == 0) - return ::send(sock, (char FAR *) buf, siz, 0); - else - return _write(fd, buf, siz); -} - // stdlib definitions are required before std API redefinitions. #include @@ -475,107 +412,6 @@ namespace Squid * - map the FD value used by Squid to the socket handes used by Windows. */ -inline int -accept(int s, struct sockaddr * a, socklen_t * l) -{ - SOCKET result; - if ((result = ::accept(_get_osfhandle(s), a, l)) == INVALID_SOCKET) { - if (WSAEMFILE == (errno = WSAGetLastError())) - errno = EMFILE; - return -1; - } else - return _open_osfhandle(result, 0); -} -#define accept(s,a,l) Squid::accept(s,a,reinterpret_cast(l)) - -inline int -bind(int s, const struct sockaddr * n, socklen_t l) -{ - if (::bind(_get_osfhandle(s),n,l) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define bind(s,n,l) Squid::bind(s,n,l) - -inline int -connect(int s, const struct sockaddr * n, socklen_t l) -{ - if (::connect(_get_osfhandle(s),n,l) == SOCKET_ERROR) { - if (WSAEMFILE == (errno = WSAGetLastError())) - errno = EMFILE; - return -1; - } else - return 0; -} -#define connect(s,n,l) Squid::connect(s,n,l) - -inline struct hostent * -gethostbyname(const char *n) { - HOSTENT FAR * result; - if ((result = ::gethostbyname(n)) == NULL) - errno = WSAGetLastError(); - return result; -} -#define gethostbyname(n) Squid::gethostbyname(n) - -inline SERVENT FAR * -getservbyname(const char * n, const char * p) -{ - SERVENT FAR * result; - if ((result = ::getservbyname(n, p)) == NULL) - errno = WSAGetLastError(); - return result; -} -#define getservbyname(n,p) Squid::getservbyname(n,p) - -inline HOSTENT FAR * -gethostbyaddr(const void * a, size_t l, int t) -{ - HOSTENT FAR * result; - if ((result = ::gethostbyaddr((const char*)a, l, t)) == NULL) - errno = WSAGetLastError(); - return result; -} -#define gethostbyaddr(a,l,t) Squid::gethostbyaddr(a,l,t) - -inline int -getsockname(int s, struct sockaddr * n, socklen_t * l) -{ - int i=*l; - if (::getsockname(_get_osfhandle(s), n, &i) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define getsockname(s,a,l) Squid::getsockname(s,a,reinterpret_cast(l)) - -inline int -gethostname(char * n, size_t l) -{ - if ((::gethostname(n, l)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define gethostname(n,l) Squid::gethostname(n,l) - -inline int -getsockopt(int s, int l, int o, void * v, socklen_t * n) -{ - Sleep(1); - if ((::getsockopt(_get_osfhandle(s), l, o,(char *) v, n)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define getsockopt(s,l,o,v,n) Squid::getsockopt(s,l,o,v,n) - -/* Simple ioctl() emulation */ inline int ioctl(int s, int c, void * a) { @@ -598,94 +434,6 @@ ioctlsocket(int s, long c, u_long FAR * a) } #define ioctlsocket(s,c,a) Squid::ioctlsocket(s,c,a) -inline int -listen(int s, int b) -{ - if (::listen(_get_osfhandle(s), b) == SOCKET_ERROR) { - if (WSAEMFILE == (errno = WSAGetLastError())) - errno = EMFILE; - return -1; - } else - return 0; -} -#define listen(s,b) Squid::listen(s,b) - -inline ssize_t -recv(int s, void * b, size_t l, int f) -{ - ssize_t result; - if ((result = ::recv(_get_osfhandle(s), (char *)b, l, f)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return result; -} -#define recv(s,b,l,f) Squid::recv(s,b,l,f) - -inline ssize_t -recvfrom(int s, void * b, size_t l, int f, struct sockaddr * fr, socklen_t * fl) -{ - ssize_t result; - int ifl=*fl; - if ((result = ::recvfrom(_get_osfhandle(s), (char *)b, l, f, fr, &ifl)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return result; -} -#define recvfrom(s,b,l,f,r,n) Squid::recvfrom(s,b,l,f,r,reinterpret_cast(n)) - -inline int -select(int n, fd_set * r, fd_set * w, fd_set * e, struct timeval * t) -{ - int result; - if ((result = ::select(n,r,w,e,t)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return result; -} -#define select(n,r,w,e,t) Squid::select(n,r,w,e,t) - -inline ssize_t -send(int s, const char * b, size_t l, int f) -{ - ssize_t result; - if ((result = ::send(_get_osfhandle(s), b, l, f)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return result; -} -#define send(s,b,l,f) Squid::send(s,reinterpret_cast(b),l,f) - -inline ssize_t -sendto(int s, const void * b, size_t l, int f, const struct sockaddr * t, socklen_t tl) -{ - ssize_t result; - if ((result = ::sendto(_get_osfhandle(s), (char *)b, l, f, t, tl)) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return result; -} -#define sendto(a,b,l,f,t,n) Squid::sendto(a,b,l,f,t,n) - -inline int -setsockopt(SOCKET s, int l, int o, const void * v, socklen_t n) -{ - SOCKET socket; - - socket = ((s == INVALID_SOCKET) ? s : (SOCKET)_get_osfhandle((int)s)); - - if (::setsockopt(socket, l, o, (const char *)v, n) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define setsockopt(s,l,o,v,n) Squid::setsockopt(s,l,o,v,n) - inline int shutdown(int s, int h) { @@ -697,30 +445,6 @@ shutdown(int s, int h) } #define shutdown(s,h) Squid::shutdown(s,h) -inline int -socket(int f, int t, int p) -{ - SOCKET result; - if ((result = ::socket(f, t, p)) == INVALID_SOCKET) { - if (WSAEMFILE == (errno = WSAGetLastError())) - errno = EMFILE; - return -1; - } else - return _open_osfhandle(result, 0); -} -#define socket(f,t,p) Squid::socket(f,t,p) - -inline int -WSAAsyncSelect(int s, HWND h, unsigned int w, long e) -{ - if (::WSAAsyncSelect(_get_osfhandle(s), h, w, e) == SOCKET_ERROR) { - errno = WSAGetLastError(); - return -1; - } else - return 0; -} -#define WSAAsyncSelect(s,h,w,e) Squid::WSAAsyncSelect(s,h,w,e) - #undef WSADuplicateSocket inline int WSADuplicateSocket(int s, DWORD n, LPWSAPROTOCOL_INFO l) @@ -758,28 +482,6 @@ WSASocket(int a, int t, int p, LPWSAPROTOCOL_INFO i, GROUP g, DWORD f) } /* namespace Squid */ #else /* #ifdef __cplusplus */ -#define connect(s,n,l) \ - (SOCKET_ERROR == connect(_get_osfhandle(s),n,l) ? \ - (WSAEMFILE == (errno = WSAGetLastError()) ? errno = EMFILE : -1, -1) : 0) -#define gethostbyname(n) \ - (NULL == ((HOSTENT FAR*)(ws32_result = (int)gethostbyname(n))) ? \ - (errno = WSAGetLastError()), (HOSTENT FAR*)NULL : (HOSTENT FAR*)ws32_result) -#define gethostname(n,l) \ - (SOCKET_ERROR == gethostname(n,l) ? \ - (errno = WSAGetLastError()), -1 : 0) -#define recv(s,b,l,f) \ - (SOCKET_ERROR == (ws32_result = recv(_get_osfhandle(s),b,l,f)) ? \ - (errno = WSAGetLastError()), -1 : ws32_result) -#define sendto(s,b,l,f,t,tl) \ - (SOCKET_ERROR == (ws32_result = sendto(_get_osfhandle(s),b,l,f,t,tl)) ? \ - (errno = WSAGetLastError()), -1 : ws32_result) -#define select(n,r,w,e,t) \ - (SOCKET_ERROR == (ws32_result = select(n,r,w,e,t)) ? \ - (errno = WSAGetLastError()), -1 : ws32_result) -#define socket(f,t,p) \ - (INVALID_SOCKET == ((SOCKET)(ws32_result = (int)socket(f,t,p))) ? \ - ((WSAEMFILE == (errno = WSAGetLastError()) ? errno = EMFILE : -1), -1) : \ - (SOCKET)_open_osfhandle(ws32_result,0)) #define write _write /* Needed in util.c */ #define open _open /* Needed in win32lib.c */ #endif /* #ifdef __cplusplus */ diff --git a/compat/select.cc b/compat/select.cc new file mode 100644 index 0000000000..f2db6dbc13 --- /dev/null +++ b/compat/select.cc @@ -0,0 +1,24 @@ +/* + * Copyright (C) 1996-2025 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 "compat/select.h" +#include "compat/wserrno.h" + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +int +xselect(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout) +{ + const auto result = select(nfds, readfds, writefds, exceptfds, timeout); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ diff --git a/compat/select.h b/compat/select.h new file mode 100644 index 0000000000..a6ef510521 --- /dev/null +++ b/compat/select.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 1996-2025 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. + */ + +#ifndef SQUID_COMPAT_SELECT_H +#define SQUID_COMPAT_SELECT_H + +#if HAVE_SYS_SELECT_H +#include +#endif + +/// POSIX select(2) equivalent +int xselect(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout); + +#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) + +inline int +xselect(int nfds, fd_set * readfds, fd_set * writefds, fd_set * exceptfds, struct timeval * timeout) +{ + return select(nfds, readfds, writefds, exceptfds, timeout); +} + +#endif /* !(_SQUID_WINDOWS_ || _SQUID_MINGW_) */ + +#endif /* SQUID_COMPAT_SELECT_H */ diff --git a/compat/socket.cc b/compat/socket.cc new file mode 100644 index 0000000000..16bca103c4 --- /dev/null +++ b/compat/socket.cc @@ -0,0 +1,233 @@ +/* + * Copyright (C) 1996-2025 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 "compat/socket.h" +#include "compat/wserrno.h" + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ +#include + +int +xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + int al = 0; + int *alp = nullptr; + if (saLength) { + assert(*saLength <= INT_MAX); + al = static_cast(*saLength); + alp = &al; + } + const auto result = accept(handle, sa, alp); + if (result == INVALID_SOCKET) { + SetErrnoFromWsaError(); + return SOCKET_ERROR; + } + const auto rv = _open_osfhandle(result, 0); + if (rv == -1) + errno = EBADF; + if (saLength) + *saLength = static_cast(al); + return rv; +} + +int +xbind(int socketFd, const struct sockaddr *sa, socklen_t saLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(saLength <= INT_MAX); + const auto result = bind(handle, sa, static_cast(saLength)); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +int +xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(saLength <= INT_MAX); + const auto result = connect(handle, sa, static_cast(saLength)); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +int +xgetsockname(int socketFd, struct sockaddr * sa, socklen_t * saLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + int al = 0; + int *alp = nullptr; + if (saLength) { + assert(*saLength <= INT_MAX); + al = static_cast(*saLength); + alp = &al; + } + const auto result = getsockname(handle, sa, alp); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + if (saLength) + *saLength = static_cast(al); + return result; +} + +int +xgetsockopt(int socketFd, int level, int optionName, void * optionValue, socklen_t * optionLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + int ol = 0; + int *olp = nullptr; + if (optionLength) { + assert(*optionLength <= INT_MAX); + ol = static_cast(*optionLength); + olp = &ol; + } + const auto result = getsockopt(handle, level, optionName, static_cast(optionValue), olp); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + if (optionLength) + *optionLength = static_cast(ol); + return result; +} + +int +xlisten(int socketFd, int backlog) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + const auto result = listen(handle, backlog); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +ssize_t +xrecv(int socketFd, void * buf, size_t bufLength, int flags) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(bufLength <= INT_MAX); + const auto result = recv(handle, static_cast(buf), static_cast(bufLength), flags); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +ssize_t +xrecvfrom(int socketFd, void * buf, size_t bufLength, int flags, struct sockaddr * from, socklen_t * fromLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(bufLength <= INT_MAX); + int fl = 0; + int *flp = nullptr; + if (fromLength) { + assert(*fromLength <= INT_MAX); + fl = static_cast(*fromLength); + flp = &fl; + } + const auto result = recvfrom(handle, static_cast(buf), static_cast(bufLength), flags, from, flp); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + if (fromLength) + *fromLength = static_cast(fl); + return result; +} + +ssize_t +xsend(int socketFd, const void * buf, size_t bufLength, int flags) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(bufLength <= INT_MAX); + const auto result = send(handle, static_cast(buf), static_cast(bufLength), flags); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +ssize_t +xsendto(int socketFd, const void * buf, size_t bufLength, int flags, const struct sockaddr * to, socklen_t toLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(bufLength <= INT_MAX); + assert(toLength <= INT_MAX); + const auto result = sendto(handle, static_cast(buf), static_cast(bufLength), flags, to, static_cast(toLength)); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +int +xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength) +{ + const auto handle = _get_osfhandle(socketFd); + if (!isValidSocketHandle(handle)) { + // errno is already set by _get_osfhandle() + return SOCKET_ERROR; + } + assert(option <= INT_MAX); + const auto result = setsockopt(handle, level, option, static_cast(value), static_cast(valueLength)); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +int +xsocket(int domain, int type, int protocol) +{ + const auto result = socket(domain, type, protocol); + if (result == INVALID_SOCKET) { + SetErrnoFromWsaError(); + return SOCKET_ERROR; + } + const auto rv = _open_osfhandle(result, 0); + if (rv == -1) + errno = EBADF; + return rv; +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ diff --git a/compat/socket.h b/compat/socket.h new file mode 100644 index 0000000000..0dbc3773a9 --- /dev/null +++ b/compat/socket.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 1996-2025 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. + */ + +#ifndef SQUID_COMPAT_SOCKET_H +#define SQUID_COMPAT_SOCKET_H + +#if HAVE_SYS_SOCKET_H +#include +#endif + +/// POSIX accept(2) equivalent +int xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength); + +/// POSIX bind(2) equivalent +int xbind(int socketFd, const struct sockaddr *sa, socklen_t saLength); + +/// POSIX connect(2) equivalent +int xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength); + +/// POSIX getsockopt(2) equivalent +int xgetsockopt(int socketFd, int level, int optionName, void * optionValue, socklen_t * optionLength); + +/// POSIX getsockname(2) equivalent +int xgetsockname(int socketFd, struct sockaddr * sa, socklen_t * saLength); + +/// POSIX listen(2) equivalent +int xlisten(int socketFd, int backlog); + +/// POSIX recv(2) equivalent +ssize_t xrecv(int socketFd, void * buf, size_t bufLength, int flags); + +/// POSIX recvfrom(2) equivalent +ssize_t xrecvfrom(int socketFd, void * buf, size_t bufLength, int flags, struct sockaddr * from, socklen_t * fromLength); + +/// POSIX send(2) equivalent +ssize_t xsend(int socketFd, const void * buf, size_t bufLength, int flags); + +/// POSIX sendto(2) equivalent +ssize_t xsendto(int socketFd, const void * buf, size_t bufLength, int flags, const struct sockaddr * to, socklen_t toLength); + +/// POSIX setsockopt(2) equivalent +int xsetsockopt(int socketFd, int level, int option, const void * value, socklen_t valueLength); + +/// POSIX socket(2) equivalent +int xsocket(int domain, int type, int protocol); + +// Solaris and possibly others lack MSG_NOSIGNAL optimization +// TODO: move this into compat/? Use a dedicated compat file to avoid dragging +// sys/socket.h into the rest of Squid?? +#ifndef MSG_NOSIGNAL +#define MSG_NOSIGNAL 0 +#endif + +#if !(_SQUID_WINDOWS_ || _SQUID_MINGW_) + +inline int +xaccept(int socketFd, struct sockaddr *sa, socklen_t *saLength) +{ + return accept(socketFd, sa, saLength); +} + +inline int +xbind(int socketFd, const struct sockaddr *sa, socklen_t saLength) +{ + return bind(socketFd, sa, saLength); +} + +inline int +xconnect(int socketFd, const struct sockaddr *sa, socklen_t saLength) +{ + return connect(socketFd, sa, saLength); +} + +inline int +xgetsockname(int socketFd, struct sockaddr * sa, socklen_t * saLength) +{ + return getsockname(socketFd, sa, saLength); +} + +inline int +xlisten(int socketFd, int backlog) +{ + return listen(socketFd, backlog); +} + +inline int +xgetsockopt(int socketFd, int level, int optionName, void * optionValue, socklen_t * optionLength) +{ + return getsockopt(socketFd, level, optionName, optionValue, optionLength); +} + +inline ssize_t +xrecv(int socketFd, void * buf, size_t bufLength, int flags) +{ + return recv(socketFd, buf, bufLength, flags); +} + +inline ssize_t +xrecvfrom(int socketFd, void * buf, size_t bufLength, int flags, struct sockaddr * from, socklen_t * fromLength) +{ + return recvfrom(socketFd, buf, bufLength, flags, from, fromLength); +} + +inline ssize_t +xsend(int socketFd, const void * buf, size_t bufLength, int flags) +{ + return send(socketFd, buf, bufLength, flags); +} + +inline ssize_t +xsendto(int socketFd, const void * buf, size_t bufLength, int flags, const struct sockaddr * to, socklen_t l) +{ + return sendto(socketFd, buf, bufLength, flags, to, l); +} + +inline int +xsetsockopt(int socketFd, int level, int option, const void *value, socklen_t valueLength) +{ + return setsockopt(socketFd, level, option, value, valueLength); +} + +inline int +xsocket(int domain, int type, int protocol) +{ + return socket(domain, type, protocol); +} + +#else + +static_assert(SOCKET_ERROR == -1); + +inline bool +isValidSocketHandle(intptr_t handle) +{ + return handle != intptr_t(INVALID_HANDLE_VALUE); +} + +#endif /* !(_SQUID_WINDOWS_ || _SQUID_MINGW_) */ + +#endif /* SQUID_COMPAT_SOCKET_H */ diff --git a/compat/unistd.cc b/compat/unistd.cc new file mode 100644 index 0000000000..f884fa0af5 --- /dev/null +++ b/compat/unistd.cc @@ -0,0 +1,114 @@ +/* + * Copyright (C) 1996-2025 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" + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +#include "compat/socket.h" +#include "compat/unistd.h" +#include "compat/wserrno.h" + +// 2025 MinGW and pre-2022 MSVC do not define these +#ifndef _S_IREAD +#define _S_IREAD 0x0100 +#endif + +#ifndef _S_IWRITE +#define _S_IWRITE 0x0080 +#endif + +/// returns true if handle is a valid socket. Preserves errno. +static bool +isSocket(intptr_t handle) +{ + if (!isValidSocketHandle(handle)) { + // isValidSocketHandle does not touch errno + return false; + } + + int value = 0; + int valueSize = sizeof(value); + const auto savedErrno = errno; + // use Windows API directly + const auto result = (getsockopt(handle, SOL_SOCKET, SO_TYPE, reinterpret_cast(&value), &valueSize) == 0); + errno = savedErrno; + return result; +} + +int +xclose(int fd) +{ + const auto sock = _get_osfhandle(fd); + if (sock == intptr_t(INVALID_HANDLE_VALUE)) { + // errno is already set by _get_osfhandle() + return -1; + } + + if (isSocket(sock)) { + const auto result = closesocket(sock); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; + } else { + const auto result = _close(fd); + if (result) + SetErrnoFromWsaError(); + return result; + } +} + +int +xgethostname(char *name, size_t nameLength) +{ + assert(nameLength <= INT_MAX); + const auto result = gethostname(name, static_cast(nameLength)); + if (result == SOCKET_ERROR) + SetErrnoFromWsaError(); + return result; +} + +int +xopen(const char *filename, int oflag, int pmode) +{ + return _open(filename, oflag, pmode & (_S_IREAD | _S_IWRITE)); +} + +int +xread(int fd, void * buf, size_t bufSize) +{ + const auto sock = _get_osfhandle(fd); + if (sock == intptr_t(INVALID_HANDLE_VALUE)) { + // errno is already set by _get_osfhandle() + return -1; + } + + assert(bufSize <= UINT_MAX); + if (isSocket(sock)) + return xrecv(sock, buf, bufSize, 0); + else + return _read(fd, buf, static_cast(bufSize)); +} + +int +xwrite(int fd, const void * buf, size_t bufSize) +{ + const auto sock = _get_osfhandle(fd); + if (sock == intptr_t(INVALID_HANDLE_VALUE)) { + // errno is already set by _get_osfhandle() + return -1; + } + + assert(bufSize <= UINT_MAX); + if (isSocket(sock)) + return xsend(sock, buf, bufSize, 0); + else + return _write(fd, buf, static_cast(bufSize)); +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ diff --git a/compat/unistd.h b/compat/unistd.h new file mode 100644 index 0000000000..5e39da4247 --- /dev/null +++ b/compat/unistd.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 1996-2025 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. + */ + +#ifndef SQUID_COMPAT_UNISTD_H +#define SQUID_COMPAT_UNISTD_H + +#if HAVE_PATHS_H +#include +#endif +#if HAVE_UNISTD_H +#include +#endif + +/// POSIX close(2) equivalent +int xclose(int fd); + +/// POSIX gethostname(2) equivalent +int xgethostname(char *name, size_t nameLength); + +/// POSIX open(2) equivalent +int xopen(const char *filename, int oflag, int pmode = 0); + +/// POSIX read(2) equivalent +int xread(int fd, void * buf, size_t bufSize); + +/// POSIX write(2) equivalent +int xwrite(int fd, const void * buf, size_t bufSize); + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +#if !defined(_PATH_DEVNULL) +#define _PATH_DEVNULL "NUL" +#endif + +#else /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ + +inline int +xclose(int fd) +{ + return close(fd); +} + +inline int +xgethostname(char *name, size_t nameLength) +{ + return gethostname(name, nameLength); +} + +inline int +xopen(const char *filename, int oflag, int pmode) +{ + return open(filename, oflag, pmode); +} + +inline int +xread(int fd, void * buf, size_t bufSize) +{ + return read(fd, buf, bufSize); +} + +inline int +xwrite(int fd, const void * buf, size_t bufSize) +{ + return write(fd, buf, bufSize); +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ +#endif /* SQUID_COMPAT_UNISTD_H */ diff --git a/compat/wserrno.cc b/compat/wserrno.cc new file mode 100644 index 0000000000..47222cffd0 --- /dev/null +++ b/compat/wserrno.cc @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1996-2025 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 "compat/wserrno.h" + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +#include + +void +SetErrnoFromWsaError() +{ + // POSIX codes which socket API users may care about + static const auto *CodeMap = new std::unordered_map { + { WSAECONNABORTED, ECONNABORTED }, + { WSAEINPROGRESS, EINPROGRESS }, + { WSAEAFNOSUPPORT, EAFNOSUPPORT }, + { WSAEINVAL, EINVAL }, + { WSAEISCONN, EISCONN }, + { WSAEWOULDBLOCK, EWOULDBLOCK }, + // no Windows error code maps to EAGAIN + { WSAEALREADY, EALREADY }, + { WSAEINTR, EINTR }, + // no Windows error code maps to ERESTART + { WSAEMFILE, EMFILE }, + // no Windows error code maps to ENFILE + { WSAECONNRESET, ECONNRESET } + }; + + const auto wsa = WSAGetLastError(); + const auto itr = CodeMap->find(wsa); + if (itr != CodeMap->cend()) + errno = itr->second; + else + errno = wsa; +} + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ diff --git a/compat/wserrno.h b/compat/wserrno.h new file mode 100644 index 0000000000..b473586cfc --- /dev/null +++ b/compat/wserrno.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 1996-2025 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. + */ + +#ifndef SQUID_COMPAT_WSERRNO_H +#define SQUID_COMPAT_WSERRNO_H + +#if _SQUID_WINDOWS_ || _SQUID_MINGW_ + +/** + * Squid socket code is written to handle POSIX errno codes. + * Set errno to the relevant POSIX or WSA code. + */ +void SetErrnoFromWsaError(); + +#endif /* _SQUID_WINDOWS_ || _SQUID_MINGW_ */ + +#endif /* SQUID_COMPAT_WSERRNO_H */ diff --git a/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc b/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc index 4eef0bf3df..dcc81107f5 100644 --- a/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc +++ b/src/DiskIO/DiskDaemon/DiskdIOStrategy.cc @@ -11,6 +11,7 @@ #include "squid.h" #include "comm.h" #include "comm/Loops.h" +#include "compat/select.h" #include "ConfigOption.h" #include "diomsg.h" #include "DiskdFile.h" @@ -409,7 +410,7 @@ DiskdIOStrategy::SEND(diomsg *M, int mtype, int id, size_t size, off_t offset, s struct timeval delay = {0, 1}; while (away > magic2) { - select(0, nullptr, nullptr, nullptr, &delay); + xselect(0, nullptr, nullptr, nullptr, &delay); Store::Root().callback(); if (delay.tv_usec < 1000000) diff --git a/src/DiskIO/DiskDaemon/diskd.cc b/src/DiskIO/DiskDaemon/diskd.cc index cd2dee0c91..e63bcba802 100644 --- a/src/DiskIO/DiskDaemon/diskd.cc +++ b/src/DiskIO/DiskDaemon/diskd.cc @@ -9,6 +9,8 @@ /* DEBUG: section -- External DISKD process implementation. */ #include "squid.h" +#include "compat/socket.h" +#include "compat/unistd.h" #include "DiskIO/DiskDaemon/diomsg.h" #include "hash.h" @@ -53,12 +55,11 @@ static int DebugLevel = 0; static int do_open(diomsg * r, int, const char *buf) { - int fd; file_state *fs; /* * note r->offset holds open() flags */ - fd = open(buf, r->offset, 0600); + const auto fd = xopen(buf, r->offset, 0600); if (fd < 0) { DEBUG(1) { @@ -111,13 +112,12 @@ do_close(diomsg * r, int) fs); } xfree(fs); - return close(fd); + return xclose(fd); } static int do_read(diomsg * r, int, char *buf) { - int x; int readlen = r->size; file_state *fs; fs = (file_state *) hash_lookup(hash, &r->id); @@ -145,7 +145,7 @@ do_read(diomsg * r, int, char *buf) } } - x = read(fs->fd, buf, readlen); + const auto x = xread(fs->fd, buf, readlen); DEBUG(2) { fprintf(stderr, "%d READ %d,%d,%" PRId64 " ret %d\n", (int) mypid, fs->fd, readlen, (int64_t)r->offset, x); @@ -168,7 +168,6 @@ static int do_write(diomsg * r, int, const char *buf) { int wrtlen = r->size; - int x; file_state *fs; fs = (file_state *) hash_lookup(hash, &r->id); @@ -195,7 +194,7 @@ do_write(diomsg * r, int, const char *buf) fprintf(stderr, "%d WRITE %d,%d,%" PRId64 "\n", (int) mypid, fs->fd, wrtlen, (int64_t)r->offset); } - x = write(fs->fd, buf, wrtlen); + const auto x = xwrite(fs->fd, buf, wrtlen); if (x < 0) { DEBUG(1) { @@ -370,7 +369,7 @@ main(int argc, char *argv[]) if (rlen < 0) { if (EINTR == errno) { - if (read(0, rbuf, 512) <= 0) { + if (xread(0, rbuf, 512) <= 0) { if (EWOULDBLOCK == errno) (void) 0; else if (EAGAIN == errno) diff --git a/src/DiskIO/DiskThreads/CommIO.cc b/src/DiskIO/DiskThreads/CommIO.cc index b3a5d6746b..c0558ab37b 100644 --- a/src/DiskIO/DiskThreads/CommIO.cc +++ b/src/DiskIO/DiskThreads/CommIO.cc @@ -11,6 +11,7 @@ #include "squid.h" #include "comm/Loops.h" #include "compat/pipe.h" +#include "compat/unistd.h" #include "DiskIO/DiskThreads/CommIO.h" #include "fd.h" #include "globals.h" @@ -40,8 +41,8 @@ CommIO::NotifyIOClose() { /* Close done pipe signal */ FlushPipe(); - close(DoneFD); - close(DoneReadFD); + xclose(DoneFD); + xclose(DoneReadFD); fd_close(DoneFD); fd_close(DoneReadFD); Initialized = false; diff --git a/src/DiskIO/DiskThreads/aiops.cc b/src/DiskIO/DiskThreads/aiops.cc index 5be893a77a..b50be32f6d 100644 --- a/src/DiskIO/DiskThreads/aiops.cc +++ b/src/DiskIO/DiskThreads/aiops.cc @@ -13,6 +13,8 @@ #endif #include "squid.h" +#include "compat/socket.h" +#include "compat/unistd.h" #include "DiskIO/DiskThreads/CommIO.h" #include "DiskThreads.h" #include "SquidConfig.h" @@ -578,7 +580,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp) case _AIO_OP_OPEN: if (cancelled && requestp->ret >= 0) /* The open() was cancelled but completed */ - close(requestp->ret); + xclose(requestp->ret); squidaio_xstrfree(requestp->path); @@ -587,7 +589,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp) case _AIO_OP_CLOSE: if (cancelled && requestp->ret < 0) /* The close() was cancelled and never got executed */ - close(requestp->fd); + xclose(requestp->fd); break; @@ -701,7 +703,7 @@ static void squidaio_do_read(squidaio_request_t * requestp) { if (lseek(requestp->fd, requestp->offset, requestp->whence) >= 0) - requestp->ret = read(requestp->fd, requestp->bufferp, requestp->buflen); + requestp->ret = xread(requestp->fd, requestp->bufferp, requestp->buflen); else requestp->ret = -1; requestp->err = errno; @@ -740,7 +742,7 @@ squidaio_write(int fd, char *bufp, size_t bufs, off_t offset, int whence, squida static void squidaio_do_write(squidaio_request_t * requestp) { - requestp->ret = write(requestp->fd, requestp->bufferp, requestp->buflen); + requestp->ret = xwrite(requestp->fd, requestp->bufferp, requestp->buflen); requestp->err = errno; } @@ -769,7 +771,7 @@ squidaio_close(int fd, squidaio_result_t * resultp) static void squidaio_do_close(squidaio_request_t * requestp) { - requestp->ret = close(requestp->fd); + requestp->ret = xclose(requestp->fd); requestp->err = errno; } diff --git a/src/DiskIO/DiskThreads/aiops_win32.cc b/src/DiskIO/DiskThreads/aiops_win32.cc index 7c3a207097..8ce649574d 100644 --- a/src/DiskIO/DiskThreads/aiops_win32.cc +++ b/src/DiskIO/DiskThreads/aiops_win32.cc @@ -9,6 +9,7 @@ /* DEBUG: section 43 Windows AIOPS */ #include "squid.h" +#include "compat/unistd.h" #include "compat/win32_maperror.h" #include "DiskIO/DiskThreads/CommIO.h" #include "DiskThreads.h" @@ -653,7 +654,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp) case _AIO_OP_OPEN: if (cancelled && requestp->ret >= 0) /* The open() was cancelled but completed */ - close(requestp->ret); + xclose(requestp->ret); squidaio_xstrfree(requestp->path); @@ -662,7 +663,7 @@ squidaio_cleanup_request(squidaio_request_t * requestp) case _AIO_OP_CLOSE: if (cancelled && requestp->ret < 0) /* The close() was cancelled and never got executed */ - close(requestp->fd); + xclose(requestp->fd); break; @@ -853,9 +854,9 @@ squidaio_close(int fd, squidaio_result_t * resultp) static void squidaio_do_close(squidaio_request_t * requestp) { - if ((requestp->ret = close(requestp->fd)) < 0) { + if ((requestp->ret = xclose(requestp->fd)) < 0) { debugs(43, DBG_CRITICAL, "squidaio_do_close: FD " << requestp->fd << ", errno " << errno); - close(requestp->fd); + xclose(requestp->fd); } requestp->err = errno; diff --git a/src/adaptation/icap/ServiceRep.cc b/src/adaptation/icap/ServiceRep.cc index a6e2bd0359..2c63aa9254 100644 --- a/src/adaptation/icap/ServiceRep.cc +++ b/src/adaptation/icap/ServiceRep.cc @@ -17,6 +17,7 @@ #include "adaptation/icap/ServiceRep.h" #include "base/TextException.h" #include "comm/Connection.h" +#include "compat/netdb.h" #include "ConfigParser.h" #include "debug/Stream.h" #include "fde.h" @@ -66,9 +67,9 @@ Adaptation::Icap::ServiceRep::finalize() if (!have_port) { struct servent *serv; if (cfg().protocol.caseCmp("icaps") == 0) - serv = getservbyname("icaps", "tcp"); + serv = xgetservbyname("icaps", "tcp"); else - serv = getservbyname("icap", "tcp"); + serv = xgetservbyname("icap", "tcp"); if (serv) { writeableCfg().port = htons(serv->s_port); diff --git a/src/auth/basic/RADIUS/basic_radius_auth.cc b/src/auth/basic/RADIUS/basic_radius_auth.cc index 72daa072f5..340faee37b 100644 --- a/src/auth/basic/RADIUS/basic_radius_auth.cc +++ b/src/auth/basic/RADIUS/basic_radius_auth.cc @@ -57,6 +57,10 @@ #include "auth/basic/RADIUS/radius-util.h" #include "auth/basic/RADIUS/radius.h" #include "base/Random.h" +#include "compat/netdb.h" +#include "compat/select.h" +#include "compat/socket.h" +#include "compat/unistd.h" #include "helper/protocol_defines.h" #include "md5.h" @@ -64,27 +68,15 @@ #include #include #include -#if HAVE_SYS_SOCKET_H -#include -#endif #if HAVE_NETINET_IN_H #include #endif -#if HAVE_UNISTD_H -#include -#endif #if HAVE_FCNTL_H #include #endif #if _SQUID_WINDOWS_ #include #endif -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_NETDB_H -#include -#endif #if HAVE_PWD_H #include #endif @@ -417,7 +409,7 @@ authenticate(int socket_fd, const char *username, const char *passwd) * Send the request we've built. */ gettimeofday(&sent, nullptr); - if (send(socket_fd, (char *) auth, total_length, 0) < 0) { + if (xsend(socket_fd, 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 ? @@ -437,11 +429,11 @@ authenticate(int socket_fd, const char *username, const char *passwd) } FD_ZERO(&readfds); FD_SET(socket_fd, &readfds); - if (select(socket_fd + 1, &readfds, nullptr, nullptr, &tv) == 0) /* Select timeout */ + if (xselect(socket_fd + 1, &readfds, nullptr, nullptr, &tv) == 0) /* Select timeout */ break; salen = sizeof(saremote); - len = recvfrom(socket_fd, recv_buffer, sizeof(i_recv_buffer), - 0, (struct sockaddr *) &saremote, &salen); + len = xrecvfrom(socket_fd, recv_buffer, sizeof(i_recv_buffer), + 0, (struct sockaddr *) &saremote, &salen); if (len < 0) continue; @@ -468,7 +460,6 @@ main(int argc, char **argv) { struct sockaddr_in salocal; struct sockaddr_in saremote; - struct servent *svp; unsigned short svc_port; char username[MAXPWNAM]; char passwd[MAXPASS]; @@ -536,7 +527,7 @@ main(int argc, char **argv) /* * Open a connection to the server. */ - svp = getservbyname(svc_name, "udp"); + const auto svp = xgetservbyname(svc_name, "udp"); if (svp != nullptr) svc_port = ntohs((unsigned short) svp->s_port); else @@ -549,7 +540,7 @@ main(int argc, char **argv) fprintf(stderr, "FATAL: %s: Couldn't find host %s\n", argv[0], server); exit(EXIT_FAILURE); } - sockfd = socket(AF_INET, SOCK_DGRAM, 0); + sockfd = xsocket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); exit(EXIT_FAILURE); @@ -559,12 +550,12 @@ main(int argc, char **argv) saremote.sin_addr.s_addr = htonl(auth_ipaddr); saremote.sin_port = htons(svc_port); - if (connect(sockfd, (struct sockaddr *) &saremote, sizeof(saremote)) < 0) { + if (xconnect(sockfd, (struct sockaddr *) &saremote, sizeof(saremote)) < 0) { perror("connect"); exit(EXIT_FAILURE); } salen = sizeof(salocal); - if (getsockname(sockfd, (struct sockaddr *) &salocal, &salen) < 0) { + if (xgetsockname(sockfd, (struct sockaddr *) &salocal, &salen) < 0) { perror("getsockname"); exit(EXIT_FAILURE); } @@ -612,7 +603,7 @@ main(int argc, char **argv) authenticate(sockfd, username, passwd); } - close(sockfd); + xclose(sockfd); return EXIT_SUCCESS; } diff --git a/src/auth/basic/RADIUS/radius-util.cc b/src/auth/basic/RADIUS/radius-util.cc index 52bac5b3ee..67ac67540f 100644 --- a/src/auth/basic/RADIUS/radius-util.cc +++ b/src/auth/basic/RADIUS/radius-util.cc @@ -46,20 +46,16 @@ char util_sccsid[] = #include "squid.h" #include "auth/basic/RADIUS/radius-util.h" +#include "compat/netdb.h" +#include "compat/socket.h" #include "md5.h" #include #include #include -#if HAVE_SYS_SOCKET_H -#include -#endif #if HAVE_NETINET_IN_H #include #endif -#if HAVE_NETDB_H -#include -#endif #if HAVE_PWD_H #include #endif @@ -146,7 +142,7 @@ uint32_t get_ipaddr(char *host) if (good_ipaddr(host) == 0) { return(ipstr2long(host)); - } else if ((hp = gethostbyname(host)) == (struct hostent *)nullptr) { + } else if (!(hp = xgethostbyname(host))) { return((uint32_t)0); } return(ntohl(*(uint32_t *)hp->h_addr)); diff --git a/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc b/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc index 1ac5a502a7..262f349809 100644 --- a/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc +++ b/src/auth/negotiate/kerberos/negotiate_kerberos_auth.cc @@ -40,14 +40,12 @@ #if HAVE_GSSAPI +#include "compat/unistd.h" #include "negotiate_kerberos.h" #if HAVE_SYS_STAT_H #include "sys/stat.h" #endif -#if HAVE_UNISTD_H -#include "unistd.h" -#endif #if HAVE_KRB5_MEMORY_KEYTAB typedef struct _krb5_kt_list { @@ -97,7 +95,7 @@ gethost_name(void) struct addrinfo *hres = nullptr, *hres_list; int rc; - rc = gethostname(hostname, sizeof(hostname)-1); + rc = xgethostname(hostname, sizeof(hostname)-1); if (rc) { debug((char *) "%s| %s: ERROR: resolving hostname '%s' failed\n", LogTime(), PROGRAM, hostname); fprintf(stderr, "%s| %s: ERROR: resolving hostname '%s' failed\n", diff --git a/src/auth/negotiate/wrapper/negotiate_wrapper.cc b/src/auth/negotiate/wrapper/negotiate_wrapper.cc index 3525aab9f8..2ac4e58201 100644 --- a/src/auth/negotiate/wrapper/negotiate_wrapper.cc +++ b/src/auth/negotiate/wrapper/negotiate_wrapper.cc @@ -33,17 +33,12 @@ #include "squid.h" #include "base64.h" #include "compat/pipe.h" +#include "compat/unistd.h" #include #include #include #include -#if HAVE_NETDB_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif #if !defined(HAVE_DECL_XMALLOC) || !HAVE_DECL_XMALLOC #define xmalloc malloc @@ -376,13 +371,13 @@ main(int argc, char *const argv[]) if ( fpid == 0 ) { /* First Child for Kerberos helper */ - close(pkin[1]); + xclose(pkin[1]); dup2(pkin[0],STDIN_FILENO); - close(pkin[0]); + xclose(pkin[0]); - close(pkout[0]); + xclose(pkout[0]); dup2(pkout[1],STDOUT_FILENO); - close(pkout[1]); + xclose(pkout[1]); setbuf(stdin, nullptr); setbuf(stdout, nullptr); @@ -392,8 +387,8 @@ main(int argc, char *const argv[]) exit(EXIT_FAILURE); } - close(pkin[0]); - close(pkout[1]); + xclose(pkin[0]); + xclose(pkout[1]); if (pipe(pnin) < 0) { fprintf(stderr, "%s| %s: Could not assign streams for pnin\n", LogTime(), PROGRAM); @@ -412,13 +407,13 @@ main(int argc, char *const argv[]) if ( fpid == 0 ) { /* Second Child for NTLM helper */ - close(pnin[1]); + xclose(pnin[1]); dup2(pnin[0],STDIN_FILENO); - close(pnin[0]); + xclose(pnin[0]); - close(pnout[0]); + xclose(pnout[0]); dup2(pnout[1],STDOUT_FILENO); - close(pnout[1]); + xclose(pnout[1]); setbuf(stdin, nullptr); setbuf(stdout, nullptr); @@ -428,8 +423,8 @@ main(int argc, char *const argv[]) exit(EXIT_FAILURE); } - close(pnin[0]); - close(pnout[1]); + xclose(pnin[0]); + xclose(pnout[1]); FILE *FDKIN=fdopen(pkin[1],"w"); FILE *FDKOUT=fdopen(pkout[0],"r"); diff --git a/src/base/File.cc b/src/base/File.cc index b2f638e978..dc518be435 100644 --- a/src/base/File.cc +++ b/src/base/File.cc @@ -8,6 +8,8 @@ #include "squid.h" #include "base/File.h" +#include "compat/socket.h" +#include "compat/unistd.h" #include "debug/Stream.h" #include "sbuf/Stream.h" #include "tools.h" @@ -22,9 +24,6 @@ #if HAVE_SYS_STAT_H #include #endif -#if HAVE_UNISTD_H -#include -#endif /* FileOpeningConfig */ @@ -182,7 +181,7 @@ File::open(const FileOpeningConfig &cfg) enter_suid(); if (cfg.creationMask) oldCreationMask = umask(cfg.creationMask); // XXX: Why here? Should not this be set for the whole Squid? - fd_ = ::open(filename, cfg.openFlags, cfg.openMode); + fd_ = xopen(filename, cfg.openFlags, cfg.openMode); const auto savedErrno = errno; if (cfg.creationMask) umask(oldCreationMask); @@ -203,7 +202,7 @@ File::close() debugs(54, DBG_IMPORTANT, sysCallFailure("CloseHandle", WindowsErrorMessage(savedError))); } #else - if (::close(fd_) != 0) { + if (xclose(fd_) != 0) { const auto savedErrno = errno; debugs(54, DBG_IMPORTANT, sysCallError("close", savedErrno)); } @@ -250,7 +249,7 @@ File::readSmall(const SBuf::size_type minBytes, const SBuf::size_type maxBytes) throw TexcHere(sysCallFailure("ReadFile", WindowsErrorMessage(savedError))); } #else - const auto result = ::read(fd_, rawBuf, readLimit); + const auto result = xread(fd_, rawBuf, readLimit); if (result < 0) { const auto savedErrno = errno; throw TexcHere(sysCallError("read", savedErrno)); @@ -287,7 +286,7 @@ File::writeAll(const SBuf &data) } const auto bytesWritten = static_cast(nBytesWritten); #else - const auto result = ::write(fd_, data.rawContent(), data.length()); + const auto result = xwrite(fd_, data.rawContent(), data.length()); if (result < 0) { const auto savedErrno = errno; throw TexcHere(sysCallError("write", savedErrno)); diff --git a/src/cache_cf.cc b/src/cache_cf.cc index cc3631403d..da21910189 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -28,6 +28,8 @@ #include "cache_cf.h" #include "CachePeer.h" #include "CachePeers.h" +#include "compat/netdb.h" +#include "compat/socket.h" #include "ConfigOption.h" #include "ConfigParser.h" #include "CpuAffinityMap.h" @@ -104,9 +106,6 @@ #if HAVE_GRP_H #include #endif -#if HAVE_SYS_SOCKET_H -#include -#endif #if HAVE_SYS_STAT_H #include #endif @@ -2130,7 +2129,7 @@ GetService(const char *proto) } /** Returns either the service port number from /etc/services */ if ( !isUnsignedNumeric(token, strlen(token)) ) - port = getservbyname(token, proto); + port = xgetservbyname(token, proto); if (port != nullptr) { return ntohs((unsigned short)port->s_port); } diff --git a/src/client_side.cc b/src/client_side.cc index 17d377dfef..d8507bd5e9 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -78,6 +78,7 @@ #include "comm/TcpAcceptor.h" #include "comm/Write.h" #include "CommCalls.h" +#include "compat/socket.h" #include "debug/Messages.h" #include "error/ExceptionErrorDetail.h" #include "errorpage.h" @@ -2134,7 +2135,7 @@ ConnStateData::start() (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) { + if (xsetsockopt(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)); } diff --git a/src/clients/FtpGateway.cc b/src/clients/FtpGateway.cc index ddf9616029..4c4b59df46 100644 --- a/src/clients/FtpGateway.cc +++ b/src/clients/FtpGateway.cc @@ -18,6 +18,7 @@ #include "comm/Read.h" #include "comm/TcpAcceptor.h" #include "CommCalls.h" +#include "compat/socket.h" #include "compat/strtoll.h" #include "errorpage.h" #include "fd.h" @@ -1777,8 +1778,8 @@ ftpOpenListenSocket(Ftp::Gateway * ftpState, int fallback) if (fallback) { int on = 1; errno = 0; - if (setsockopt(ftpState->ctrl.conn->fd, SOL_SOCKET, SO_REUSEADDR, - (char *) &on, sizeof(on)) == -1) { + if (xsetsockopt(ftpState->ctrl.conn->fd, SOL_SOCKET, SO_REUSEADDR, + &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: " << xstrerr(xerrno)); diff --git a/src/comm.cc b/src/comm.cc index 4b88933c01..034c177603 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -21,6 +21,8 @@ #include "comm/TcpAcceptor.h" #include "comm/Write.h" #include "compat/cmsg.h" +#include "compat/socket.h" +#include "compat/unistd.h" #include "DescriptorSet.h" #include "event.h" #include "fd.h" @@ -129,7 +131,7 @@ comm_udp_recvfrom(int fd, void *buf, size_t len, int flags, Ip::Address &from) debugs(5,8, "comm_udp_recvfrom: FD " << fd << " from " << from); struct addrinfo *AI = nullptr; Ip::Address::InitAddr(AI); - int x = recvfrom(fd, buf, len, flags, AI->ai_addr, &AI->ai_addrlen); + int x = xrecvfrom(fd, buf, len, flags, AI->ai_addr, &AI->ai_addrlen); from = *AI; Ip::Address::FreeAddr(AI); return x; @@ -145,7 +147,7 @@ comm_udp_recv(int fd, void *buf, size_t len, int flags) ssize_t comm_udp_send(int s, const void *buf, size_t len, int flags) { - return send(s, buf, len, flags); + return xsend(s, buf, len, flags); } bool @@ -183,7 +185,7 @@ comm_local_port(int fd) Ip::Address::InitAddr(addr); - if (getsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) { + if (xgetsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) { int xerrno = errno; debugs(50, DBG_IMPORTANT, "ERROR: " << MYNAME << "Failed to retrieve TCP/UDP port number for socket: FD " << fd << ": " << xstrerr(xerrno)); Ip::Address::FreeAddr(addr); @@ -211,7 +213,7 @@ commSetBindAddressNoPort(const int fd) { #if defined(IP_BIND_ADDRESS_NO_PORT) int flag = 1; - if (setsockopt(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, reinterpret_cast(&flag), sizeof(flag)) < 0) { + if (xsetsockopt(fd, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, &flag, sizeof(flag)) < 0) { const auto savedErrno = errno; debugs(50, DBG_IMPORTANT, "ERROR: setsockopt(IP_BIND_ADDRESS_NO_PORT) failure: " << xstrerr(savedErrno)); } @@ -225,7 +227,7 @@ commBind(int s, struct addrinfo &inaddr) { ++ statCounter.syscalls.sock.binds; - if (bind(s, inaddr.ai_addr, inaddr.ai_addrlen) == 0) { + if (xbind(s, inaddr.ai_addr, inaddr.ai_addrlen) == 0) { debugs(50, 6, "bind socket FD " << s << " to " << fd_table[s].local_addr); return Comm::OK; } @@ -294,7 +296,7 @@ static void comm_set_v6only(int fd, int tos) { #ifdef IPV6_V6ONLY - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *) &tos, sizeof(int)) < 0) { + if (xsetsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &tos, sizeof(int)) < 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(IPV6_V6ONLY) " << (tos?"ON":"OFF") << " for FD " << fd << ": " << xstrerr(xerrno)); } @@ -336,7 +338,7 @@ comm_set_transparent(int fd) #if defined(soLevel) && defined(soFlag) int tos = 1; - if (setsockopt(fd, soLevel, soFlag, (char *) &tos, sizeof(int)) < 0) { + if (xsetsockopt(fd, soLevel, soFlag, &tos, sizeof(int)) < 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, MYNAME << "setsockopt(TPROXY) on FD " << fd << ": " << xstrerr(xerrno)); } else { @@ -378,7 +380,7 @@ comm_openex(int sock_type, debugs(50, 3, "comm_openex: Attempt open socket for: " << addr ); - new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); + new_socket = xsocket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); const auto firstErrNo = errno; /* under IPv6 there is the possibility IPv6 is present but disabled. */ @@ -391,7 +393,7 @@ comm_openex(int sock_type, AI->ai_socktype = sock_type; AI->ai_protocol = proto; debugs(50, 3, "Attempt fallback open socket for: " << addr ); - new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); + new_socket = xsocket(AI->ai_family, AI->ai_socktype, AI->ai_protocol); // TODO: Report failures of this second socket() call. // if both socket() calls fail, we use firstErrNo debugs(50, 2, "attempt open " << note << " socket on: " << addr); @@ -506,7 +508,7 @@ comm_apply_flags(int new_socket, #if defined(SO_REUSEPORT) if (flags & COMM_REUSEPORT) { int on = 1; - if (setsockopt(new_socket, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast(&on), sizeof(on)) < 0) { + if (xsetsockopt(new_socket, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on)) < 0) { const auto savedErrno = errno; const auto errorMessage = ToSBuf("cannot enable SO_REUSEPORT socket option when binding to ", addr, ": ", xstrerr(savedErrno)); @@ -671,7 +673,8 @@ comm_connect_addr(int sock, const Ip::Address &address) ++ statCounter.syscalls.sock.connects; errno = 0; - if ((x = connect(sock, AI->ai_addr, AI->ai_addrlen)) < 0) { + x = xconnect(sock, AI->ai_addr, AI->ai_addrlen); + if (x < 0) { xerrno = errno; debugs(5,5, "sock=" << sock << ", addrinfo(" << " flags=" << AI->ai_flags << @@ -693,7 +696,7 @@ comm_connect_addr(int sock, const Ip::Address &address) } else { errno = 0; errlen = sizeof(err); - x = getsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &errlen); + x = xgetsockopt(sock, SOL_SOCKET, SO_ERROR, &err, &errlen); if (x == 0) xerrno = err; @@ -770,7 +773,7 @@ commConfigureLinger(const int fd, const OnOff enabled) fd_table[fd].flags.harshClosureRequested = (l.l_onoff && !l.l_linger); // close(2) sends TCP RST if true - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, reinterpret_cast(&l), sizeof(l)) < 0) { + if (xsetsockopt(fd, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) { const auto xerrno = errno; debugs(50, DBG_CRITICAL, "ERROR: Failed to set closure behavior (SO_LINGER) for FD " << fd << ": " << xstrerr(xerrno)); } @@ -813,7 +816,7 @@ comm_close_complete(const int fd) F->ssl.reset(); F->dynamicTlsContext.reset(); fd_close(fd); /* update fdstat */ - close(fd); + xclose(fd); ++ statCounter.syscalls.sock.closes; @@ -917,7 +920,7 @@ comm_udp_sendto(int fd, struct addrinfo *AI = nullptr; to_addr.getAddrInfo(AI, fd_table[fd].sock_family); - int x = sendto(fd, buf, len, 0, AI->ai_addr, AI->ai_addrlen); + int x = xsendto(fd, buf, len, 0, AI->ai_addr, AI->ai_addrlen); int xerrno = errno; Ip::Address::FreeAddr(AI); @@ -1012,7 +1015,7 @@ static void commSetReuseAddr(int fd) { int on = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &on, sizeof(on)) < 0) { + if (xsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno)); } @@ -1021,16 +1024,16 @@ commSetReuseAddr(int fd) static void commSetTcpRcvbuf(int fd, int size) { - if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof(size)) < 0) { + if (xsetsockopt(fd, SOL_SOCKET, SO_RCVBUF, &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) { + if (xsetsockopt(fd, SOL_SOCKET, SO_SNDBUF, &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) { + if (xsetsockopt(fd, SOL_TCP, TCP_WINDOW_CLAMP, &size, sizeof(size)) < 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ", SIZE " << size << ": " << xstrerr(xerrno)); } @@ -1124,7 +1127,7 @@ commSetTcpNoDelay(int fd) { int on = 1; - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) { + if (xsetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &on, sizeof(on)) < 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, MYNAME << "FD " << fd << ": " << xstrerr(xerrno)); } @@ -1696,7 +1699,7 @@ comm_open_uds(int sock_type, debugs(50, 3, "Attempt open socket for: " << addr->sun_path); - if ((new_socket = socket(AI.ai_family, AI.ai_socktype, AI.ai_protocol)) < 0) { + if ((new_socket = xsocket(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 diff --git a/src/comm/ConnOpener.cc b/src/comm/ConnOpener.cc index 25aad6bb4b..44838865a1 100644 --- a/src/comm/ConnOpener.cc +++ b/src/comm/ConnOpener.cc @@ -14,6 +14,7 @@ #include "comm/Connection.h" #include "comm/ConnOpener.h" #include "comm/Loops.h" +#include "compat/socket.h" #include "fd.h" #include "fde.h" #include "globals.h" @@ -431,7 +432,7 @@ Comm::ConnOpener::lookupLocalAddress() { struct sockaddr_storage addr = {}; socklen_t len = sizeof(addr); - if (getsockname(conn_->fd, reinterpret_cast(&addr), &len) != 0) { + if (xgetsockname(conn_->fd, reinterpret_cast(&addr), &len) != 0) { int xerrno = errno; debugs(50, DBG_IMPORTANT, "ERROR: Failed to retrieve TCP/UDP details for socket: " << conn_ << ": " << xstrerr(xerrno)); return; diff --git a/src/comm/ModDevPoll.cc b/src/comm/ModDevPoll.cc index e049fb578e..b2f08f17b6 100644 --- a/src/comm/ModDevPoll.cc +++ b/src/comm/ModDevPoll.cc @@ -30,6 +30,7 @@ #include "base/IoManip.h" #include "comm/Loops.h" +#include "compat/unistd.h" #include "fd.h" #include "fde.h" #include "mgr/Registration.h" @@ -92,7 +93,6 @@ static void commDevPollRegisterWithCacheManager(void); static void comm_flush_updates(void) { - int i; if (devpoll_update.cur == -1) return; /* array of changes to make is empty */ @@ -102,11 +102,11 @@ comm_flush_updates(void) (devpoll_update.cur + 1) << " fds queued" ); - i = write( - devpoll_fd, /* open handle to /dev/poll */ - devpoll_update.pfds, /* pointer to array of struct pollfd */ - (devpoll_update.cur + 1) * sizeof(struct pollfd) /* bytes to process */ - ); + const auto i = xwrite( + devpoll_fd, /* open handle to /dev/poll */ + devpoll_update.pfds, /* pointer to array of struct pollfd */ + (devpoll_update.cur + 1) * sizeof(struct pollfd) /* bytes to process */ + ); assert(i > 0); assert(static_cast(i) == (sizeof(struct pollfd) * (devpoll_update.cur + 1))); devpoll_update.cur = -1; /* reset size of array, no elements remain */ @@ -191,7 +191,7 @@ Comm::SelectLoopInit(void) ); /* attempt to open /dev/poll device */ - devpoll_fd = open("/dev/poll", O_RDWR); + devpoll_fd = xopen("/dev/poll", O_RDWR); if (devpoll_fd < 0) { int xerrno = errno; fatalf("comm_select_init: can't open /dev/poll: %s\n", xstrerr(xerrno)); diff --git a/src/comm/ModSelect.cc b/src/comm/ModSelect.cc index 6f3a58d3ef..79e91fc430 100644 --- a/src/comm/ModSelect.cc +++ b/src/comm/ModSelect.cc @@ -15,6 +15,7 @@ #include "anyp/PortCfg.h" #include "comm/Connection.h" #include "comm/Loops.h" +#include "compat/select.h" #include "fde.h" #include "globals.h" #include "ICP.h" @@ -156,7 +157,7 @@ comm_check_incoming_select_handlers(int nfds, int *fds) ++ statCounter.syscalls.selects; - if (select(maxfd, &read_mask, &write_mask, nullptr, &zero_tv) < 1) + if (xselect(maxfd, &read_mask, &write_mask, nullptr, &zero_tv) < 1) return incoming_sockets_accepted; for (i = 0; i < nfds; ++i) { @@ -320,7 +321,7 @@ Comm::DoSelect(int msec) poll_time.tv_sec = msec / 1000; poll_time.tv_usec = (msec % 1000) * 1000; ++ statCounter.syscalls.selects; - num = select(maxfd, &readfds, &writefds, nullptr, &poll_time); + num = xselect(maxfd, &readfds, &writefds, nullptr, &poll_time); int xerrno = errno; ++ statCounter.select_loops; diff --git a/src/comm/Tcp.cc b/src/comm/Tcp.cc index d42c290821..ee41d00a85 100644 --- a/src/comm/Tcp.cc +++ b/src/comm/Tcp.cc @@ -10,6 +10,7 @@ #include "squid.h" #include "comm/Tcp.h" +#include "compat/socket.h" #include "debug/Stream.h" #if HAVE_NETINET_TCP_H @@ -18,19 +19,16 @@ #if HAVE_NETINET_IN_H #include #endif -#if HAVE_SYS_SOCKET_H -#include -#endif #include -/// setsockopt(2) wrapper +/// xsetsockopt(2) wrapper template static bool SetSocketOption(const int fd, const int level, const int optName, const Option &optValue) { static_assert(std::is_trivially_copyable