include/boost/corosio/native/detail/validate_fd.hpp

90.0% Lines (18/0/20) 100.0% List of functions (1/0/1)
validate_fd.hpp
f(x) Functions (1)
Line TLA Hits Source 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
39 274x validate_socket_fd(int fd, int expected_type, bool is_ip) noexcept
40 {
41 274x if (fd < 0)
42 14x return make_err(EBADF);
43
44 260x sockaddr_storage st{};
45 260x socklen_t st_len = sizeof(st);
46 260x if (::getsockname(fd, reinterpret_cast<sockaddr*>(&st), &st_len) != 0)
47 return make_err(errno);
48 260x if (is_ip)
49 {
50 38x if (st.ss_family != AF_INET && st.ss_family != AF_INET6)
51 6x return make_err(EAFNOSUPPORT);
52 }
53 222x else if (st.ss_family != AF_UNIX)
54 {
55 2x return make_err(EAFNOSUPPORT);
56 }
57
58 252x int sock_type = 0;
59 252x socklen_t opt_len = sizeof(sock_type);
60 252x if (::getsockopt(fd, SOL_SOCKET, SO_TYPE,
61 252x &sock_type, &opt_len) != 0)
62 return make_err(errno);
63 252x if (sock_type != expected_type)
64 18x return make_err(EPROTOTYPE);
65
66 234x return {};
67 }
68
69 } // namespace boost::corosio::detail
70
71 #endif // BOOST_COROSIO_POSIX
72
73 #endif // BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
74