TLA Line data 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 : #ifndef BOOST_COROSIO_LOCAL_ENDPOINT_HPP
11 : #define BOOST_COROSIO_LOCAL_ENDPOINT_HPP
12 :
13 : #include <boost/corosio/detail/config.hpp>
14 :
15 : #include <algorithm>
16 : #include <compare>
17 : #include <cstddef>
18 : #include <cstdint>
19 : #include <cstring>
20 : #include <iosfwd>
21 : #include <string_view>
22 : #include <system_error>
23 :
24 : namespace boost::corosio {
25 :
26 : /** A Unix domain socket endpoint (filesystem path).
27 :
28 : Stores the path in a fixed-size buffer, avoiding heap
29 : allocation. The object is trivially copyable.
30 :
31 : Abstract sockets (Linux-only) are represented by paths whose
32 : first character is '\0'. The full path including the leading
33 : null byte is stored.
34 :
35 : The library does NOT automatically unlink the socket path on
36 : close — callers are responsible for cleanup.
37 :
38 : @par Thread Safety
39 : Distinct objects: Safe.@n
40 : Shared objects: Safe.
41 : */
42 : class BOOST_COROSIO_DECL local_endpoint
43 : {
44 : // sun_path is 108 on Linux, 104 on macOS/FreeBSD. Use the
45 : // minimum so local_endpoint is portable across all three.
46 : char path_[104]{};
47 : std::uint8_t len_ = 0;
48 :
49 : public:
50 : /// Maximum path length for a Unix domain socket (excluding null terminator).
51 : static constexpr std::size_t max_path_length = 103;
52 :
53 : /// Default constructor. Creates an empty (unbound) endpoint.
54 HIT 940 : local_endpoint() noexcept = default;
55 :
56 : /** Construct from a path.
57 :
58 : @param path The filesystem path for the socket.
59 : Must not exceed @ref max_path_length bytes.
60 :
61 : @throws std::system_error if the path is too long.
62 : */
63 : explicit local_endpoint(std::string_view path);
64 :
65 : /** Construct from a path (no-throw).
66 :
67 : @param path The filesystem path for the socket.
68 : @param ec Set to an error if the path is too long.
69 : */
70 : local_endpoint(std::string_view path, std::error_code& ec) noexcept;
71 :
72 : /** Return the socket path.
73 :
74 : For abstract sockets, the returned view includes the
75 : leading null byte.
76 :
77 : @return A view over the stored path bytes.
78 : */
79 52 : std::string_view path() const noexcept
80 : {
81 52 : return std::string_view(path_, len_);
82 : }
83 :
84 : /** Check if this is an abstract socket (Linux-only).
85 :
86 : Abstract sockets live in a kernel namespace rather than
87 : the filesystem. They are identified by a leading null byte
88 : in the path.
89 :
90 : @return `true` if the path starts with '\\0'.
91 : */
92 48 : bool is_abstract() const noexcept
93 : {
94 48 : return len_ > 0 && path_[0] == '\0';
95 : }
96 :
97 : /// Return true if the endpoint has no path.
98 10 : bool empty() const noexcept
99 : {
100 10 : return len_ == 0;
101 : }
102 :
103 : /// Compare endpoints for equality.
104 : friend bool
105 4 : operator==(local_endpoint const& a, local_endpoint const& b) noexcept
106 : {
107 8 : return a.len_ == b.len_ &&
108 8 : std::memcmp(a.path_, b.path_, a.len_) == 0;
109 : }
110 :
111 : /** Format the endpoint for stream output.
112 :
113 : Non-abstract paths are printed as-is. Abstract paths
114 : (leading null byte) are printed as `[abstract:name]`.
115 : Empty endpoints produce no output.
116 :
117 : @param os The output stream.
118 : @param ep The endpoint to format.
119 :
120 : @return A reference to @p os.
121 : */
122 : friend BOOST_COROSIO_DECL std::ostream&
123 : operator<<(std::ostream& os, local_endpoint const& ep);
124 :
125 : /// Lexicographic ordering on stored path bytes.
126 : friend std::strong_ordering
127 18 : operator<=>(local_endpoint const& a, local_endpoint const& b) noexcept
128 : {
129 18 : auto common = (std::min)(a.len_, b.len_);
130 18 : if (int cmp = std::memcmp(a.path_, b.path_, common); cmp != 0)
131 6 : return cmp <=> 0;
132 12 : return a.len_ <=> b.len_;
133 : }
134 : };
135 :
136 : } // namespace boost::corosio
137 :
138 : #endif // BOOST_COROSIO_LOCAL_ENDPOINT_HPP
|