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