98.31% Lines (58/59) 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/detail/except.hpp> 15   #include <boost/corosio/detail/except.hpp>
16   #include <boost/corosio/detail/local_stream_service.hpp> 16   #include <boost/corosio/detail/local_stream_service.hpp>
  17 +
  18 + #include "src/detail/use_backend_service.hpp"
17   #include <boost/corosio/native/detail/make_err.hpp> 19   #include <boost/corosio/native/detail/make_err.hpp>
18   20  
19   #if BOOST_COROSIO_POSIX 21   #if BOOST_COROSIO_POSIX
20   #include <sys/ioctl.h> 22   #include <sys/ioctl.h>
21   #include <sys/socket.h> 23   #include <sys/socket.h>
22   #elif BOOST_COROSIO_HAS_IOCP 24   #elif BOOST_COROSIO_HAS_IOCP
23   #include <boost/corosio/native/detail/iocp/win_windows.hpp> 25   #include <boost/corosio/native/detail/iocp/win_windows.hpp>
24   #ifndef AF_UNIX 26   #ifndef AF_UNIX
25   #define AF_UNIX 1 27   #define AF_UNIX 1
26   #endif 28   #endif
27   #endif 29   #endif
28   30  
29   namespace boost::corosio { 31   namespace boost::corosio {
30   32  
HITCBC 31   342 local_stream_socket::~local_stream_socket() 33   344 local_stream_socket::~local_stream_socket()
32   { 34   {
HITCBC 33   342 close(); 35   344 close();
HITCBC 34   342 } 36   344 }
35   37  
HITCBC 36   284 local_stream_socket::local_stream_socket(capy::execution_context& ctx) 38   286 local_stream_socket::local_stream_socket(capy::execution_context& ctx)
HITCBC 37 - 284 : io_object(create_handle<detail::local_stream_service>(ctx)) 39 + 286 : io_object(handle(
  40 + ctx,
  41 + detail::use_backend_service<
  42 + detail::local_stream_service_of,
HITGNC   43 + 572 detail::local_stream_service>(ctx)))
38   { 44   {
HITCBC 39   284 } 45   286 }
40   46  
41   std::error_code 47   std::error_code
HITCBC 42   51 local_stream_socket::open() noexcept 48   51 local_stream_socket::open() noexcept
43   { 49   {
HITCBC 44   51 if (is_open()) 50   51 if (is_open())
MISUBC 45   ✗ return {}; 51   ✗ return {};
HITCBC 46   51 return open_for_family(AF_UNIX, SOCK_STREAM, 0); 52   51 return open_for_family(AF_UNIX, SOCK_STREAM, 0);
47   } 53   }
48   54  
49   std::error_code 55   std::error_code
HITCBC 50   51 local_stream_socket::open_for_family( 56   51 local_stream_socket::open_for_family(
51   int family, int type, int protocol) noexcept 57   int family, int type, int protocol) noexcept
52   { 58   {
HITCBC 53   51 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 59   51 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 54   51 std::error_code ec = svc.open_socket( 60   51 std::error_code ec = svc.open_socket(
HITCBC 55   51 static_cast<local_stream_socket::implementation&>(*h_.get()), family, 61   51 static_cast<local_stream_socket::implementation&>(*h_.get()), family,
56   type, protocol); 62   type, protocol);
HITCBC 57   51 return ec; 63   51 return ec;
58   } 64   }
59   65  
60   void 66   void
HITCBC 61   355 local_stream_socket::close() noexcept 67   357 local_stream_socket::close() noexcept
62   { 68   {
HITCBC 63   355 if (!is_open()) 69   357 if (!is_open())
HITCBC 64   133 return; 70   135 return;
HITCBC 65   222 h_.service().close(h_); 71   222 h_.service().close(h_);
66   } 72   }
67   73  
68   void 74   void
HITCBC 69   8 local_stream_socket::cancel() noexcept 75   8 local_stream_socket::cancel() noexcept
70   { 76   {
HITCBC 71   8 if (!is_open()) 77   8 if (!is_open())
HITCBC 72   2 return; 78   2 return;
HITCBC 73   6 get().cancel(); 79   6 get().cancel();
74   } 80   }
75   81  
76   std::error_code 82   std::error_code
HITCBC 77   6 local_stream_socket::shutdown(shutdown_type what) noexcept 83   6 local_stream_socket::shutdown(shutdown_type what) noexcept
78   { 84   {
HITCBC 79   6 if (!is_open()) 85   6 if (!is_open())
HITCBC 80   2 return make_error_code(std::errc::bad_file_descriptor); 86   2 return make_error_code(std::errc::bad_file_descriptor);
HITCBC 81   4 return get().shutdown(what); 87   4 return get().shutdown(what);
82   } 88   }
83   89  
84   std::error_code 90   std::error_code
HITCBC 85   173 local_stream_socket::assign(native_handle_type fd) noexcept 91   173 local_stream_socket::assign(native_handle_type fd) noexcept
86   { 92   {
HITCBC 87   173 auto& svc = static_cast<detail::local_stream_service&>(h_.service()); 93   173 auto& svc = static_cast<detail::local_stream_service&>(h_.service());
HITCBC 88   173 std::error_code ec = svc.assign_socket( 94   173 std::error_code ec = svc.assign_socket(
HITCBC 89   173 static_cast<local_stream_socket::implementation&>(*h_.get()), fd); 95   173 static_cast<local_stream_socket::implementation&>(*h_.get()), fd);
HITCBC 90   173 return ec; 96   173 return ec;
91   } 97   }
92   98  
93   native_handle_type 99   native_handle_type
HITCBC 94   25 local_stream_socket::native_handle() const noexcept 100   25 local_stream_socket::native_handle() const noexcept
95   { 101   {
HITCBC 96   25 if (!is_open()) 102   25 if (!is_open())
97   #if BOOST_COROSIO_HAS_IOCP 103   #if BOOST_COROSIO_HAS_IOCP
98   return ~native_handle_type(0); 104   return ~native_handle_type(0);
99   #else 105   #else
HITCBC 100   2 return -1; 106   2 return -1;
101   #endif 107   #endif
HITCBC 102   23 return get().native_handle(); 108   23 return get().native_handle();
103   } 109   }
104   110  
105   native_handle_type 111   native_handle_type
HITCBC 106   6 local_stream_socket::release() 112   6 local_stream_socket::release()
107   { 113   {
HITCBC 108   6 if (!is_open()) 114   6 if (!is_open())
HITCBC 109   2 detail::throw_system_error( 115   2 detail::throw_system_error(
HITCBC 110   2 make_error_code(std::errc::bad_file_descriptor), 116   2 make_error_code(std::errc::bad_file_descriptor),
111   "local_stream_socket::release"); 117   "local_stream_socket::release");
HITCBC 112   4 return get().release_socket(); 118   4 return get().release_socket();
113   } 119   }
114   120  
115   std::size_t 121   std::size_t
HITCBC 116   11 local_stream_socket::available() const 122   11 local_stream_socket::available() const
117   { 123   {
HITCBC 118   11 if (!is_open()) 124   11 if (!is_open())
HITCBC 119   2 detail::throw_system_error( 125   2 detail::throw_system_error(
HITCBC 120   4 make_error_code(std::errc::bad_file_descriptor), 126   4 make_error_code(std::errc::bad_file_descriptor),
121   "local_stream_socket::available"); 127   "local_stream_socket::available");
122   #if BOOST_COROSIO_HAS_IOCP 128   #if BOOST_COROSIO_HAS_IOCP
123   u_long value = 0; 129   u_long value = 0;
124   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) != 130   if (::ioctlsocket(static_cast<SOCKET>(native_handle()), FIONREAD, &value) !=
125   0) 131   0)
126   detail::throw_system_error( 132   detail::throw_system_error(
127   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())), 133   detail::make_err(static_cast<unsigned long>(::WSAGetLastError())),
128   "local_stream_socket::available"); 134   "local_stream_socket::available");
129   return static_cast<std::size_t>(value); 135   return static_cast<std::size_t>(value);
130   #else 136   #else
HITCBC 131   9 int value = 0; 137   9 int value = 0;
HITCBC 132   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0) 138   9 if (::ioctl(native_handle(), FIONREAD, &value) < 0)
HITCBC 133   5 detail::throw_system_error( 139   5 detail::throw_system_error(
HITCBC 134   10 detail::make_err(errno), "local_stream_socket::available"); 140   10 detail::make_err(errno), "local_stream_socket::available");
HITCBC 135   4 return static_cast<std::size_t>(value); 141   4 return static_cast<std::size_t>(value);
136   #endif 142   #endif
137   } 143   }
138   144  
139   local_endpoint 145   local_endpoint
HITCBC 140   6 local_stream_socket::local_endpoint() const noexcept 146   6 local_stream_socket::local_endpoint() const noexcept
141   { 147   {
HITCBC 142   6 if (!is_open()) 148   6 if (!is_open())
HITCBC 143   2 return corosio::local_endpoint{}; 149   2 return corosio::local_endpoint{};
HITCBC 144   4 return get().local_endpoint(); 150   4 return get().local_endpoint();
145   } 151   }
146   152  
147   local_endpoint 153   local_endpoint
HITCBC 148   6 local_stream_socket::remote_endpoint() const noexcept 154   6 local_stream_socket::remote_endpoint() const noexcept
149   { 155   {
HITCBC 150   6 if (!is_open()) 156   6 if (!is_open())
HITCBC 151   2 return corosio::local_endpoint{}; 157   2 return corosio::local_endpoint{};
HITCBC 152   4 return get().remote_endpoint(); 158   4 return get().remote_endpoint();
153   } 159   }
154   160  
155   } // namespace boost::corosio 161   } // namespace boost::corosio
156   162  
157   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP 163   #endif // BOOST_COROSIO_POSIX || BOOST_COROSIO_HAS_IOCP