98.36% Lines (60/61) 100.00% Functions (13/13)
TLA Baseline Branch
Line Hits Code Line Hits Code
1   // 1   //
2   // Copyright (c) 2026 Michael Vandeberg 2   // Copyright (c) 2026 Michael Vandeberg
3   // 3   //
4   // Distributed under the Boost Software License, Version 1.0. (See accompanying 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) 5   // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6   // 6   //
7   // Official repository: https://github.com/cppalliance/corosio 7   // Official repository: https://github.com/cppalliance/corosio
8   // 8   //
9   9  
10   #include <boost/corosio/detail/platform.hpp> 10   #include <boost/corosio/detail/platform.hpp>
11   11  
12   #if BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 12   #if BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP
13   13  
14   #include <boost/corosio/local_stream_socket.hpp> 14   #include <boost/corosio/local_stream_socket.hpp>
15   #include <boost/corosio/error.hpp> 15   #include <boost/corosio/error.hpp>
16   #include <boost/corosio/detail/except.hpp> 16   #include <boost/corosio/detail/except.hpp>
17   #include <boost/corosio/detail/local_stream_service.hpp> 17   #include <boost/corosio/detail/local_stream_service.hpp>
18   18  
19   #include "src/detail/use_backend_service.hpp" 19   #include "src/detail/use_backend_service.hpp"
20   #include <boost/corosio/native/detail/make_err.hpp> 20   #include <boost/corosio/native/detail/make_err.hpp>
21   21  
22   #if BOOST_COROSIO_POSIX 22   #if BOOST_COROSIO_POSIX
23   #include <sys/ioctl.h> 23   #include <sys/ioctl.h>
24   #include <sys/socket.h> 24   #include <sys/socket.h>
25   #elif BOOST_COROSIO_HAS_IOCP 25   #elif BOOST_COROSIO_HAS_IOCP
26   #include <boost/corosio/native/detail/iocp/win_windows.hpp> 26   #include <boost/corosio/native/detail/iocp/win_windows.hpp>
27   #ifndef AF_UNIX 27   #ifndef AF_UNIX
28   #define AF_UNIX 1 28   #define AF_UNIX 1
29   #endif 29   #endif
30   #endif 30   #endif
31   31  
32   namespace boost::corosio { 32   namespace boost::corosio {
33   33  
HITCBC 34   432 local_stream_socket::~local_stream_socket() 34   432 local_stream_socket::~local_stream_socket()
35   { 35   {
HITCBC 36   432 close(); 36   432 close();
HITCBC 37   432 } 37   432 }
38   38  
HITCBC 39   374 local_stream_socket::local_stream_socket(capy::execution_context& ctx) 39   374 local_stream_socket::local_stream_socket(capy::execution_context& ctx)
HITCBC 40   374 : io_object(handle( 40   374 : io_object(handle(
41   ctx, 41   ctx,
42   detail::use_backend_service< 42   detail::use_backend_service<
43   detail::local_stream_service_of, 43   detail::local_stream_service_of,
HITCBC 44   748 detail::local_stream_service>(ctx))) 44   748 detail::local_stream_service>(ctx)))
45   { 45   {
HITCBC 46   374 } 46   374 }
47   47  
48   std::error_code 48   std::error_code
HITCBC 49   53 local_stream_socket::open() noexcept 49   53 local_stream_socket::open() noexcept
50   { 50   {
HITCBC 51   53 if (is_open()) 51   53 if (is_open())
MISUBC 52   ✗ return {}; 52   ✗ return {};
HITCBC 53   53 return open_for_family(AF_UNIX, SOCK_STREAM, 0); 53   53 return open_for_family(AF_UNIX, SOCK_STREAM, 0);
54   } 54   }
55   55  
56   std::error_code 56   std::error_code
HITCBC 57   53 local_stream_socket::open_for_family( 57   53 local_stream_socket::open_for_family(
58   int family, int type, int protocol) noexcept 58   int family, int type, int protocol) noexcept
59   { 59   {
HITCBC 60   53 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 60   53 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 61   53 std::error_code ec = svc.open_socket( 61   53 std::error_code ec = svc.open_socket(
HITCBC 62   53 static_cast<local_stream_socket::implementation&>(*h_.get()), family, 62   53 static_cast<local_stream_socket::implementation&>(*h_.get()), family,
63   type, protocol); 63   type, protocol);
HITCBC 64   53 return ec; 64   53 return ec;
65   } 65   }
66   66  
67   void 67   void
HITCBC 68   453 local_stream_socket::close() noexcept 68   453 local_stream_socket::close() noexcept
69   { 69   {
HITCBC 70   453 if (!is_open()) 70   453 if (!is_open())
HITCBC 71   213 return; 71   213 return;
HITCBC 72   240 h_.service().close(h_); 72   240 h_.service().close(h_);
73   } 73   }
74   74  
75   void 75   void
HITCBC 76   10 local_stream_socket::cancel() noexcept 76   10 local_stream_socket::cancel() noexcept
77   { 77   {
HITCBC 78   10 if (!is_open()) 78   10 if (!is_open())
HITCBC 79   2 return; 79   2 return;
HITCBC 80   8 get().cancel(); 80   8 get().cancel();
81   } 81   }
82   82  
83   std::error_code 83   std::error_code
HITCBC 84   6 local_stream_socket::shutdown(shutdown_type what) noexcept 84   6 local_stream_socket::shutdown(shutdown_type what) noexcept
85   { 85   {
HITCBC 86   6 if (!is_open()) 86   6 if (!is_open())
HITCBC 87   2 return make_error_code(std::errc::bad_file_descriptor); 87   2 return make_error_code(std::errc::bad_file_descriptor);
HITCBC 88   4 return get().shutdown(what); 88   4 return get().shutdown(what);
89   } 89   }
90   90  
91   std::error_code 91   std::error_code
HITCBC 92   191 local_stream_socket::assign(native_handle_type fd) noexcept 92   191 local_stream_socket::assign(native_handle_type fd) noexcept
93   { 93   {
HITCBC 94   191 if (is_open()) 94   191 if (is_open())
HITCBC 95   8 return make_error_code(error::already_open); 95   8 return make_error_code(error::already_open);
HITCBC 96   183 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 96   183 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 97   183 std::error_code ec = svc.assign_socket( 97   183 std::error_code ec = svc.assign_socket(
HITCBC 98   183 static_cast<local_stream_socket::implementation&>(*h_.get()), fd); 98   183 static_cast<local_stream_socket::implementation&>(*h_.get()), fd);
HITCBC 99   183 return ec; 99   183 return ec;
100   } 100   }
101   101  
102   native_handle_type 102   native_handle_type
HITCBC 103   31 local_stream_socket::native_handle() const noexcept 103   31 local_stream_socket::native_handle() const noexcept
104   { 104   {
HITCBC 105   31 if (!is_open()) 105   31 if (!is_open())
106   #if BOOST_COROSIO_HAS_IOCP 106   #if BOOST_COROSIO_HAS_IOCP
107   return ~native_handle_type(0); 107   return ~native_handle_type(0);
108   #else 108   #else
HITCBC 109   2 return -1; 109   2 return -1;
110   #endif 110   #endif
HITCBC 111   29 return get().native_handle(); 111   29 return get().native_handle();
112   } 112   }
113   113  
114   native_handle_type 114   native_handle_type
HITCBC 115   8 local_stream_socket::release() 115   8 local_stream_socket::release()
116   { 116   {
HITCBC 117   8 if (!is_open()) 117   8 if (!is_open())
HITCBC 118   2 detail::throw_system_error( 118   2 detail::throw_system_error(
HITCBC 119   2 make_error_code(std::errc::bad_file_descriptor), 119   2 make_error_code(std::errc::bad_file_descriptor),
120   "local_stream_socket::release"); 120   "local_stream_socket::release");
HITCBC 121   6 return get().release_socket(); 121   6 return get().release_socket();
122   } 122   }
123   123  
124   std::size_t 124   std::size_t
HITCBC 125   11 local_stream_socket::available() const 125   11 local_stream_socket::available() const
126   { 126   {
HITCBC 127   11 if (!is_open()) 127   11 if (!is_open())
HITCBC 128   2 detail::throw_system_error( 128   2 detail::throw_system_error(
HITCBC 129   4 make_error_code(std::errc::bad_file_descriptor), 129   4 make_error_code(std::errc::bad_file_descriptor),
130   "local_stream_socket::available"); 130   "local_stream_socket::available");
131   #if BOOST_COROSIO_HAS_IOCP 131   #if BOOST_COROSIO_HAS_IOCP
132   u_long value = 0; 132   u_long value = 0;
133   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) != 133   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) !=
134   0) 134   0)
135   detail::throw_system_error( 135   detail::throw_system_error(
136   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())), 136   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())),
137   "local_stream_socket::available"); 137   "local_stream_socket::available");
138   return static_cast<std::size_t>(value); 138   return static_cast<std::size_t>(value);
139   #else 139   #else
HITCBC 140   9 int value = 0; 140   9 int value = 0;
HITCBC 141   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0) 141   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0)
HITCBC 142   5 detail::throw_system_error( 142   5 detail::throw_system_error(
HITCBC 143   10 detail::make_err(errno), "local_stream_socket::available"); 143   10 detail::make_err(errno), "local_stream_socket::available");
HITCBC 144   4 return static_cast<std::size_t>(value); 144   4 return static_cast<std::size_t>(value);
145   #endif 145   #endif
146   } 146   }
147   147  
148   local_endpoint 148   local_endpoint
HITCBC 149   6 local_stream_socket::local_endpoint() const noexcept 149   6 local_stream_socket::local_endpoint() const noexcept
150   { 150   {
HITCBC 151   6 if (!is_open()) 151   6 if (!is_open())
HITCBC 152   2 return corosio::local_endpoint{}; 152   2 return corosio::local_endpoint{};
HITCBC 153   4 return get().local_endpoint(); 153   4 return get().local_endpoint();
154   } 154   }
155   155  
156   local_endpoint 156   local_endpoint
HITCBC 157   6 local_stream_socket::remote_endpoint() const noexcept 157   6 local_stream_socket::remote_endpoint() const noexcept
158   { 158   {
HITCBC 159   6 if (!is_open()) 159   6 if (!is_open())
HITCBC 160   2 return corosio::local_endpoint{}; 160   2 return corosio::local_endpoint{};
HITCBC 161   4 return get().remote_endpoint(); 161   4 return get().remote_endpoint();
162   } 162   }
163   163  
164   } // namespace boost::corosio 164   } // namespace boost::corosio
165   165  
166   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 166   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP