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