src/corosio/src/local_datagram_socket.cpp

94.4% Lines (68/0/72) 100.0% List of functions (15/0/15)
local_datagram_socket.cpp
f(x) Functions (15)
Line TLA Hits Source Code
1 //
2 // Copyright (c) 2026 Michael Vandeberg
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 #include <boost/corosio/detail/platform.hpp>
11
12 #if BOOST_COROSIO_POSIX
13
14 #include <boost/corosio/local_datagram_socket.hpp>
15 #include <boost/corosio/detail/except.hpp>
16 #include <boost/corosio/detail/local_datagram_service.hpp>
17
18 #include <sys/ioctl.h>
19
20 namespace boost::corosio {
21
22 200x local_datagram_socket::~local_datagram_socket()
23 {
24 200x close();
25 200x }
26
27 172x local_datagram_socket::local_datagram_socket(capy::execution_context& ctx)
28 172x : io_object(create_handle<detail::local_datagram_service>(ctx))
29 {
30 172x }
31
32 void
33 70x local_datagram_socket::open(local_datagram proto)
34 {
35 70x if (is_open())
36 return;
37 70x open_for_family(proto.family(), proto.type(), proto.protocol());
38 }
39
40 void
41 70x local_datagram_socket::open_for_family(int family, int type, int protocol)
42 {
43 70x auto& svc = static_cast<detail::local_datagram_service&>(h_.service());
44 70x std::error_code ec = svc.open_socket(
45 70x static_cast<local_datagram_socket::implementation&>(*h_.get()),
46 family, type, protocol);
47 70x if (ec)
48 detail::throw_system_error(ec, "local_datagram_socket::open");
49 70x }
50
51 void
52 207x local_datagram_socket::close()
53 {
54 207x if (!is_open())
55 41x return;
56 166x h_.service().close(h_);
57 }
58
59 std::error_code
60 54x local_datagram_socket::bind(corosio::local_endpoint ep)
61 {
62 54x if (!is_open())
63 2x detail::throw_logic_error("bind: socket not open");
64 52x auto& svc = static_cast<detail::local_datagram_service&>(h_.service());
65 52x return svc.bind_socket(
66 52x static_cast<local_datagram_socket::implementation&>(*h_.get()),
67 52x ep);
68 }
69
70 void
71 6x local_datagram_socket::cancel()
72 {
73 6x if (!is_open())
74 2x return;
75 4x get().cancel();
76 }
77
78 void
79 4x local_datagram_socket::shutdown(shutdown_type what)
80 {
81 4x if (is_open())
82 {
83 // Best-effort: errors like ENOTCONN are expected and unhelpful
84 2x [[maybe_unused]] auto ec = get().shutdown(what);
85 }
86 4x }
87
88 void
89 8x local_datagram_socket::shutdown(shutdown_type what, std::error_code& ec) noexcept
90 {
91 8x ec = {};
92 8x if (is_open())
93 6x ec = get().shutdown(what);
94 8x }
95
96 void
97 106x local_datagram_socket::assign(native_handle_type fd)
98 {
99 106x auto& svc = static_cast<detail::local_datagram_service&>(h_.service());
100 106x std::error_code ec = svc.assign_socket(
101 106x static_cast<local_datagram_socket::implementation&>(*h_.get()), fd);
102 106x if (ec)
103 6x detail::throw_system_error(ec, "local_datagram_socket::assign");
104 100x }
105
106 native_handle_type
107 8x local_datagram_socket::native_handle() const noexcept
108 {
109 8x if (!is_open())
110 2x return -1;
111 6x return get().native_handle();
112 }
113
114 native_handle_type
115 4x local_datagram_socket::release()
116 {
117 4x if (!is_open())
118 2x detail::throw_logic_error("release: socket not open");
119 2x return get().release_socket();
120 }
121
122 std::size_t
123 4x local_datagram_socket::available() const
124 {
125 4x if (!is_open())
126 2x detail::throw_logic_error("available: socket not open");
127 2x int value = 0;
128 2x if (::ioctl(native_handle(), FIONREAD, &value) < 0)
129 detail::throw_system_error(
130 std::error_code(errno, std::system_category()),
131 "local_datagram_socket::available");
132 2x return static_cast<std::size_t>(value);
133 }
134
135 local_endpoint
136 4x local_datagram_socket::local_endpoint() const noexcept
137 {
138 4x if (!is_open())
139 2x return corosio::local_endpoint{};
140 2x return get().local_endpoint();
141 }
142
143 local_endpoint
144 4x local_datagram_socket::remote_endpoint() const noexcept
145 {
146 4x if (!is_open())
147 2x return corosio::local_endpoint{};
148 2x return get().remote_endpoint();
149 }
150
151 } // namespace boost::corosio
152
153 #endif // BOOST_COROSIO_POSIX
154