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

90.9% Lines (20/22) 100.0% List of functions (1/1) 66.7% Branches (16/24)
validate_fd.hpp
f(x) Functions (1)
Line Branch 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 272x validate_socket_fd(int fd, int expected_type, bool is_ip) noexcept
40 {
41
2/2
✓ Branch 0 taken 258 times.
✓ Branch 1 taken 14 times.
272x if (fd < 0)
42 14x return make_err(EBADF);
43
44 258x sockaddr_storage st{};
45 258x socklen_t st_len = sizeof(st);
46
2/4
✓ Branch 0 taken 258 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 258 times.
258x if (::getsockname(fd, reinterpret_cast<sockaddr*>(&st), &st_len) != 0)
47 return make_err(errno);
48
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 220 times.
258x if (is_ip)
49 {
50
4/4
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 26 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 6 times.
38x if (st.ss_family != AF_INET && st.ss_family != AF_INET6)
51 6x return make_err(EAFNOSUPPORT);
52 32x }
53
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 218 times.
220x else if (st.ss_family != AF_UNIX)
54 {
55 2x return make_err(EAFNOSUPPORT);
56 }
57
58 250x int sock_type = 0;
59 250x socklen_t opt_len = sizeof(sock_type);
60
2/4
✓ Branch 0 taken 250 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 250 times.
250x if (::getsockopt(fd, SOL_SOCKET, SO_TYPE,
61 250x &sock_type, &opt_len) != 0)
62 return make_err(errno);
63
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 232 times.
250x if (sock_type != expected_type)
64 18x return make_err(EPROTOTYPE);
65
66 232x return {};
67 272x }
68
69 } // namespace boost::corosio::detail
70
71 #endif // BOOST_COROSIO_POSIX
72
73 #endif // BOOST_COROSIO_NATIVE_DETAIL_VALIDATE_FD_HPP
74