src/corosio/src/local_stream_acceptor.cpp

86.3% Lines (44/51) 100.0% List of functions (9/9) 63.0% Branches (17/27)
local_stream_acceptor.cpp
f(x) Functions (9)
Line Branch 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/local_stream_acceptor.hpp>
11 #include <boost/corosio/detail/except.hpp>
12 #include <boost/corosio/detail/platform.hpp>
13 #include <boost/corosio/detail/local_stream_acceptor_service.hpp>
14
15 #include <cstring>
16
17 #if BOOST_COROSIO_POSIX
18 #include <unistd.h>
19 #else
20 // Windows: AF_UNIX socket files are reparse points with tag
21 // IO_REPARSE_TAG_AF_UNIX. DeleteFileA reliably removes them;
22 // std::filesystem::remove via libstdc++/MS STL was observed to
23 // silently leave them in place on at least some Windows hosts,
24 // so call the Win32 API directly.
25 #define WIN32_LEAN_AND_MEAN
26 #include <windows.h>
27 #endif
28
29 namespace boost::corosio {
30
31 16x local_stream_acceptor::~local_stream_acceptor()
32 {
33 16x close();
34 16x }
35
36 10x local_stream_acceptor::local_stream_acceptor(capy::execution_context& ctx)
37 10x : io_object(create_handle<detail::local_stream_acceptor_service>(ctx))
38
1/1
✓ Branch 2 → 3 taken 10 times.
10x , ctx_(ctx)
39 {
40 10x }
41
42 void
43 10x local_stream_acceptor::open(local_stream proto)
44 {
45
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 10 times.
10x if (is_open())
46 return;
47 auto& svc =
48 10x static_cast<detail::local_stream_acceptor_service&>(h_.service());
49
1/1
✓ Branch 10 → 11 taken 10 times.
20x auto ec = svc.open_acceptor_socket(
50 10x static_cast<local_stream_acceptor::implementation&>(*h_.get()),
51 proto.family(), proto.type(), proto.protocol());
52
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 10 times.
10x if (ec)
53 detail::throw_system_error(ec, "local_stream_acceptor::open");
54 }
55
56 std::error_code
57 11x local_stream_acceptor::bind(corosio::local_endpoint ep, bind_option opt)
58 {
59
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 10 times.
11x if (!is_open())
60 1x detail::throw_logic_error("bind: acceptor not open");
61
62 10x if (opt == bind_option::unlink_existing &&
63
2/8
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 11 taken 10 times.
✗ Branch 7 → 8 not taken.
✗ Branch 7 → 11 not taken.
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 11 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 19 taken 10 times.
10x !ep.empty() && !ep.is_abstract())
64 {
65 // Best-effort removal; missing file is fine.
66 auto p = ep.path();
67 char buf[local_endpoint::max_path_length + 1];
68 std::memcpy(buf, p.data(), p.size());
69 buf[p.size()] = '\0';
70 #if BOOST_COROSIO_POSIX
71 ::unlink(buf);
72 #else
73 ::DeleteFileA(buf);
74 #endif
75 }
76
77 auto& svc =
78 10x static_cast<detail::local_stream_acceptor_service&>(h_.service());
79 10x return svc.bind_acceptor(
80 10x static_cast<local_stream_acceptor::implementation&>(*h_.get()),
81 10x ep);
82 }
83
84 std::error_code
85 10x local_stream_acceptor::listen(int backlog)
86 {
87
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 9 times.
10x if (!is_open())
88 1x detail::throw_logic_error("listen: acceptor not open");
89 auto& svc =
90 9x static_cast<detail::local_stream_acceptor_service&>(h_.service());
91 9x return svc.listen_acceptor(
92 9x static_cast<local_stream_acceptor::implementation&>(*h_.get()),
93 9x backlog);
94 }
95
96 void
97 17x local_stream_acceptor::close()
98 {
99
2/2
✓ Branch 3 → 4 taken 8 times.
✓ Branch 3 → 5 taken 9 times.
17x if (!is_open())
100 8x return;
101 9x h_.service().close(h_);
102 }
103
104 native_handle_type
105 2x local_stream_acceptor::release()
106 {
107
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1 time.
2x if (!is_open())
108 1x detail::throw_logic_error("release: acceptor not open");
109 1x return get().release_socket();
110 }
111
112 void
113 1x local_stream_acceptor::cancel()
114 {
115
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 5 not taken.
1x if (!is_open())
116 1x return;
117 get().cancel();
118 }
119
120 local_endpoint
121 2x local_stream_acceptor::local_endpoint() const noexcept
122 {
123
2/2
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 5 taken 1 time.
2x if (!is_open())
124 1x return corosio::local_endpoint{};
125 1x return get().local_endpoint();
126 }
127
128 } // namespace boost::corosio
129