src/corosio/src/local_datagram_socket.cpp

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