90.00% Lines (18/20) 100.00% Functions (1/1)
TLA Baseline Branch
Line Hits Code Line Hits Code
  1 + //
  2 + // Copyright (c) 2026 Steve Gerbino
  3 + //
  4 + // Distributed under the Boost Software License, Version 1.0. (See accompanying
  5 + // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6 + //
  7 + // Official repository: https://github.com/cppalliance/corosio
  8 + //
  9 +
  10 + #ifndef BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
  11 + #define BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
  12 +
  13 + #include <boost/corosio/detail/platform.hpp>
  14 +
  15 + #if BOOST_COROSIO_POSIX
  16 +
  17 + #include <boost/corosio/native/detail/make_err.hpp>
  18 +
  19 + #include <cerrno>
  20 + #include <system_error>
  21 +
  22 + #include <sys/socket.h>
  23 +
  24 + namespace boost::corosio::detail {
  25 +
  26 + /** Validate a caller-supplied socket fd for adoption.
  27 +
  28 + Non-mutating: interrogates the fd without changing any of its
  29 + flags, so a rejected fd goes back to the caller untouched.
  30 +
  31 + @param fd The descriptor to validate.
  32 + @param expected_type `SOCK_STREAM` or `SOCK_DGRAM`.
  33 + @param is_ip Accept `AF_INET`/`AF_INET6` when true, `AF_UNIX`
  34 + when false.
  35 + @return Empty on success; `EBADF`, `EAFNOSUPPORT`, `EPROTOTYPE`,
  36 + or the `errno` reported by the interrogating call.
  37 + */
  38 + inline std::error_code
HITGNC   39 + 266 validate_socket_fd(int fd, int expected_type, bool is_ip) noexcept
  40 + {
HITGNC   41 + 266 if (fd < 0)
HITGNC   42 + 10 return make_err(EBADF);
  43 +
HITGNC   44 + 256 sockaddr_storage st{};
HITGNC   45 + 256 socklen_t st_len = sizeof(st);
HITGNC   46 + 256 if (::getsockname(fd, reinterpret_cast<sockaddr*>(&st), &st_len) != 0)
MISUNC   47 + return make_err(errno);
HITGNC   48 + 256 if (is_ip)
  49 + {
HITGNC   50 + 38 if (st.ss_family != AF_INET && st.ss_family != AF_INET6)
HITGNC   51 + 6 return make_err(EAFNOSUPPORT);
  52 + }
HITGNC   53 + 218 else if (st.ss_family != AF_UNIX)
  54 + {
HITGNC   55 + 2 return make_err(EAFNOSUPPORT);
  56 + }
  57 +
HITGNC   58 + 248 int sock_type = 0;
HITGNC   59 + 248 socklen_t opt_len = sizeof(sock_type);
HITGNC   60 + 248 if (::getsockopt(fd, SOL_SOCKET, SO_TYPE,
HITGNC   61 + 248 &sock_type, &opt_len) != 0)
MISUNC   62 + return make_err(errno);
HITGNC   63 + 248 if (sock_type != expected_type)
HITGNC   64 + 18 return make_err(EPROTOTYPE);
  65 +
HITGNC   66 + 230 return {};
  67 + }
  68 +
  69 + } // namespace boost::corosio::detail
  70 +
  71 + #endif // BOOST_COROSIO_POSIX
  72 +
  73 + #endif // BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP