1 1.1 mrg // <experimental/socket> -*- C++ -*- 2 1.1 mrg 3 1.1.1.5 mrg // Copyright (C) 2015-2024 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file experimental/socket 26 1.1 mrg * This is a TS C++ Library header. 27 1.1.1.2 mrg * @ingroup networking-ts 28 1.1 mrg */ 29 1.1 mrg 30 1.1 mrg #ifndef _GLIBCXX_EXPERIMENTAL_SOCKET 31 1.1 mrg #define _GLIBCXX_EXPERIMENTAL_SOCKET 32 1.1 mrg 33 1.1 mrg #pragma GCC system_header 34 1.1 mrg 35 1.1.1.5 mrg #include <bits/requires_hosted.h> // experimental is currently omitted 36 1.1.1.5 mrg 37 1.1 mrg #if __cplusplus >= 201402L 38 1.1 mrg 39 1.1 mrg #include <experimental/netfwd> 40 1.1 mrg #include <experimental/buffer> 41 1.1 mrg #include <experimental/io_context> 42 1.1 mrg #include <experimental/bits/net.h> 43 1.1 mrg #include <streambuf> 44 1.1 mrg #include <istream> 45 1.1 mrg #include <bits/unique_ptr.h> 46 1.1 mrg #if _GLIBCXX_HAVE_UNISTD_H 47 1.1 mrg # include <unistd.h> 48 1.1 mrg # ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 49 1.1 mrg # include <sys/socket.h> // socket etc 50 1.1 mrg # endif 51 1.1 mrg # ifdef _GLIBCXX_HAVE_SYS_IOCTL_H 52 1.1 mrg # include <sys/ioctl.h> // ioctl 53 1.1 mrg # endif 54 1.1 mrg # ifdef _GLIBCXX_HAVE_SYS_UIO_H 55 1.1 mrg # include <sys/uio.h> // iovec 56 1.1 mrg # endif 57 1.1 mrg # ifdef _GLIBCXX_HAVE_POLL_H 58 1.1 mrg # include <poll.h> // poll, pollfd, POLLIN, POLLOUT, POLLERR 59 1.1 mrg # endif 60 1.1 mrg # ifdef _GLIBCXX_HAVE_FCNTL_H 61 1.1 mrg # include <fcntl.h> // fcntl, F_GETFL, F_SETFL 62 1.1 mrg # endif 63 1.1 mrg #endif 64 1.1 mrg 65 1.1 mrg namespace std _GLIBCXX_VISIBILITY(default) 66 1.1 mrg { 67 1.1 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 68 1.1 mrg namespace experimental 69 1.1 mrg { 70 1.1 mrg namespace net 71 1.1 mrg { 72 1.1 mrg inline namespace v1 73 1.1 mrg { 74 1.1 mrg 75 1.1.1.2 mrg /** @addtogroup networking-ts 76 1.1.1.2 mrg * @{ 77 1.1 mrg */ 78 1.1 mrg 79 1.1 mrg enum class socket_errc { // TODO decide values 80 1.1 mrg already_open = 3, 81 1.1 mrg not_found = 4 82 1.1 mrg }; 83 1.1 mrg 84 1.1.1.2 mrg } // namespace v1 85 1.1.1.2 mrg } // namespace net 86 1.1.1.2 mrg } // namespace experimental 87 1.1.1.2 mrg 88 1.1.1.2 mrg template<> 89 1.1.1.2 mrg struct is_error_code_enum<experimental::net::v1::socket_errc> 90 1.1.1.2 mrg : public true_type {}; 91 1.1.1.2 mrg 92 1.1.1.2 mrg namespace experimental 93 1.1.1.2 mrg { 94 1.1.1.2 mrg namespace net 95 1.1.1.2 mrg { 96 1.1.1.2 mrg inline namespace v1 97 1.1.1.2 mrg { 98 1.1 mrg const error_category& socket_category() noexcept 99 1.1 mrg { 100 1.1 mrg struct __cat : error_category 101 1.1 mrg { 102 1.1 mrg const char* name() const noexcept { return "socket"; } 103 1.1 mrg 104 1.1 mrg std::string message(int __e) const 105 1.1 mrg { 106 1.1 mrg if (__e == (int)socket_errc::already_open) 107 1.1 mrg return "already open"; 108 1.1 mrg else if (__e == (int)socket_errc::not_found) 109 1.1 mrg return "endpoint not found"; 110 1.1 mrg return "socket error"; 111 1.1 mrg } 112 1.1 mrg 113 1.1 mrg virtual void __message(int) { } // TODO dual ABI XXX 114 1.1 mrg }; 115 1.1 mrg static __cat __c; 116 1.1 mrg return __c; 117 1.1 mrg } 118 1.1 mrg 119 1.1 mrg inline error_code 120 1.1 mrg make_error_code(socket_errc __e) noexcept 121 1.1 mrg { return error_code(static_cast<int>(__e), socket_category()); } 122 1.1 mrg 123 1.1 mrg inline error_condition 124 1.1 mrg make_error_condition(socket_errc __e) noexcept 125 1.1 mrg { return error_condition(static_cast<int>(__e), socket_category()); } 126 1.1 mrg 127 1.1.1.4 mrg 128 1.1 mrg // TODO GettableSocket reqs 129 1.1 mrg // TODO SettableSocket reqs 130 1.1 mrg // TODO BooleanSocketOption reqs 131 1.1 mrg // TODO IntegerSocketOption reqs 132 1.1.1.2 mrg // TODO IoControlCommand reqs 133 1.1.1.2 mrg // TODO ConnectCondition reqs 134 1.1 mrg 135 1.1 mrg /** @brief Sockets 136 1.1 mrg * @{ 137 1.1 mrg */ 138 1.1 mrg 139 1.1 mrg class socket_base 140 1.1 mrg { 141 1.1 mrg public: 142 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 143 1.1.1.4 mrg class broadcast : public __sockopt_crtp<broadcast, bool> 144 1.1 mrg { 145 1.1.1.4 mrg public: 146 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 147 1.1.1.4 mrg using __sockopt_crtp::operator=; 148 1.1 mrg 149 1.1.1.4 mrg private: 150 1.1.1.4 mrg friend __sockopt_crtp<broadcast, bool>; 151 1.1 mrg static const int _S_level = SOL_SOCKET; 152 1.1 mrg static const int _S_name = SO_BROADCAST; 153 1.1 mrg }; 154 1.1 mrg 155 1.1.1.4 mrg class debug : public __sockopt_crtp<debug, bool> 156 1.1 mrg { 157 1.1.1.4 mrg public: 158 1.1.1.4 mrg friend __sockopt_crtp<debug, bool>; 159 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 160 1.1.1.4 mrg using __sockopt_crtp::operator=; 161 1.1 mrg 162 1.1.1.4 mrg private: 163 1.1 mrg static const int _S_level = SOL_SOCKET; 164 1.1 mrg static const int _S_name = SO_DEBUG; 165 1.1 mrg }; 166 1.1 mrg 167 1.1.1.4 mrg class do_not_route : public __sockopt_crtp<do_not_route, bool> 168 1.1 mrg { 169 1.1.1.4 mrg public: 170 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 171 1.1.1.4 mrg using __sockopt_crtp::operator=; 172 1.1 mrg 173 1.1.1.4 mrg private: 174 1.1.1.4 mrg friend __sockopt_crtp<do_not_route, bool>; 175 1.1 mrg static const int _S_level = SOL_SOCKET; 176 1.1 mrg static const int _S_name = SO_DONTROUTE; 177 1.1 mrg }; 178 1.1 mrg 179 1.1.1.4 mrg class keep_alive : public __sockopt_crtp<keep_alive, bool> 180 1.1 mrg { 181 1.1.1.4 mrg public: 182 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 183 1.1.1.4 mrg using __sockopt_crtp::operator=; 184 1.1 mrg 185 1.1.1.4 mrg private: 186 1.1.1.4 mrg friend __sockopt_crtp<keep_alive, bool>; 187 1.1 mrg static const int _S_level = SOL_SOCKET; 188 1.1 mrg static const int _S_name = SO_KEEPALIVE; 189 1.1 mrg }; 190 1.1 mrg 191 1.1.1.4 mrg class linger : public __sockopt_crtp<linger, ::linger> 192 1.1 mrg { 193 1.1.1.4 mrg public: 194 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 195 1.1.1.4 mrg using __sockopt_crtp::operator=; 196 1.1 mrg 197 1.1 mrg linger() noexcept = default; 198 1.1 mrg 199 1.1 mrg linger(bool __e, chrono::seconds __t) noexcept 200 1.1 mrg { 201 1.1 mrg enabled(__e); 202 1.1 mrg timeout(__t); 203 1.1 mrg } 204 1.1 mrg 205 1.1 mrg bool 206 1.1 mrg enabled() const noexcept 207 1.1 mrg { return _M_value.l_onoff != 0; } 208 1.1 mrg 209 1.1 mrg void 210 1.1 mrg enabled(bool __e) noexcept 211 1.1 mrg { _M_value.l_onoff = int(__e); } 212 1.1 mrg 213 1.1 mrg chrono::seconds 214 1.1 mrg timeout() const noexcept 215 1.1 mrg { return chrono::seconds(_M_value.l_linger); } 216 1.1 mrg 217 1.1 mrg void 218 1.1 mrg timeout(chrono::seconds __t) noexcept 219 1.1 mrg { _M_value.l_linger = __t.count(); } 220 1.1 mrg 221 1.1.1.4 mrg private: 222 1.1.1.4 mrg friend __sockopt_crtp<linger, ::linger>; 223 1.1 mrg static const int _S_level = SOL_SOCKET; 224 1.1 mrg static const int _S_name = SO_LINGER; 225 1.1 mrg }; 226 1.1 mrg 227 1.1.1.4 mrg class out_of_band_inline : public __sockopt_crtp<out_of_band_inline, bool> 228 1.1 mrg { 229 1.1.1.4 mrg public: 230 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 231 1.1.1.4 mrg using __sockopt_crtp::operator=; 232 1.1 mrg 233 1.1.1.4 mrg private: 234 1.1.1.4 mrg friend __sockopt_crtp<out_of_band_inline, bool>; 235 1.1 mrg static const int _S_level = SOL_SOCKET; 236 1.1 mrg static const int _S_name = SO_OOBINLINE; 237 1.1 mrg }; 238 1.1 mrg 239 1.1.1.4 mrg class receive_buffer_size : public __sockopt_crtp<receive_buffer_size> 240 1.1 mrg { 241 1.1.1.4 mrg public: 242 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 243 1.1.1.4 mrg using __sockopt_crtp::operator=; 244 1.1 mrg 245 1.1.1.4 mrg private: 246 1.1.1.4 mrg friend __sockopt_crtp<receive_buffer_size>; 247 1.1 mrg static const int _S_level = SOL_SOCKET; 248 1.1 mrg static const int _S_name = SO_RCVBUF; 249 1.1 mrg }; 250 1.1 mrg 251 1.1.1.4 mrg class receive_low_watermark : public __sockopt_crtp<receive_low_watermark> 252 1.1 mrg { 253 1.1.1.4 mrg public: 254 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 255 1.1.1.4 mrg using __sockopt_crtp::operator=; 256 1.1 mrg 257 1.1.1.4 mrg private: 258 1.1.1.4 mrg friend __sockopt_crtp<receive_low_watermark>; 259 1.1 mrg static const int _S_level = SOL_SOCKET; 260 1.1 mrg static const int _S_name = SO_RCVLOWAT; 261 1.1 mrg }; 262 1.1 mrg 263 1.1.1.4 mrg class reuse_address : public __sockopt_crtp<reuse_address, bool> 264 1.1 mrg { 265 1.1.1.4 mrg public: 266 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 267 1.1.1.4 mrg using __sockopt_crtp::operator=; 268 1.1 mrg 269 1.1.1.4 mrg private: 270 1.1.1.4 mrg friend __sockopt_crtp<reuse_address, bool>; 271 1.1 mrg static const int _S_level = SOL_SOCKET; 272 1.1 mrg static const int _S_name = SO_REUSEADDR; 273 1.1 mrg }; 274 1.1 mrg 275 1.1.1.4 mrg class send_buffer_size : public __sockopt_crtp<send_buffer_size> 276 1.1 mrg { 277 1.1.1.4 mrg public: 278 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 279 1.1.1.4 mrg using __sockopt_crtp::operator=; 280 1.1 mrg 281 1.1.1.4 mrg private: 282 1.1.1.4 mrg friend __sockopt_crtp<send_buffer_size>; 283 1.1 mrg static const int _S_level = SOL_SOCKET; 284 1.1 mrg static const int _S_name = SO_SNDBUF; 285 1.1 mrg }; 286 1.1 mrg 287 1.1.1.4 mrg class send_low_watermark : public __sockopt_crtp<send_low_watermark> 288 1.1 mrg { 289 1.1.1.4 mrg public: 290 1.1 mrg using __sockopt_crtp::__sockopt_crtp; 291 1.1.1.4 mrg using __sockopt_crtp::operator=; 292 1.1 mrg 293 1.1.1.4 mrg private: 294 1.1.1.4 mrg friend __sockopt_crtp<send_low_watermark>; 295 1.1 mrg static const int _S_level = SOL_SOCKET; 296 1.1 mrg static const int _S_name = SO_SNDLOWAT; 297 1.1 mrg }; 298 1.1.1.4 mrg #endif // HAVE_SYS_SOCKET_H 299 1.1 mrg 300 1.1.1.4 mrg enum shutdown_type : int { }; 301 1.1.1.4 mrg #if defined SHUT_RD && defined SHUT_WR && defined SHUT_RDWR 302 1.1.1.4 mrg static constexpr shutdown_type shutdown_receive = (shutdown_type)SHUT_RD; 303 1.1.1.4 mrg static constexpr shutdown_type shutdown_send = (shutdown_type)SHUT_WR; 304 1.1.1.4 mrg static constexpr shutdown_type shutdown_both = (shutdown_type)SHUT_RDWR; 305 1.1.1.4 mrg #endif 306 1.1 mrg 307 1.1.1.4 mrg enum wait_type : int { }; 308 1.1 mrg #ifdef _GLIBCXX_HAVE_POLL_H 309 1.1.1.4 mrg static constexpr wait_type wait_read = (wait_type)POLLIN; 310 1.1.1.4 mrg static constexpr wait_type wait_write = (wait_type)POLLOUT; 311 1.1.1.4 mrg static constexpr wait_type wait_error = (wait_type)POLLERR; 312 1.1.1.4 mrg #else 313 1.1.1.4 mrg static constexpr wait_type wait_read = (wait_type)1; 314 1.1.1.4 mrg static constexpr wait_type wait_write = (wait_type)2; 315 1.1.1.4 mrg static constexpr wait_type wait_error = (wait_type)4; 316 1.1 mrg #endif 317 1.1 mrg 318 1.1.1.4 mrg enum message_flags : int { }; 319 1.1.1.4 mrg #if defined MSG_PEEK && defined MSG_OOB && defined MSG_DONTROUTE 320 1.1.1.4 mrg static constexpr message_flags message_peek 321 1.1.1.4 mrg = (message_flags)MSG_PEEK; 322 1.1.1.4 mrg static constexpr message_flags message_out_of_band 323 1.1.1.4 mrg = (message_flags)MSG_OOB; 324 1.1.1.4 mrg static constexpr message_flags message_do_not_route 325 1.1.1.4 mrg = (message_flags)MSG_DONTROUTE; 326 1.1.1.4 mrg #endif 327 1.1 mrg 328 1.1.1.4 mrg #ifdef SOMAXCONN 329 1.1.1.4 mrg static constexpr int max_listen_connections = SOMAXCONN; 330 1.1.1.4 mrg #else 331 1.1.1.4 mrg static constexpr int max_listen_connections = 4; 332 1.1 mrg #endif 333 1.1 mrg 334 1.1.1.4 mrg // message_flags bitmask operations are defined as hidden friends. 335 1.1.1.4 mrg 336 1.1.1.4 mrg friend constexpr message_flags 337 1.1.1.4 mrg operator&(message_flags __f1, message_flags __f2) noexcept 338 1.1.1.4 mrg { return message_flags( int(__f1) & int(__f2) ); } 339 1.1.1.4 mrg 340 1.1.1.4 mrg friend constexpr message_flags 341 1.1.1.4 mrg operator|(message_flags __f1, message_flags __f2) noexcept 342 1.1.1.4 mrg { return message_flags( int(__f1) | int(__f2) ); } 343 1.1.1.4 mrg 344 1.1.1.4 mrg friend constexpr message_flags 345 1.1.1.4 mrg operator^(message_flags __f1, message_flags __f2) noexcept 346 1.1.1.4 mrg { return message_flags( int(__f1) ^ int(__f2) ); } 347 1.1.1.4 mrg 348 1.1.1.4 mrg friend constexpr message_flags 349 1.1.1.4 mrg operator~(message_flags __f) noexcept 350 1.1.1.4 mrg { return message_flags( ~int(__f) ); } 351 1.1.1.4 mrg 352 1.1.1.4 mrg friend constexpr message_flags& 353 1.1.1.4 mrg operator&=(message_flags& __f1, message_flags __f2) noexcept 354 1.1.1.4 mrg { return __f1 = (__f1 & __f2); } 355 1.1.1.4 mrg 356 1.1.1.4 mrg friend constexpr message_flags& 357 1.1.1.4 mrg operator|=(message_flags& __f1, message_flags __f2) noexcept 358 1.1.1.4 mrg { return __f1 = (__f1 | __f2); } 359 1.1.1.4 mrg 360 1.1.1.4 mrg friend constexpr message_flags& 361 1.1.1.4 mrg operator^=(message_flags& __f1, message_flags __f2) noexcept 362 1.1.1.4 mrg { return __f1 = (__f1 ^ __f2); } 363 1.1 mrg 364 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 365 1.1.1.4 mrg protected: 366 1.1 mrg struct __msg_hdr : ::msghdr 367 1.1 mrg { 368 1.1 mrg #ifdef IOV_MAX 369 1.1 mrg using __iovec_array = array<::iovec, IOV_MAX>; 370 1.1 mrg #elif _GLIBCXX_HAVE_UNISTD_H 371 1.1 mrg struct __iovec_array 372 1.1 mrg { 373 1.1 mrg __iovec_array() : _M_ptr(new ::iovec[size()]) { } 374 1.1 mrg 375 1.1 mrg ::iovec& operator[](size_t __n) noexcept { return _M_ptr[__n]; } 376 1.1 mrg 377 1.1 mrg ::iovec* data() noexcept { return _M_ptr.get(); } 378 1.1 mrg 379 1.1 mrg static size_t size() 380 1.1 mrg { 381 1.1 mrg static const size_t __iov_max = ::sysconf(_SC_IOV_MAX); 382 1.1 mrg return __iov_max; 383 1.1 mrg } 384 1.1 mrg 385 1.1 mrg private: 386 1.1 mrg unique_ptr<::iovec[]> _M_ptr; 387 1.1 mrg }; 388 1.1 mrg #else 389 1.1 mrg using __iovec_array = array<::iovec, 16>; 390 1.1 mrg #endif 391 1.1 mrg 392 1.1 mrg __iovec_array _M_iov; 393 1.1 mrg 394 1.1 mrg template<typename _BufferSequence> 395 1.1 mrg explicit 396 1.1 mrg __msg_hdr(const _BufferSequence& __buffers) 397 1.1 mrg : msghdr() 398 1.1 mrg { 399 1.1 mrg auto __buf = net::buffer_sequence_begin(__buffers); 400 1.1 mrg const auto __bufend = net::buffer_sequence_end(__buffers); 401 1.1 mrg size_t __len = 0; 402 1.1 mrg while (__buf != __bufend && __len != _M_iov.size()) 403 1.1 mrg { 404 1.1 mrg _M_iov[__len].iov_base = (void*)__buf->data(); 405 1.1 mrg _M_iov[__len].iov_len = __buf->size(); 406 1.1 mrg ++__buf; 407 1.1 mrg ++__len; 408 1.1 mrg } 409 1.1 mrg this->msg_iovlen = __len; 410 1.1 mrg this->msg_iov = _M_iov.data(); 411 1.1 mrg } 412 1.1 mrg 413 1.1 mrg template<typename _BufferSequence, typename _Endpoint> 414 1.1 mrg __msg_hdr(const _BufferSequence& __buffers, const _Endpoint& __ep) 415 1.1 mrg : __msg_hdr(__buffers) 416 1.1 mrg { 417 1.1 mrg this->msg_name = __ep.data(); 418 1.1 mrg this->msg_namelen = __ep.size(); 419 1.1 mrg } 420 1.1 mrg }; 421 1.1 mrg #endif 422 1.1.1.4 mrg 423 1.1.1.4 mrg protected: 424 1.1.1.4 mrg socket_base() = default; 425 1.1.1.4 mrg ~socket_base() = default; 426 1.1 mrg }; 427 1.1 mrg 428 1.1.1.4 mrg // TODO define socket_base static constants in .so for C++14 mode 429 1.1 mrg 430 1.1 mrg #if _GLIBCXX_HAVE_UNISTD_H 431 1.1 mrg 432 1.1 mrg class __socket_impl 433 1.1 mrg { 434 1.1 mrg protected: 435 1.1 mrg 436 1.1 mrg using executor_type = io_context::executor_type; 437 1.1 mrg using native_handle_type = int; 438 1.1 mrg 439 1.1 mrg explicit 440 1.1 mrg __socket_impl(io_context& __ctx) : _M_ctx(std::addressof(__ctx)) { } 441 1.1 mrg 442 1.1 mrg __socket_impl(__socket_impl&& __rhs) 443 1.1 mrg : _M_ctx(__rhs._M_ctx), 444 1.1.1.4 mrg _M_sockfd(std::__exchange(__rhs._M_sockfd, -1)), 445 1.1.1.4 mrg _M_bits(std::__exchange(__rhs._M_bits, {})) 446 1.1 mrg { } 447 1.1 mrg 448 1.1 mrg __socket_impl& 449 1.1 mrg operator=(__socket_impl&& __rhs) 450 1.1 mrg { 451 1.1 mrg _M_ctx = __rhs._M_ctx; 452 1.1.1.4 mrg _M_sockfd = std::__exchange(__rhs._M_sockfd, -1); 453 1.1.1.4 mrg _M_bits = std::__exchange(__rhs._M_bits, {}); 454 1.1 mrg return *this; 455 1.1 mrg } 456 1.1 mrg 457 1.1 mrg ~__socket_impl() = default; 458 1.1 mrg 459 1.1 mrg __socket_impl(const __socket_impl&) = delete; 460 1.1 mrg __socket_impl& operator=(const __socket_impl&) = delete; 461 1.1 mrg 462 1.1 mrg executor_type get_executor() noexcept { return _M_ctx->get_executor(); } 463 1.1 mrg 464 1.1 mrg native_handle_type native_handle() noexcept { return _M_sockfd; } 465 1.1 mrg 466 1.1 mrg bool is_open() const noexcept { return _M_sockfd != -1; } 467 1.1 mrg 468 1.1 mrg void 469 1.1 mrg close(error_code& __ec) 470 1.1 mrg { 471 1.1 mrg if (is_open()) 472 1.1 mrg { 473 1.1 mrg cancel(__ec); 474 1.1 mrg if (!__ec) 475 1.1 mrg { 476 1.1 mrg if (::close(_M_sockfd) == -1) 477 1.1 mrg __ec.assign(errno, generic_category()); 478 1.1 mrg else 479 1.1 mrg { 480 1.1 mrg get_executor().context()._M_remove_fd(_M_sockfd); 481 1.1 mrg _M_sockfd = -1; 482 1.1 mrg } 483 1.1 mrg } 484 1.1 mrg } 485 1.1 mrg } 486 1.1 mrg 487 1.1 mrg void cancel(error_code& __ec) { _M_ctx->cancel(_M_sockfd, __ec); } 488 1.1 mrg 489 1.1 mrg void 490 1.1 mrg non_blocking(bool __mode, error_code&) 491 1.1 mrg { _M_bits.non_blocking = __mode; } 492 1.1 mrg 493 1.1 mrg bool non_blocking() const { return _M_bits.non_blocking; } 494 1.1 mrg 495 1.1 mrg void 496 1.1.1.5 mrg native_non_blocking([[maybe_unused]] bool __mode, error_code& __ec) 497 1.1 mrg { 498 1.1.1.4 mrg #if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK 499 1.1 mrg int __flags = ::fcntl(_M_sockfd, F_GETFL, 0); 500 1.1 mrg if (__flags >= 0) 501 1.1 mrg { 502 1.1 mrg if (__mode) 503 1.1 mrg __flags |= O_NONBLOCK; 504 1.1 mrg else 505 1.1 mrg __flags &= ~O_NONBLOCK; 506 1.1 mrg __flags = ::fcntl(_M_sockfd, F_SETFL, __flags); 507 1.1 mrg } 508 1.1 mrg if (__flags == -1) 509 1.1 mrg __ec.assign(errno, generic_category()); 510 1.1 mrg else 511 1.1 mrg { 512 1.1 mrg __ec.clear(); 513 1.1 mrg _M_bits.native_non_blocking = __mode; 514 1.1 mrg } 515 1.1 mrg #else 516 1.1 mrg __ec = std::make_error_code(std::errc::not_supported); 517 1.1 mrg #endif 518 1.1 mrg } 519 1.1 mrg 520 1.1 mrg bool 521 1.1 mrg native_non_blocking() const 522 1.1 mrg { 523 1.1.1.4 mrg #if defined _GLIBCXX_HAVE_FCNTL_H && defined _GLIBCXX_HAVE_DECL_O_NONBLOCK 524 1.1 mrg if (_M_bits.native_non_blocking == -1) 525 1.1 mrg { 526 1.1 mrg const int __flags = ::fcntl(_M_sockfd, F_GETFL, 0); 527 1.1 mrg if (__flags == -1) 528 1.1 mrg return 0; 529 1.1 mrg _M_bits.native_non_blocking = __flags & O_NONBLOCK; 530 1.1 mrg } 531 1.1 mrg return _M_bits.native_non_blocking; 532 1.1 mrg #else 533 1.1 mrg return false; 534 1.1 mrg #endif 535 1.1 mrg } 536 1.1 mrg 537 1.1 mrg io_context* _M_ctx; 538 1.1 mrg int _M_sockfd{-1}; 539 1.1 mrg struct { 540 1.1 mrg unsigned non_blocking : 1; 541 1.1 mrg mutable signed native_non_blocking : 2; 542 1.1 mrg unsigned enable_connection_aborted : 1; 543 1.1 mrg } _M_bits{}; 544 1.1 mrg }; 545 1.1 mrg 546 1.1 mrg template<typename _Protocol> 547 1.1 mrg class __basic_socket_impl : public __socket_impl 548 1.1 mrg { 549 1.1 mrg using __base = __socket_impl; 550 1.1 mrg 551 1.1 mrg protected: 552 1.1 mrg using protocol_type = _Protocol; 553 1.1 mrg using endpoint_type = typename protocol_type::endpoint; 554 1.1 mrg 555 1.1 mrg explicit 556 1.1 mrg __basic_socket_impl(io_context& __ctx) : __base(__ctx) { } 557 1.1 mrg 558 1.1 mrg __basic_socket_impl(__basic_socket_impl&&) = default; 559 1.1 mrg 560 1.1 mrg template<typename _OtherProtocol> 561 1.1 mrg __basic_socket_impl(__basic_socket_impl<_OtherProtocol>&& __rhs) 562 1.1 mrg : __base(std::move(__rhs)), _M_protocol(std::move(__rhs._M_protocol)) 563 1.1 mrg { } 564 1.1 mrg 565 1.1 mrg __basic_socket_impl& 566 1.1 mrg operator=(__basic_socket_impl&& __rhs) 567 1.1 mrg { 568 1.1 mrg if (this == std::addressof(__rhs)) 569 1.1 mrg return *this; 570 1.1 mrg _M_close(); 571 1.1 mrg __base::operator=(std::move(__rhs)); 572 1.1 mrg return *this; 573 1.1 mrg } 574 1.1 mrg 575 1.1 mrg ~__basic_socket_impl() { _M_close(); } 576 1.1 mrg 577 1.1 mrg __basic_socket_impl(const __basic_socket_impl&) = delete; 578 1.1 mrg __basic_socket_impl& operator=(const __basic_socket_impl&) = delete; 579 1.1 mrg 580 1.1 mrg void 581 1.1 mrg open(const protocol_type& __protocol, error_code& __ec) 582 1.1 mrg { 583 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 584 1.1 mrg if (is_open()) 585 1.1 mrg __ec = socket_errc::already_open; 586 1.1 mrg else 587 1.1 mrg { 588 1.1 mrg _M_protocol = __protocol; 589 1.1 mrg _M_sockfd = ::socket(__protocol.family(), __protocol.type(), 590 1.1 mrg __protocol.protocol()); 591 1.1 mrg if (is_open()) 592 1.1 mrg { 593 1.1 mrg get_executor().context()._M_add_fd(_M_sockfd); 594 1.1 mrg __ec.clear(); 595 1.1 mrg } 596 1.1 mrg else 597 1.1 mrg __ec.assign(errno, std::generic_category()); 598 1.1 mrg } 599 1.1 mrg #else 600 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 601 1.1 mrg #endif 602 1.1 mrg } 603 1.1 mrg 604 1.1 mrg void 605 1.1 mrg assign(const protocol_type& __protocol, 606 1.1 mrg const native_handle_type& __native_socket, 607 1.1 mrg error_code& __ec) 608 1.1 mrg { 609 1.1 mrg if (is_open()) 610 1.1 mrg __ec = socket_errc::already_open; 611 1.1 mrg else 612 1.1 mrg { 613 1.1 mrg _M_protocol = __protocol; 614 1.1 mrg _M_bits.native_non_blocking = -1; 615 1.1 mrg _M_sockfd = __native_socket; 616 1.1 mrg if (is_open()) 617 1.1 mrg { 618 1.1 mrg get_executor().context()._M_add_fd(_M_sockfd); 619 1.1 mrg __ec.clear(); 620 1.1 mrg } 621 1.1 mrg else 622 1.1 mrg __ec.assign(errno, std::generic_category()); 623 1.1 mrg } 624 1.1 mrg } 625 1.1 mrg 626 1.1.1.2 mrg native_handle_type release(error_code& __ec) 627 1.1.1.2 mrg { 628 1.1.1.2 mrg __glibcxx_assert(is_open()); 629 1.1.1.2 mrg cancel(__ec); 630 1.1.1.4 mrg return std::__exchange(_M_sockfd, -1); 631 1.1.1.2 mrg } 632 1.1.1.2 mrg 633 1.1 mrg template<typename _SettableSocketOption> 634 1.1 mrg void 635 1.1 mrg set_option(const _SettableSocketOption& __option, error_code& __ec) 636 1.1 mrg { 637 1.1.1.4 mrg # ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 638 1.1 mrg int __result = ::setsockopt(_M_sockfd, __option.level(_M_protocol), 639 1.1 mrg __option.name(_M_protocol), 640 1.1 mrg __option.data(_M_protocol), 641 1.1 mrg __option.size(_M_protocol)); 642 1.1 mrg if (__result == -1) 643 1.1 mrg __ec.assign(errno, generic_category()); 644 1.1 mrg else 645 1.1 mrg __ec.clear(); 646 1.1.1.4 mrg #else 647 1.1.1.4 mrg __ec = std::make_error_code(std::errc::not_supported); 648 1.1.1.4 mrg #endif 649 1.1 mrg } 650 1.1 mrg 651 1.1 mrg template<typename _GettableSocketOption> 652 1.1 mrg void 653 1.1 mrg get_option(_GettableSocketOption& __option, error_code& __ec) const 654 1.1 mrg { 655 1.1.1.4 mrg # ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 656 1.1 mrg int __result = ::getsockopt(_M_sockfd, __option.level(_M_protocol), 657 1.1 mrg __option.name(_M_protocol), 658 1.1 mrg __option.data(_M_protocol), 659 1.1 mrg __option.size(_M_protocol)); 660 1.1 mrg if (__result == -1) 661 1.1 mrg __ec.assign(errno, generic_category()); 662 1.1 mrg else 663 1.1 mrg __ec.clear(); 664 1.1.1.4 mrg #else 665 1.1.1.4 mrg __ec = std::make_error_code(std::errc::not_supported); 666 1.1.1.4 mrg #endif 667 1.1 mrg } 668 1.1 mrg 669 1.1 mrg template<typename _IoControlCommand> 670 1.1 mrg void 671 1.1 mrg io_control(_IoControlCommand& __command, error_code& __ec) 672 1.1 mrg { 673 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_IOCTL_H 674 1.1 mrg int __result = ::ioctl(_M_sockfd, __command.name(), 675 1.1 mrg __command.data()); 676 1.1 mrg if (__result == -1) 677 1.1 mrg __ec.assign(errno, generic_category()); 678 1.1 mrg else 679 1.1 mrg __ec.clear(); 680 1.1 mrg #else 681 1.1 mrg __ec = std::make_error_code(std::errc::not_supported); 682 1.1 mrg #endif 683 1.1 mrg } 684 1.1 mrg 685 1.1 mrg endpoint_type 686 1.1 mrg local_endpoint(error_code& __ec) const 687 1.1 mrg { 688 1.1 mrg endpoint_type __endpoint; 689 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 690 1.1 mrg socklen_t __endpoint_len = __endpoint.capacity(); 691 1.1 mrg if (::getsockname(_M_sockfd, (sockaddr*)__endpoint.data(), 692 1.1.1.2 mrg &__endpoint_len) == -1) 693 1.1 mrg { 694 1.1 mrg __ec.assign(errno, generic_category()); 695 1.1 mrg return endpoint_type{}; 696 1.1 mrg } 697 1.1 mrg __ec.clear(); 698 1.1 mrg __endpoint.resize(__endpoint_len); 699 1.1 mrg #else 700 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 701 1.1 mrg #endif 702 1.1 mrg return __endpoint; 703 1.1 mrg } 704 1.1 mrg 705 1.1 mrg void 706 1.1 mrg bind(const endpoint_type& __endpoint, error_code& __ec) 707 1.1 mrg { 708 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 709 1.1 mrg if (::bind(_M_sockfd, (sockaddr*)__endpoint.data(), __endpoint.size()) 710 1.1 mrg == -1) 711 1.1 mrg __ec.assign(errno, generic_category()); 712 1.1 mrg else 713 1.1 mrg __ec.clear(); 714 1.1 mrg #else 715 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 716 1.1 mrg #endif 717 1.1 mrg } 718 1.1 mrg 719 1.1 mrg _Protocol _M_protocol{ endpoint_type{}.protocol() }; 720 1.1 mrg 721 1.1 mrg private: 722 1.1 mrg void 723 1.1 mrg _M_close() 724 1.1 mrg { 725 1.1 mrg if (is_open()) 726 1.1 mrg { 727 1.1 mrg error_code __ec; 728 1.1 mrg cancel(__ec); 729 1.1.1.4 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 730 1.1 mrg set_option(socket_base::linger{false, chrono::seconds{}}, __ec); 731 1.1.1.4 mrg #endif 732 1.1 mrg ::close(_M_sockfd); 733 1.1 mrg } 734 1.1 mrg } 735 1.1 mrg }; 736 1.1 mrg 737 1.1 mrg template<typename _Protocol> 738 1.1 mrg class basic_socket 739 1.1 mrg : public socket_base, private __basic_socket_impl<_Protocol> 740 1.1 mrg { 741 1.1 mrg using __base = __basic_socket_impl<_Protocol>; 742 1.1 mrg 743 1.1 mrg public: 744 1.1 mrg // types: 745 1.1 mrg 746 1.1.1.4 mrg using executor_type = io_context::executor_type; 747 1.1.1.4 mrg using native_handle_type = int; 748 1.1.1.4 mrg using protocol_type = _Protocol; 749 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 750 1.1.1.4 mrg 751 1.1.1.4 mrg static_assert(__detail::__protocol<protocol_type>, 752 1.1.1.4 mrg "protocol_type meets the Protocol requirements"); 753 1.1 mrg 754 1.1 mrg // basic_socket operations: 755 1.1 mrg 756 1.1 mrg executor_type get_executor() noexcept { return __base::get_executor(); } 757 1.1 mrg 758 1.1 mrg native_handle_type 759 1.1 mrg native_handle() noexcept { return __base::native_handle(); } 760 1.1 mrg 761 1.1 mrg void 762 1.1 mrg open(const protocol_type& __protocol = protocol_type()) 763 1.1 mrg { open(__protocol, __throw_on_error{"basic_socket::open"}); } 764 1.1 mrg 765 1.1 mrg void 766 1.1 mrg open(const protocol_type& __protocol, error_code& __ec) 767 1.1 mrg { __base::open(__protocol, __ec); } 768 1.1 mrg 769 1.1 mrg void 770 1.1 mrg assign(const protocol_type& __protocol, 771 1.1 mrg const native_handle_type& __native_socket) 772 1.1 mrg { 773 1.1 mrg assign(__protocol, __native_socket, 774 1.1 mrg __throw_on_error{"basic_socket::assign"}); 775 1.1 mrg } 776 1.1 mrg 777 1.1 mrg void 778 1.1 mrg assign(const protocol_type& __protocol, 779 1.1 mrg const native_handle_type& __native_socket, 780 1.1 mrg error_code& __ec) 781 1.1 mrg { __base::assign(__protocol, __native_socket, __ec); } 782 1.1 mrg 783 1.1.1.2 mrg native_handle_type release() 784 1.1.1.2 mrg { return release(__throw_on_error{"basic_socket::release"}); } 785 1.1.1.2 mrg 786 1.1.1.2 mrg native_handle_type release(error_code& __ec) 787 1.1.1.2 mrg { return __base::release(__ec); } 788 1.1.1.2 mrg 789 1.1.1.2 mrg _GLIBCXX_NODISCARD bool 790 1.1.1.2 mrg is_open() const noexcept { return __base::is_open(); } 791 1.1 mrg 792 1.1 mrg void close() { close(__throw_on_error{"basic_socket::close"}); } 793 1.1 mrg 794 1.1.1.2 mrg void close(error_code& __ec) { __base::close(__ec); } 795 1.1 mrg 796 1.1 mrg void cancel() { cancel(__throw_on_error{"basic_socket::cancel"}); } 797 1.1 mrg 798 1.1 mrg void cancel(error_code& __ec) { __base::cancel(__ec); } 799 1.1 mrg 800 1.1 mrg template<typename _SettableSocketOption> 801 1.1 mrg void 802 1.1 mrg set_option(const _SettableSocketOption& __option) 803 1.1 mrg { set_option(__option, __throw_on_error{"basic_socket::set_option"}); } 804 1.1 mrg 805 1.1 mrg template<typename _SettableSocketOption> 806 1.1 mrg void 807 1.1 mrg set_option(const _SettableSocketOption& __option, error_code& __ec) 808 1.1 mrg { __base::set_option(__option, __ec); } 809 1.1 mrg 810 1.1 mrg template<typename _GettableSocketOption> 811 1.1 mrg void 812 1.1 mrg get_option(_GettableSocketOption& __option) const 813 1.1 mrg { get_option(__option, __throw_on_error{"basic_socket::get_option"}); } 814 1.1 mrg 815 1.1 mrg template<typename _GettableSocketOption> 816 1.1 mrg void 817 1.1 mrg get_option(_GettableSocketOption& __option, error_code& __ec) const 818 1.1 mrg { __base::get_option(__option, __ec); } 819 1.1 mrg 820 1.1 mrg template<typename _IoControlCommand> 821 1.1 mrg void 822 1.1 mrg io_control(_IoControlCommand& __command) 823 1.1 mrg { 824 1.1 mrg io_control(__command, __throw_on_error{"basic_socket::io_control"}); 825 1.1 mrg } 826 1.1 mrg 827 1.1 mrg template<typename _IoControlCommand> 828 1.1 mrg void 829 1.1 mrg io_control(_IoControlCommand& __command, error_code& __ec) 830 1.1 mrg { __base::io_control(__command, __ec); } 831 1.1 mrg 832 1.1 mrg void 833 1.1 mrg non_blocking(bool __mode) 834 1.1 mrg { non_blocking(__mode, __throw_on_error{"basic_socket::non_blocking"}); } 835 1.1 mrg 836 1.1 mrg void 837 1.1 mrg non_blocking(bool __mode, error_code& __ec) 838 1.1 mrg { __base::non_blocking(__mode, __ec); } 839 1.1 mrg 840 1.1 mrg bool non_blocking() const { return __base::non_blocking(); } 841 1.1 mrg 842 1.1 mrg void 843 1.1 mrg native_non_blocking(bool __mode) 844 1.1 mrg { 845 1.1 mrg native_non_blocking(__mode, __throw_on_error{ 846 1.1 mrg "basic_socket::native_non_blocking"}); 847 1.1 mrg } 848 1.1 mrg 849 1.1 mrg void 850 1.1 mrg native_non_blocking(bool __mode, error_code& __ec) 851 1.1 mrg { __base::native_non_blocking(__mode, __ec); } 852 1.1 mrg 853 1.1 mrg bool 854 1.1 mrg native_non_blocking() const 855 1.1 mrg { return __base::native_non_blocking(); } 856 1.1 mrg 857 1.1 mrg bool at_mark() const 858 1.1 mrg { return at_mark(__throw_on_error{"basic_socket::at_mark"}); } 859 1.1 mrg 860 1.1 mrg bool 861 1.1 mrg at_mark(error_code& __ec) const 862 1.1 mrg { 863 1.1 mrg #ifdef _GLIBCXX_HAVE_SOCKATMARK 864 1.1 mrg const int __result = ::sockatmark(native_handle()); 865 1.1 mrg if (__result == -1) 866 1.1 mrg { 867 1.1 mrg __ec.assign(errno, generic_category()); 868 1.1 mrg return false; 869 1.1 mrg } 870 1.1 mrg __ec.clear(); 871 1.1 mrg return (bool)__result; 872 1.1 mrg #else 873 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 874 1.1 mrg return false; 875 1.1 mrg #endif 876 1.1 mrg } 877 1.1 mrg 878 1.1 mrg size_t 879 1.1 mrg available() const 880 1.1 mrg { return available(__throw_on_error{"basic_socket::available"}); } 881 1.1 mrg 882 1.1 mrg size_t 883 1.1 mrg available(error_code& __ec) const 884 1.1 mrg { 885 1.1 mrg if (!is_open()) 886 1.1 mrg { 887 1.1 mrg __ec = std::make_error_code(errc::bad_file_descriptor); 888 1.1 mrg return 0; 889 1.1 mrg } 890 1.1 mrg #if defined _GLIBCXX_HAVE_SYS_IOCTL_H && defined FIONREAD 891 1.1 mrg int __avail = 0; 892 1.1 mrg if (::ioctl(this->_M_sockfd, FIONREAD, &__avail) == -1) 893 1.1 mrg { 894 1.1 mrg __ec.assign(errno, generic_category()); 895 1.1 mrg return 0; 896 1.1 mrg } 897 1.1 mrg __ec.clear(); 898 1.1 mrg return __avail; 899 1.1 mrg #else 900 1.1 mrg return 0; 901 1.1 mrg #endif 902 1.1 mrg } 903 1.1 mrg 904 1.1 mrg void 905 1.1 mrg bind(const endpoint_type& __endpoint) 906 1.1 mrg { return bind(__endpoint, __throw_on_error{"basic_socket::bind"}); } 907 1.1 mrg 908 1.1 mrg void 909 1.1 mrg bind(const endpoint_type& __endpoint, error_code& __ec) 910 1.1 mrg { __base::bind(__endpoint, __ec); } 911 1.1 mrg 912 1.1 mrg void shutdown(shutdown_type __what) 913 1.1 mrg { return shutdown(__what, __throw_on_error{"basic_socket::shutdown"}); } 914 1.1 mrg 915 1.1 mrg void 916 1.1 mrg shutdown(shutdown_type __what, error_code& __ec) 917 1.1 mrg { 918 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 919 1.1 mrg if (::shutdown(native_handle(), static_cast<int>(__what)) == -1) 920 1.1 mrg __ec.assign(errno, generic_category()); 921 1.1 mrg else 922 1.1 mrg __ec.clear(); 923 1.1 mrg #else 924 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 925 1.1 mrg #endif 926 1.1 mrg } 927 1.1 mrg 928 1.1 mrg endpoint_type 929 1.1 mrg local_endpoint() const 930 1.1 mrg { 931 1.1 mrg return local_endpoint( 932 1.1 mrg __throw_on_error{"basic_socket::local_endpoint"}); 933 1.1 mrg } 934 1.1 mrg 935 1.1 mrg endpoint_type 936 1.1 mrg local_endpoint(error_code& __ec) const 937 1.1 mrg { return __base::local_endpoint(__ec); } 938 1.1 mrg 939 1.1 mrg endpoint_type 940 1.1 mrg remote_endpoint() const 941 1.1 mrg { 942 1.1 mrg return remote_endpoint( 943 1.1 mrg __throw_on_error{"basic_socket::remote_endpoint"}); 944 1.1 mrg } 945 1.1 mrg 946 1.1 mrg endpoint_type 947 1.1 mrg remote_endpoint(error_code& __ec) const 948 1.1 mrg { 949 1.1 mrg endpoint_type __endpoint; 950 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 951 1.1 mrg socklen_t __endpoint_len = __endpoint.capacity(); 952 1.1 mrg if (::getpeername(this->_M_sockfd, (sockaddr*)__endpoint.data(), 953 1.1.1.2 mrg &__endpoint_len) 954 1.1 mrg == -1) 955 1.1 mrg { 956 1.1 mrg __ec.assign(errno, generic_category()); 957 1.1 mrg return endpoint_type{}; 958 1.1 mrg } 959 1.1 mrg __ec.clear(); 960 1.1 mrg __endpoint.resize(__endpoint_len); 961 1.1 mrg #else 962 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 963 1.1 mrg #endif 964 1.1 mrg return __endpoint; 965 1.1 mrg } 966 1.1 mrg 967 1.1 mrg void 968 1.1 mrg connect(const endpoint_type& __endpoint) 969 1.1 mrg { 970 1.1 mrg return connect(__endpoint, __throw_on_error{"basic_socket::connect"}); 971 1.1 mrg } 972 1.1 mrg 973 1.1 mrg void 974 1.1 mrg connect(const endpoint_type& __endpoint, error_code& __ec) 975 1.1 mrg { 976 1.1.1.2 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 977 1.1 mrg if (!is_open()) 978 1.1 mrg { 979 1.1 mrg open(__endpoint.protocol(), __ec); 980 1.1 mrg if (__ec) 981 1.1 mrg return; 982 1.1 mrg } 983 1.1 mrg if (::connect(native_handle(), (const sockaddr*)__endpoint.data(), 984 1.1 mrg __endpoint.size()) == -1) 985 1.1 mrg __ec.assign(errno, generic_category()); 986 1.1 mrg else 987 1.1 mrg __ec.clear(); 988 1.1 mrg #else 989 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 990 1.1 mrg #endif 991 1.1 mrg } 992 1.1 mrg 993 1.1 mrg template<typename _CompletionToken> 994 1.1 mrg __deduced_t<_CompletionToken, void(error_code)> 995 1.1 mrg async_connect(const endpoint_type& __endpoint, 996 1.1 mrg _CompletionToken&& __token) 997 1.1 mrg { 998 1.1 mrg async_completion<_CompletionToken, void(error_code)> __init{__token}; 999 1.1 mrg 1000 1.1 mrg if (!is_open()) 1001 1.1 mrg { 1002 1.1 mrg error_code __ec; 1003 1.1 mrg open(__endpoint.protocol(), __ec); 1004 1.1 mrg if (__ec) 1005 1.1 mrg { 1006 1.1 mrg auto __ex = net::get_associated_executor( 1007 1.1 mrg __init.completion_handler, get_executor()); 1008 1.1 mrg auto __a = get_associated_allocator( 1009 1.1 mrg __init.completion_handler, std::allocator<void>()); 1010 1.1 mrg __ex.post( 1011 1.1.1.2 mrg [__h = std::move(__init.completion_handler), __ec] 1012 1.1 mrg () mutable 1013 1.1 mrg { __h(__ec); }, __a); 1014 1.1 mrg return __init.result.get(); 1015 1.1 mrg } 1016 1.1 mrg } 1017 1.1 mrg 1018 1.1 mrg get_executor().context().async_wait( native_handle(), 1019 1.1.1.4 mrg (int) socket_base::wait_read, 1020 1.1 mrg [__h = std::move(__init.completion_handler), 1021 1.1 mrg __ep = std::move(__endpoint), 1022 1.1 mrg __fd = native_handle()] 1023 1.1 mrg (error_code __ec) mutable { 1024 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1025 1.1 mrg if (!__ec && ::connect(__fd, (const sockaddr*)__ep.data(), 1026 1.1 mrg __ep.size()) == -1) 1027 1.1 mrg __ec.assign(errno, generic_category()); 1028 1.1 mrg #else 1029 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1030 1.1 mrg #endif 1031 1.1 mrg __h(__ec); 1032 1.1 mrg }); 1033 1.1 mrg return __init.result.get(); 1034 1.1 mrg } 1035 1.1 mrg 1036 1.1 mrg void 1037 1.1 mrg wait(wait_type __w) 1038 1.1 mrg { return wait(__w, __throw_on_error{"basic_socket::wait"}); } 1039 1.1 mrg 1040 1.1 mrg void 1041 1.1 mrg wait(wait_type __w, error_code& __ec) 1042 1.1 mrg { 1043 1.1 mrg #ifdef _GLIBCXX_HAVE_POLL_H 1044 1.1 mrg ::pollfd __fd; 1045 1.1 mrg __fd.fd = native_handle(); 1046 1.1 mrg __fd.events = static_cast<int>(__w); 1047 1.1 mrg int __res = ::poll(&__fd, 1, -1); 1048 1.1 mrg if (__res == -1) 1049 1.1 mrg __ec.assign(errno, generic_category()); 1050 1.1 mrg else 1051 1.1 mrg __ec.clear(); 1052 1.1 mrg #else 1053 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1054 1.1 mrg #endif 1055 1.1 mrg } 1056 1.1 mrg 1057 1.1 mrg template<typename _CompletionToken> 1058 1.1 mrg __deduced_t<_CompletionToken, void(error_code)> 1059 1.1 mrg async_wait(wait_type __w, _CompletionToken&& __token) 1060 1.1 mrg { 1061 1.1 mrg async_completion<_CompletionToken, void(error_code)> __init{__token}; 1062 1.1 mrg get_executor().context().async_wait( native_handle(), 1063 1.1 mrg static_cast<int>(__w), 1064 1.1 mrg [__h = std::move(__init.completion_handler)] 1065 1.1 mrg (error_code __ec) mutable { 1066 1.1 mrg __h(__ec); 1067 1.1 mrg }); 1068 1.1 mrg return __init.result.get(); 1069 1.1 mrg } 1070 1.1 mrg 1071 1.1 mrg protected: 1072 1.1 mrg // construct / copy / destroy: 1073 1.1 mrg 1074 1.1 mrg using __base::__base; 1075 1.1 mrg 1076 1.1 mrg explicit 1077 1.1 mrg basic_socket(io_context& __ctx) : __base(__ctx) { } 1078 1.1 mrg 1079 1.1 mrg basic_socket(io_context& __ctx, const protocol_type& __protocol) 1080 1.1 mrg : __base(__ctx) 1081 1.1 mrg { open(__protocol); } 1082 1.1 mrg 1083 1.1 mrg basic_socket(io_context& __ctx, const endpoint_type& __endpoint) 1084 1.1.1.2 mrg : basic_socket(__ctx, __endpoint.protocol()) 1085 1.1 mrg { bind(__endpoint); } 1086 1.1 mrg 1087 1.1 mrg basic_socket(io_context& __ctx, const protocol_type& __protocol, 1088 1.1 mrg const native_handle_type& __native_socket) 1089 1.1 mrg : __base(__ctx) 1090 1.1 mrg { assign(__protocol, __native_socket); } 1091 1.1 mrg 1092 1.1 mrg basic_socket(const basic_socket&) = delete; 1093 1.1 mrg 1094 1.1 mrg basic_socket(basic_socket&& __rhs) = default; 1095 1.1 mrg 1096 1.1 mrg template<typename _OtherProtocol, typename _Requires 1097 1.1 mrg = _Require<is_convertible<_OtherProtocol, _Protocol>>> 1098 1.1 mrg basic_socket(basic_socket<_OtherProtocol>&& __rhs) 1099 1.1 mrg : __base(std::move(__rhs)) { } 1100 1.1 mrg 1101 1.1 mrg ~basic_socket() = default; 1102 1.1 mrg 1103 1.1 mrg basic_socket& operator=(const basic_socket&) = delete; 1104 1.1 mrg 1105 1.1 mrg basic_socket& operator=(basic_socket&& __rhs) = default; 1106 1.1 mrg 1107 1.1 mrg template<typename _OtherProtocol> 1108 1.1 mrg enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, 1109 1.1 mrg basic_socket&> 1110 1.1 mrg operator=(basic_socket<_OtherProtocol>&& __rhs) 1111 1.1 mrg { return *this = basic_socket{std::move(__rhs)}; } 1112 1.1 mrg }; 1113 1.1 mrg 1114 1.1 mrg template<typename _Protocol> 1115 1.1 mrg class basic_datagram_socket : public basic_socket<_Protocol> 1116 1.1 mrg { 1117 1.1 mrg using __base = basic_socket<_Protocol>; 1118 1.1 mrg 1119 1.1 mrg public: 1120 1.1 mrg // types: 1121 1.1 mrg 1122 1.1.1.4 mrg using native_handle_type = int; 1123 1.1.1.4 mrg using protocol_type = _Protocol; 1124 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 1125 1.1 mrg 1126 1.1 mrg // construct / copy / destroy: 1127 1.1 mrg 1128 1.1 mrg explicit 1129 1.1 mrg basic_datagram_socket(io_context& __ctx) : __base(__ctx) { } 1130 1.1 mrg 1131 1.1 mrg basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol) 1132 1.1 mrg : __base(__ctx, __protocol) { } 1133 1.1 mrg 1134 1.1 mrg basic_datagram_socket(io_context& __ctx, const endpoint_type& __endpoint) 1135 1.1 mrg : __base(__ctx, __endpoint) { } 1136 1.1 mrg 1137 1.1 mrg basic_datagram_socket(io_context& __ctx, const protocol_type& __protocol, 1138 1.1 mrg const native_handle_type& __native_socket) 1139 1.1 mrg : __base(__ctx, __protocol, __native_socket) { } 1140 1.1 mrg 1141 1.1 mrg basic_datagram_socket(const basic_datagram_socket&) = delete; 1142 1.1 mrg 1143 1.1 mrg basic_datagram_socket(basic_datagram_socket&& __rhs) = default; 1144 1.1 mrg 1145 1.1 mrg template<typename _OtherProtocol, typename _Requires 1146 1.1 mrg = _Require<is_convertible<_OtherProtocol, _Protocol>>> 1147 1.1 mrg basic_datagram_socket(basic_datagram_socket<_OtherProtocol>&& __rhs) 1148 1.1 mrg : __base(std::move(__rhs)) { } 1149 1.1 mrg 1150 1.1 mrg ~basic_datagram_socket() = default; 1151 1.1 mrg 1152 1.1 mrg basic_datagram_socket& operator=(const basic_datagram_socket&) = delete; 1153 1.1 mrg 1154 1.1 mrg basic_datagram_socket& operator=(basic_datagram_socket&& __rhs) = default; 1155 1.1 mrg 1156 1.1 mrg template<typename _OtherProtocol> 1157 1.1 mrg enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, 1158 1.1 mrg basic_datagram_socket&> 1159 1.1 mrg operator=(basic_datagram_socket<_OtherProtocol>&& __rhs) 1160 1.1 mrg { 1161 1.1 mrg __base::operator=(std::move(__rhs)); 1162 1.1 mrg return *this; 1163 1.1 mrg } 1164 1.1 mrg 1165 1.1 mrg // basic_datagram_socket operations: 1166 1.1 mrg 1167 1.1 mrg template<typename _MutableBufferSequence> 1168 1.1 mrg size_t 1169 1.1 mrg receive(const _MutableBufferSequence& __buffers) 1170 1.1 mrg { 1171 1.1 mrg return receive(__buffers, socket_base::message_flags(), 1172 1.1 mrg __throw_on_error{"basic_datagram_socket::receive"}); 1173 1.1 mrg } 1174 1.1 mrg 1175 1.1 mrg template<typename _MutableBufferSequence> 1176 1.1 mrg size_t 1177 1.1 mrg receive(const _MutableBufferSequence& __buffers, error_code& __ec) 1178 1.1 mrg { return receive(__buffers, socket_base::message_flags(), __ec); } 1179 1.1 mrg 1180 1.1 mrg template<typename _MutableBufferSequence> 1181 1.1 mrg size_t 1182 1.1 mrg receive(const _MutableBufferSequence& __buffers, 1183 1.1 mrg socket_base::message_flags __flags) 1184 1.1 mrg { 1185 1.1 mrg return receive(__buffers, __flags, 1186 1.1 mrg __throw_on_error{"basic_datagram_socket::receive"}); 1187 1.1 mrg } 1188 1.1 mrg 1189 1.1 mrg template<typename _MutableBufferSequence> 1190 1.1 mrg size_t 1191 1.1 mrg receive(const _MutableBufferSequence& __buffers, 1192 1.1 mrg socket_base::message_flags __flags, error_code& __ec) 1193 1.1 mrg { 1194 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1195 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1196 1.1 mrg ssize_t __result = ::recvmsg(this->native_handle(), &__msg, 1197 1.1 mrg static_cast<int>(__flags)); 1198 1.1 mrg if (__result == -1) 1199 1.1 mrg { 1200 1.1 mrg __ec.assign(errno, generic_category()); 1201 1.1 mrg return 0; 1202 1.1 mrg } 1203 1.1 mrg __ec.clear(); 1204 1.1 mrg return __result; 1205 1.1 mrg #else 1206 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1207 1.1 mrg return 0; 1208 1.1 mrg #endif 1209 1.1 mrg } 1210 1.1 mrg 1211 1.1 mrg template<typename _MutableBufferSequence, typename _CompletionToken> 1212 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1213 1.1 mrg async_receive(const _MutableBufferSequence& __buffers, 1214 1.1 mrg _CompletionToken&& __token) 1215 1.1 mrg { 1216 1.1 mrg return async_receive(__buffers, socket_base::message_flags(), 1217 1.1 mrg std::forward<_CompletionToken>(__token)); 1218 1.1 mrg } 1219 1.1 mrg 1220 1.1 mrg template<typename _MutableBufferSequence, typename _CompletionToken> 1221 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1222 1.1 mrg async_receive(const _MutableBufferSequence& __buffers, 1223 1.1 mrg socket_base::message_flags __flags, 1224 1.1 mrg _CompletionToken&& __token) 1225 1.1 mrg { 1226 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1227 1.1 mrg __init{__token}; 1228 1.1 mrg 1229 1.1 mrg this->get_executor().context().async_wait(this->native_handle(), 1230 1.1.1.4 mrg (int) socket_base::wait_read, 1231 1.1 mrg [__h = std::move(__init.completion_handler), 1232 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1233 1.1 mrg __fd = this->native_handle()] 1234 1.1 mrg (error_code __ec) mutable { 1235 1.1 mrg if (__ec) 1236 1.1 mrg { 1237 1.1 mrg __h(__ec); 1238 1.1 mrg return; 1239 1.1 mrg } 1240 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1241 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1242 1.1 mrg ssize_t __result = ::recvmsg(__fd, &__msg, __flags); 1243 1.1 mrg if (__result == -1) 1244 1.1 mrg { 1245 1.1 mrg __ec.assign(errno, generic_category()); 1246 1.1 mrg __result = 0; 1247 1.1 mrg } 1248 1.1 mrg else 1249 1.1 mrg __ec.clear(); 1250 1.1 mrg __h(__ec, __result); 1251 1.1 mrg #else 1252 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1253 1.1 mrg #endif 1254 1.1 mrg }); 1255 1.1 mrg return __init.result.get(); 1256 1.1 mrg } 1257 1.1 mrg 1258 1.1 mrg template<typename _MutableBufferSequence> 1259 1.1 mrg size_t 1260 1.1 mrg receive_from(const _MutableBufferSequence& __buffers, 1261 1.1 mrg endpoint_type& __sender) 1262 1.1 mrg { 1263 1.1 mrg return receive_from(__buffers, __sender, 1264 1.1 mrg socket_base::message_flags(), 1265 1.1 mrg __throw_on_error{ 1266 1.1 mrg "basic_datagram_socket::receive_from"}); 1267 1.1 mrg } 1268 1.1 mrg 1269 1.1 mrg template<typename _MutableBufferSequence> 1270 1.1 mrg size_t 1271 1.1 mrg receive_from(const _MutableBufferSequence& __buffers, 1272 1.1 mrg endpoint_type& __sender, error_code& __ec) 1273 1.1 mrg { 1274 1.1 mrg return receive_from(__buffers, __sender, 1275 1.1 mrg socket_base::message_flags(), __ec); 1276 1.1 mrg } 1277 1.1 mrg 1278 1.1 mrg template<typename _MutableBufferSequence> 1279 1.1 mrg size_t 1280 1.1 mrg receive_from(const _MutableBufferSequence& __buffers, 1281 1.1 mrg endpoint_type& __sender, 1282 1.1 mrg socket_base::message_flags __flags) 1283 1.1 mrg { 1284 1.1 mrg return receive_from(__buffers, __sender, __flags, 1285 1.1 mrg __throw_on_error{ 1286 1.1 mrg "basic_datagram_socket::receive_from"}); 1287 1.1 mrg } 1288 1.1 mrg 1289 1.1 mrg template<typename _MutableBufferSequence> 1290 1.1 mrg size_t 1291 1.1 mrg receive_from(const _MutableBufferSequence& __buffers, 1292 1.1 mrg endpoint_type& __sender, 1293 1.1 mrg socket_base::message_flags __flags, 1294 1.1 mrg error_code& __ec) 1295 1.1 mrg { 1296 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1297 1.1 mrg socket_base::__msg_hdr __msg(__buffers, __sender); 1298 1.1 mrg ssize_t __result = ::recvmsg(this->native_handle(), &__msg, 1299 1.1 mrg static_cast<int>(__flags)); 1300 1.1 mrg if (__result == -1) 1301 1.1 mrg { 1302 1.1 mrg __ec.assign(errno, generic_category()); 1303 1.1 mrg return 0; 1304 1.1 mrg } 1305 1.1 mrg __ec.clear(); 1306 1.1 mrg __sender.resize(__msg.msg_namelen); 1307 1.1 mrg return __result; 1308 1.1 mrg #else 1309 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1310 1.1 mrg return 0; 1311 1.1 mrg #endif 1312 1.1 mrg } 1313 1.1 mrg 1314 1.1 mrg template<typename _MutableBufferSequence, typename _CompletionToken> 1315 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1316 1.1 mrg async_receive_from(const _MutableBufferSequence& __buffers, 1317 1.1 mrg endpoint_type& __sender, 1318 1.1 mrg _CompletionToken&& __token) 1319 1.1 mrg { 1320 1.1 mrg return async_receive_from(__buffers, __sender, 1321 1.1 mrg socket_base::message_flags(), 1322 1.1 mrg std::forward<_CompletionToken>(__token)); 1323 1.1 mrg } 1324 1.1 mrg 1325 1.1 mrg template<typename _MutableBufferSequence, typename _CompletionToken> 1326 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1327 1.1 mrg async_receive_from(const _MutableBufferSequence& __buffers, 1328 1.1 mrg endpoint_type& __sender, 1329 1.1 mrg socket_base::message_flags __flags, 1330 1.1 mrg _CompletionToken&& __token) 1331 1.1 mrg { 1332 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1333 1.1 mrg __init{__token}; 1334 1.1 mrg 1335 1.1 mrg this->get_executor().context().async_wait( this->native_handle(), 1336 1.1.1.4 mrg (int) socket_base::wait_read, 1337 1.1 mrg [__h = std::move(__init.completion_handler), 1338 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1339 1.1 mrg __sender = std::move(__sender), 1340 1.1 mrg __fd = this->native_handle()] 1341 1.1 mrg (error_code __ec) mutable { 1342 1.1 mrg if (__ec) 1343 1.1 mrg { 1344 1.1 mrg __h(__ec); 1345 1.1 mrg return; 1346 1.1 mrg } 1347 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1348 1.1 mrg socket_base::__msg_hdr __msg(__buffers, __sender); 1349 1.1 mrg ssize_t __result = ::recvmsg(__fd, &__msg, __flags); 1350 1.1 mrg if (__result == -1) 1351 1.1 mrg { 1352 1.1 mrg __ec.assign(errno, generic_category()); 1353 1.1 mrg __result = 0; 1354 1.1 mrg } 1355 1.1 mrg else 1356 1.1 mrg { 1357 1.1 mrg __ec.clear(); 1358 1.1 mrg __sender.resize(__msg.msg_namelen); 1359 1.1 mrg } 1360 1.1 mrg __h(__ec, __result); 1361 1.1 mrg #else 1362 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1363 1.1 mrg #endif 1364 1.1 mrg }); 1365 1.1 mrg return __init.result.get(); 1366 1.1 mrg } 1367 1.1 mrg 1368 1.1 mrg template<typename _ConstBufferSequence> 1369 1.1 mrg size_t 1370 1.1 mrg send(const _ConstBufferSequence& __buffers) 1371 1.1 mrg { 1372 1.1 mrg return send(__buffers, socket_base::message_flags(), 1373 1.1 mrg __throw_on_error{"basic_datagram_socket::send"}); 1374 1.1 mrg } 1375 1.1 mrg 1376 1.1 mrg template<typename _ConstBufferSequence> 1377 1.1 mrg size_t 1378 1.1 mrg send(const _ConstBufferSequence& __buffers, error_code& __ec) 1379 1.1 mrg { return send(__buffers, socket_base::message_flags(), __ec); } 1380 1.1 mrg 1381 1.1 mrg template<typename _ConstBufferSequence> 1382 1.1 mrg size_t 1383 1.1 mrg send(const _ConstBufferSequence& __buffers, 1384 1.1 mrg socket_base::message_flags __flags) 1385 1.1 mrg { 1386 1.1 mrg return send(__buffers, __flags, 1387 1.1 mrg __throw_on_error{"basic_datagram_socket::send"}); 1388 1.1 mrg } 1389 1.1 mrg 1390 1.1 mrg template<typename _ConstBufferSequence> 1391 1.1 mrg size_t 1392 1.1 mrg send(const _ConstBufferSequence& __buffers, 1393 1.1 mrg socket_base::message_flags __flags, error_code& __ec) 1394 1.1 mrg { 1395 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1396 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1397 1.1 mrg ssize_t __result = ::sendmsg(this->native_handle(), &__msg, 1398 1.1 mrg static_cast<int>(__flags)); 1399 1.1 mrg if (__result == -1) 1400 1.1 mrg { 1401 1.1 mrg __ec.assign(errno, generic_category()); 1402 1.1 mrg return 0; 1403 1.1 mrg } 1404 1.1 mrg __ec.clear(); 1405 1.1 mrg return __result; 1406 1.1 mrg #else 1407 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1408 1.1 mrg return 0; 1409 1.1 mrg #endif 1410 1.1 mrg } 1411 1.1 mrg 1412 1.1 mrg template<typename _ConstBufferSequence, typename _CompletionToken> 1413 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1414 1.1 mrg async_send(const _ConstBufferSequence& __buffers, 1415 1.1 mrg _CompletionToken&& __token) 1416 1.1 mrg { 1417 1.1 mrg return async_send(__buffers, socket_base::message_flags(), 1418 1.1 mrg std::forward<_CompletionToken>(__token)); 1419 1.1 mrg } 1420 1.1 mrg 1421 1.1 mrg template<typename _ConstBufferSequence, typename _CompletionToken> 1422 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1423 1.1 mrg async_send(const _ConstBufferSequence& __buffers, 1424 1.1 mrg socket_base::message_flags __flags, 1425 1.1 mrg _CompletionToken&& __token) 1426 1.1 mrg { 1427 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1428 1.1 mrg __init{__token}; 1429 1.1 mrg 1430 1.1 mrg this->get_executor().context().async_wait( this->native_handle(), 1431 1.1.1.4 mrg (int) socket_base::wait_write, 1432 1.1 mrg [__h = std::move(__init.completion_handler), 1433 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1434 1.1 mrg __fd = this->native_handle()] 1435 1.1 mrg (error_code __ec) mutable { 1436 1.1 mrg if (__ec) 1437 1.1 mrg { 1438 1.1 mrg __h(__ec); 1439 1.1 mrg return; 1440 1.1 mrg } 1441 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1442 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1443 1.1 mrg ssize_t __result = ::sendmsg(__fd, &__msg, __flags); 1444 1.1 mrg if (__result == -1) 1445 1.1 mrg { 1446 1.1 mrg __ec.assign(errno, generic_category()); 1447 1.1 mrg __result = 0; 1448 1.1 mrg } 1449 1.1 mrg else 1450 1.1 mrg __ec.clear(); 1451 1.1 mrg __h(__ec, __result); 1452 1.1 mrg #else 1453 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1454 1.1 mrg #endif 1455 1.1 mrg }); 1456 1.1 mrg return __init.result.get(); 1457 1.1 mrg } 1458 1.1 mrg 1459 1.1 mrg template<typename _ConstBufferSequence> 1460 1.1 mrg size_t 1461 1.1 mrg send_to(const _ConstBufferSequence& __buffers, 1462 1.1 mrg const endpoint_type& __recipient) 1463 1.1 mrg { 1464 1.1 mrg return send_to(__buffers, __recipient, 1465 1.1 mrg socket_base::message_flags(), 1466 1.1 mrg __throw_on_error{"basic_datagram_socket::send_to"}); 1467 1.1 mrg } 1468 1.1 mrg 1469 1.1 mrg template<typename _ConstBufferSequence> 1470 1.1 mrg size_t 1471 1.1 mrg send_to(const _ConstBufferSequence& __buffers, 1472 1.1 mrg const endpoint_type& __recipient, error_code& __ec) 1473 1.1 mrg { 1474 1.1 mrg return send_to(__buffers, __recipient, 1475 1.1 mrg socket_base::message_flags(), __ec); 1476 1.1 mrg } 1477 1.1 mrg 1478 1.1 mrg template<typename _ConstBufferSequence> 1479 1.1 mrg size_t 1480 1.1 mrg send_to(const _ConstBufferSequence& __buffers, 1481 1.1 mrg const endpoint_type& __recipient, 1482 1.1 mrg socket_base::message_flags __flags) 1483 1.1 mrg { 1484 1.1 mrg return send_to(__buffers, __recipient, __flags, 1485 1.1 mrg __throw_on_error{"basic_datagram_socket::send_to"}); 1486 1.1 mrg } 1487 1.1 mrg 1488 1.1 mrg template<typename _ConstBufferSequence> 1489 1.1 mrg size_t 1490 1.1 mrg send_to(const _ConstBufferSequence& __buffers, 1491 1.1 mrg const endpoint_type& __recipient, 1492 1.1 mrg socket_base::message_flags __flags, error_code& __ec) 1493 1.1 mrg { 1494 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1495 1.1 mrg socket_base::__msg_hdr __msg(__buffers, __recipient); 1496 1.1 mrg ssize_t __result = ::sendmsg(this->native_handle(), &__msg, 1497 1.1 mrg static_cast<int>(__flags)); 1498 1.1 mrg if (__result == -1) 1499 1.1 mrg { 1500 1.1 mrg __ec.assign(errno, generic_category()); 1501 1.1 mrg return 0; 1502 1.1 mrg } 1503 1.1 mrg __ec.clear(); 1504 1.1 mrg __recipient.resize(__msg.msg_namelen); 1505 1.1 mrg return __result; 1506 1.1 mrg #else 1507 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1508 1.1 mrg return 0; 1509 1.1 mrg #endif 1510 1.1 mrg } 1511 1.1 mrg 1512 1.1 mrg template<typename _ConstBufferSequence, typename _CompletionToken> 1513 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1514 1.1 mrg async_send_to(const _ConstBufferSequence& __buffers, 1515 1.1 mrg const endpoint_type& __recipient, 1516 1.1 mrg _CompletionToken&& __token) 1517 1.1 mrg { 1518 1.1 mrg return async_send_to(__buffers, __recipient, 1519 1.1 mrg socket_base::message_flags(), 1520 1.1 mrg std::forward<_CompletionToken>(__token)); 1521 1.1 mrg } 1522 1.1 mrg 1523 1.1 mrg template<typename _ConstBufferSequence, typename _CompletionToken> 1524 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1525 1.1 mrg async_send_to(const _ConstBufferSequence& __buffers, 1526 1.1 mrg const endpoint_type& __recipient, 1527 1.1 mrg socket_base::message_flags __flags, 1528 1.1 mrg _CompletionToken&& __token) 1529 1.1 mrg { 1530 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1531 1.1 mrg __init{__token}; 1532 1.1 mrg 1533 1.1 mrg this->get_executor().context().async_wait( this->native_handle(), 1534 1.1.1.4 mrg (int) socket_base::wait_write, 1535 1.1 mrg [__h = std::move(__init.completion_handler), 1536 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1537 1.1 mrg __recipient = std::move(__recipient), 1538 1.1 mrg __fd = this->native_handle()] 1539 1.1 mrg (error_code __ec) mutable { 1540 1.1 mrg if (__ec) 1541 1.1 mrg { 1542 1.1 mrg __h(__ec); 1543 1.1 mrg return; 1544 1.1 mrg } 1545 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1546 1.1 mrg socket_base::__msg_hdr __msg(__buffers, __recipient); 1547 1.1 mrg ssize_t __result = ::sendmsg(__fd, &__msg, __flags); 1548 1.1 mrg if (__result == -1) 1549 1.1 mrg { 1550 1.1 mrg __ec.assign(errno, generic_category()); 1551 1.1 mrg __result = 0; 1552 1.1 mrg } 1553 1.1 mrg else 1554 1.1 mrg { 1555 1.1 mrg __ec.clear(); 1556 1.1 mrg __recipient.resize(__msg.msg_namelen); 1557 1.1 mrg } 1558 1.1 mrg __h(__ec, __result); 1559 1.1 mrg #else 1560 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1561 1.1 mrg #endif 1562 1.1 mrg }); 1563 1.1 mrg return __init.result.get(); 1564 1.1 mrg } 1565 1.1 mrg }; 1566 1.1 mrg 1567 1.1 mrg template<typename _Protocol> 1568 1.1 mrg class basic_stream_socket : public basic_socket<_Protocol> 1569 1.1 mrg { 1570 1.1 mrg using __base = basic_socket<_Protocol>; 1571 1.1 mrg 1572 1.1 mrg public: 1573 1.1 mrg // types: 1574 1.1 mrg 1575 1.1.1.4 mrg using native_handle_type = int; 1576 1.1.1.4 mrg using protocol_type = _Protocol; 1577 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 1578 1.1 mrg 1579 1.1 mrg // construct / copy / destroy: 1580 1.1 mrg 1581 1.1 mrg explicit 1582 1.1 mrg basic_stream_socket(io_context& __ctx) : __base(__ctx) { } 1583 1.1 mrg 1584 1.1 mrg basic_stream_socket(io_context& __ctx, const protocol_type& __protocol) 1585 1.1 mrg : __base(__ctx, __protocol) { } 1586 1.1 mrg 1587 1.1 mrg basic_stream_socket(io_context& __ctx, const endpoint_type& __endpoint) 1588 1.1 mrg : __base(__ctx, __endpoint) { } 1589 1.1 mrg 1590 1.1 mrg basic_stream_socket(io_context& __ctx, const protocol_type& __protocol, 1591 1.1 mrg const native_handle_type& __native_socket) 1592 1.1 mrg : __base(__ctx, __protocol, __native_socket) { } 1593 1.1 mrg 1594 1.1 mrg basic_stream_socket(const basic_stream_socket&) = delete; 1595 1.1 mrg 1596 1.1 mrg basic_stream_socket(basic_stream_socket&& __rhs) = default; 1597 1.1 mrg 1598 1.1 mrg template<typename _OtherProtocol, typename _Requires 1599 1.1 mrg = _Require<is_convertible<_OtherProtocol, _Protocol>>> 1600 1.1 mrg basic_stream_socket(basic_stream_socket<_OtherProtocol>&& __rhs) 1601 1.1 mrg : __base(std::move(__rhs)) { } 1602 1.1 mrg 1603 1.1 mrg ~basic_stream_socket() = default; 1604 1.1 mrg 1605 1.1 mrg basic_stream_socket& operator=(const basic_stream_socket&) = delete; 1606 1.1 mrg 1607 1.1 mrg basic_stream_socket& operator=(basic_stream_socket&& __rhs) = default; 1608 1.1 mrg 1609 1.1 mrg template<class _OtherProtocol> 1610 1.1 mrg enable_if_t<is_convertible<_OtherProtocol, _Protocol>::value, 1611 1.1 mrg basic_stream_socket&> 1612 1.1 mrg operator=(basic_stream_socket<_OtherProtocol>&& __rhs) 1613 1.1 mrg { 1614 1.1 mrg __base::operator=(std::move(__rhs)); 1615 1.1 mrg return *this; 1616 1.1 mrg } 1617 1.1 mrg 1618 1.1 mrg // basic_stream_socket operations: 1619 1.1 mrg 1620 1.1 mrg template<class _MutableBufferSequence> 1621 1.1 mrg size_t 1622 1.1 mrg receive(const _MutableBufferSequence& __buffers) 1623 1.1 mrg { 1624 1.1 mrg return receive(__buffers, socket_base::message_flags(), 1625 1.1 mrg __throw_on_error{"basic_stream_socket::receive"}); 1626 1.1 mrg } 1627 1.1 mrg 1628 1.1 mrg template<class _MutableBufferSequence> 1629 1.1 mrg size_t 1630 1.1 mrg receive(const _MutableBufferSequence& __buffers, error_code& __ec) 1631 1.1 mrg { return receive(__buffers, socket_base::message_flags(), __ec); } 1632 1.1 mrg 1633 1.1 mrg template<class _MutableBufferSequence> 1634 1.1 mrg size_t 1635 1.1 mrg receive(const _MutableBufferSequence& __buffers, 1636 1.1 mrg socket_base::message_flags __flags) 1637 1.1 mrg { 1638 1.1 mrg return receive(__buffers, __flags, 1639 1.1 mrg __throw_on_error{"basic_stream_socket::receive"}); 1640 1.1 mrg } 1641 1.1 mrg 1642 1.1 mrg template<class _MutableBufferSequence> 1643 1.1 mrg size_t 1644 1.1 mrg receive(const _MutableBufferSequence& __buffers, 1645 1.1 mrg socket_base::message_flags __flags, error_code& __ec) 1646 1.1 mrg { 1647 1.1 mrg if (__buffer_empty(__buffers)) 1648 1.1 mrg { 1649 1.1 mrg __ec.clear(); 1650 1.1 mrg return 0; 1651 1.1 mrg } 1652 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1653 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1654 1.1 mrg ssize_t __result = ::recvmsg(this->native_handle(), &__msg, 1655 1.1 mrg static_cast<int>(__flags)); 1656 1.1 mrg if (__result >= 0) 1657 1.1 mrg { 1658 1.1 mrg __ec.clear(); 1659 1.1 mrg return __result; 1660 1.1 mrg } 1661 1.1 mrg __ec.assign(errno, generic_category()); 1662 1.1 mrg #else 1663 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1664 1.1 mrg #endif 1665 1.1 mrg return 0; 1666 1.1 mrg } 1667 1.1 mrg 1668 1.1 mrg template<class _MutableBufferSequence, class _CompletionToken> 1669 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1670 1.1 mrg async_receive(const _MutableBufferSequence& __buffers, 1671 1.1 mrg _CompletionToken&& __token) 1672 1.1 mrg { 1673 1.1 mrg return async_receive(__buffers, socket_base::message_flags(), 1674 1.1 mrg std::forward<_CompletionToken>(__token)); 1675 1.1 mrg } 1676 1.1 mrg 1677 1.1 mrg template<class _MutableBufferSequence, class _CompletionToken> 1678 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1679 1.1 mrg async_receive(const _MutableBufferSequence& __buffers, 1680 1.1 mrg socket_base::message_flags __flags, 1681 1.1 mrg _CompletionToken&& __token) 1682 1.1 mrg { 1683 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1684 1.1 mrg __init{__token}; 1685 1.1 mrg 1686 1.1 mrg if (__buffer_empty(__buffers)) 1687 1.1 mrg { 1688 1.1 mrg auto __ex = net::get_associated_executor( 1689 1.1 mrg __init.completion_handler, this->get_executor()); 1690 1.1 mrg auto __a = get_associated_allocator( 1691 1.1 mrg __init.completion_handler, std::allocator<void>()); 1692 1.1 mrg __ex.post( 1693 1.1 mrg [__h=std::move(__init.completion_handler)] () mutable 1694 1.1 mrg { __h(error_code{}, 0); }, __a); 1695 1.1 mrg return __init.result.get(); 1696 1.1 mrg } 1697 1.1 mrg 1698 1.1 mrg this->get_executor().context().async_wait(this->native_handle(), 1699 1.1.1.4 mrg (int) socket_base::wait_read, 1700 1.1 mrg [__h = std::move(__init.completion_handler), 1701 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1702 1.1 mrg __fd = this->native_handle()] 1703 1.1 mrg (error_code __ec) mutable { 1704 1.1 mrg if (__ec) 1705 1.1 mrg { 1706 1.1 mrg __h(__ec); 1707 1.1 mrg return; 1708 1.1 mrg } 1709 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1710 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1711 1.1 mrg ssize_t __result = ::recvmsg(__fd, &__msg, __flags); 1712 1.1 mrg if (__result == -1) 1713 1.1 mrg { 1714 1.1 mrg __ec.assign(errno, generic_category()); 1715 1.1 mrg __result = 0; 1716 1.1 mrg } 1717 1.1 mrg else 1718 1.1 mrg __ec.clear(); 1719 1.1 mrg __h(__ec, __result); 1720 1.1 mrg #else 1721 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1722 1.1 mrg #endif 1723 1.1 mrg }); 1724 1.1 mrg return __init.result.get(); 1725 1.1 mrg } 1726 1.1 mrg 1727 1.1 mrg template<class _ConstBufferSequence> 1728 1.1 mrg size_t 1729 1.1 mrg send(const _ConstBufferSequence& __buffers) 1730 1.1 mrg { 1731 1.1 mrg return send(__buffers, socket_base::message_flags(), 1732 1.1 mrg __throw_on_error{"basic_stream_socket::send"}); 1733 1.1 mrg } 1734 1.1 mrg 1735 1.1 mrg template<class _ConstBufferSequence> 1736 1.1 mrg size_t 1737 1.1 mrg send(const _ConstBufferSequence& __buffers, error_code& __ec) 1738 1.1 mrg { return send(__buffers, socket_base::message_flags(), __ec); } 1739 1.1 mrg 1740 1.1 mrg template<class _ConstBufferSequence> 1741 1.1 mrg size_t 1742 1.1 mrg send(const _ConstBufferSequence& __buffers, 1743 1.1 mrg socket_base::message_flags __flags) 1744 1.1 mrg { 1745 1.1 mrg return send(__buffers, socket_base::message_flags(), 1746 1.1 mrg __throw_on_error{"basic_stream_socket::send"}); 1747 1.1 mrg } 1748 1.1 mrg 1749 1.1 mrg template<class _ConstBufferSequence> 1750 1.1 mrg size_t 1751 1.1 mrg send(const _ConstBufferSequence& __buffers, 1752 1.1 mrg socket_base::message_flags __flags, error_code& __ec) 1753 1.1 mrg { 1754 1.1 mrg if (__buffer_empty(__buffers)) 1755 1.1 mrg { 1756 1.1 mrg __ec.clear(); 1757 1.1 mrg return 0; 1758 1.1 mrg } 1759 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1760 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1761 1.1 mrg ssize_t __result = ::sendmsg(this->native_handle(), &__msg, 1762 1.1 mrg static_cast<int>(__flags)); 1763 1.1 mrg if (__result >= 0) 1764 1.1 mrg { 1765 1.1 mrg __ec.clear(); 1766 1.1 mrg return __result; 1767 1.1 mrg } 1768 1.1 mrg __ec.assign(errno, generic_category()); 1769 1.1 mrg #else 1770 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 1771 1.1 mrg #endif 1772 1.1 mrg return 0; 1773 1.1 mrg } 1774 1.1 mrg 1775 1.1 mrg template<class _ConstBufferSequence, class _CompletionToken> 1776 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1777 1.1 mrg async_send(const _ConstBufferSequence& __buffers, 1778 1.1 mrg _CompletionToken&& __token) 1779 1.1 mrg { 1780 1.1 mrg return async_send(__buffers, socket_base::message_flags(), 1781 1.1 mrg std::forward<_CompletionToken>(__token)); 1782 1.1 mrg } 1783 1.1 mrg 1784 1.1 mrg template<class _ConstBufferSequence, class _CompletionToken> 1785 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1786 1.1 mrg async_send(const _ConstBufferSequence& __buffers, 1787 1.1 mrg socket_base::message_flags __flags, 1788 1.1 mrg _CompletionToken&& __token) 1789 1.1 mrg { 1790 1.1 mrg async_completion<_CompletionToken, void(error_code, size_t)> 1791 1.1 mrg __init{__token}; 1792 1.1 mrg 1793 1.1 mrg if (__buffer_empty(__buffers)) 1794 1.1 mrg { 1795 1.1 mrg auto __ex = net::get_associated_executor( 1796 1.1 mrg __init.completion_handler, this->get_executor()); 1797 1.1 mrg auto __a = get_associated_allocator( 1798 1.1 mrg __init.completion_handler, std::allocator<void>()); 1799 1.1 mrg __ex.post( 1800 1.1 mrg [__h=std::move(__init.completion_handler)] () mutable 1801 1.1 mrg { __h(error_code{}, 0); }, __a); 1802 1.1 mrg return __init.result.get(); 1803 1.1 mrg } 1804 1.1 mrg 1805 1.1 mrg this->get_executor().context().async_wait(this->native_handle(), 1806 1.1.1.4 mrg (int) socket_base::wait_write, 1807 1.1 mrg [__h = std::move(__init.completion_handler), 1808 1.1 mrg &__buffers, __flags = static_cast<int>(__flags), 1809 1.1 mrg __fd = this->native_handle()] 1810 1.1 mrg (error_code __ec) mutable { 1811 1.1 mrg if (__ec) 1812 1.1 mrg { 1813 1.1 mrg __h(__ec); 1814 1.1 mrg return; 1815 1.1 mrg } 1816 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1817 1.1 mrg socket_base::__msg_hdr __msg(__buffers); 1818 1.1 mrg ssize_t __result = ::sendmsg(__fd, &__msg, __flags); 1819 1.1 mrg if (__result == -1) 1820 1.1 mrg { 1821 1.1 mrg __ec.assign(errno, generic_category()); 1822 1.1 mrg __result = 0; 1823 1.1 mrg } 1824 1.1 mrg else 1825 1.1 mrg __ec.clear(); 1826 1.1 mrg __h(__ec, __result); 1827 1.1 mrg #else 1828 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 1829 1.1 mrg #endif 1830 1.1 mrg }); 1831 1.1 mrg return __init.result.get(); 1832 1.1 mrg } 1833 1.1 mrg 1834 1.1 mrg template<class _MutableBufferSequence> 1835 1.1 mrg size_t 1836 1.1 mrg read_some(const _MutableBufferSequence& __buffers) 1837 1.1 mrg { 1838 1.1 mrg return receive(__buffers, 1839 1.1 mrg __throw_on_error{"basic_stream_socket::read_some"}); 1840 1.1 mrg } 1841 1.1 mrg 1842 1.1 mrg template<class _MutableBufferSequence> 1843 1.1 mrg size_t 1844 1.1 mrg read_some(const _MutableBufferSequence& __buffers, error_code& __ec) 1845 1.1 mrg { return receive(__buffers, __ec); } 1846 1.1 mrg 1847 1.1 mrg template<class _MutableBufferSequence, class _CompletionToken> 1848 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1849 1.1 mrg async_read_some(const _MutableBufferSequence& __buffers, 1850 1.1 mrg _CompletionToken&& __token) 1851 1.1 mrg { 1852 1.1 mrg return async_receive(__buffers, 1853 1.1 mrg std::forward<_CompletionToken>(__token)); 1854 1.1 mrg } 1855 1.1 mrg 1856 1.1 mrg template<class _ConstBufferSequence> 1857 1.1 mrg size_t 1858 1.1 mrg write_some(const _ConstBufferSequence& __buffers) 1859 1.1 mrg { 1860 1.1 mrg return send(__buffers, 1861 1.1 mrg __throw_on_error{"basic_stream_socket:write_some"}); 1862 1.1 mrg } 1863 1.1 mrg 1864 1.1 mrg template<class _ConstBufferSequence> 1865 1.1 mrg size_t 1866 1.1 mrg write_some(const _ConstBufferSequence& __buffers, error_code& __ec) 1867 1.1 mrg { return send(__buffers, __ec); } 1868 1.1 mrg 1869 1.1 mrg template<class _ConstBufferSequence, class _CompletionToken> 1870 1.1 mrg __deduced_t<_CompletionToken, void(error_code, size_t)> 1871 1.1 mrg async_write_some(const _ConstBufferSequence& __buffers, 1872 1.1 mrg _CompletionToken&& __token) 1873 1.1 mrg { 1874 1.1 mrg return async_send(__buffers, 1875 1.1 mrg std::forward<_CompletionToken>(__token)); 1876 1.1 mrg } 1877 1.1 mrg }; 1878 1.1 mrg 1879 1.1 mrg template<typename _AcceptableProtocol> 1880 1.1 mrg class basic_socket_acceptor 1881 1.1 mrg : public socket_base, private __basic_socket_impl<_AcceptableProtocol> 1882 1.1 mrg { 1883 1.1 mrg using __base = __basic_socket_impl<_AcceptableProtocol>; 1884 1.1 mrg 1885 1.1 mrg public: 1886 1.1 mrg // types: 1887 1.1 mrg 1888 1.1.1.4 mrg using executor_type = io_context::executor_type; 1889 1.1.1.4 mrg using native_handle_type = int; 1890 1.1.1.4 mrg using protocol_type = _AcceptableProtocol; 1891 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 1892 1.1.1.4 mrg using socket_type = typename protocol_type::socket; 1893 1.1.1.4 mrg 1894 1.1.1.4 mrg static_assert(__detail::__acceptable_protocol<protocol_type>, 1895 1.1.1.4 mrg "protocol_type meets the AcceptableProtocol requirements"); 1896 1.1 mrg 1897 1.1 mrg // construct / copy / destroy: 1898 1.1 mrg 1899 1.1 mrg explicit 1900 1.1 mrg basic_socket_acceptor(io_context& __ctx) 1901 1.1 mrg : __base(__ctx), _M_protocol(endpoint_type{}.protocol()) { } 1902 1.1 mrg 1903 1.1 mrg basic_socket_acceptor(io_context& __ctx, 1904 1.1 mrg const protocol_type& __protocol) 1905 1.1 mrg : __base(__ctx), _M_protocol(__protocol) 1906 1.1 mrg { open(__protocol); } 1907 1.1 mrg 1908 1.1 mrg basic_socket_acceptor(io_context& __ctx, const endpoint_type& __endpoint, 1909 1.1.1.4 mrg [[__maybe_unused__]] bool __reuse_addr = true) 1910 1.1 mrg : basic_socket_acceptor(__ctx, __endpoint.protocol()) 1911 1.1 mrg { 1912 1.1.1.4 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 1913 1.1 mrg if (__reuse_addr) 1914 1.1 mrg set_option(reuse_address(true)); 1915 1.1.1.4 mrg #endif 1916 1.1 mrg bind(__endpoint); 1917 1.1 mrg listen(); 1918 1.1 mrg } 1919 1.1 mrg 1920 1.1 mrg basic_socket_acceptor(io_context& __ctx, const protocol_type& __protocol, 1921 1.1 mrg const native_handle_type& __native_acceptor) 1922 1.1 mrg : basic_socket_acceptor(__ctx, __protocol) 1923 1.1 mrg { assign(__protocol, __native_acceptor); } 1924 1.1 mrg 1925 1.1 mrg basic_socket_acceptor(const basic_socket_acceptor&) = delete; 1926 1.1 mrg 1927 1.1 mrg basic_socket_acceptor(basic_socket_acceptor&&) = default; 1928 1.1 mrg 1929 1.1 mrg template<typename _OtherProtocol, typename _Requires 1930 1.1 mrg = _Require<is_convertible<_OtherProtocol, protocol_type>>> 1931 1.1 mrg basic_socket_acceptor(basic_socket_acceptor<_OtherProtocol>&& __rhs) 1932 1.1 mrg : __base(std::move(__rhs)) { } 1933 1.1 mrg 1934 1.1 mrg ~basic_socket_acceptor() = default; 1935 1.1 mrg 1936 1.1 mrg basic_socket_acceptor& operator=(const basic_socket_acceptor&) = delete; 1937 1.1 mrg 1938 1.1 mrg basic_socket_acceptor& operator=(basic_socket_acceptor&&) = default; 1939 1.1 mrg 1940 1.1 mrg template<class _OtherProtocol> 1941 1.1 mrg enable_if_t<is_convertible<_OtherProtocol, protocol_type>::value, 1942 1.1 mrg basic_socket_acceptor&> 1943 1.1 mrg operator=(basic_socket_acceptor<_OtherProtocol>&& __rhs) 1944 1.1 mrg { 1945 1.1 mrg __base::operator=(std::move(__rhs)); 1946 1.1 mrg return *this; 1947 1.1 mrg } 1948 1.1 mrg 1949 1.1 mrg // basic_socket_acceptor operations: 1950 1.1 mrg 1951 1.1 mrg executor_type get_executor() noexcept { return __base::get_executor(); } 1952 1.1 mrg 1953 1.1 mrg native_handle_type 1954 1.1 mrg native_handle() noexcept { return __base::native_handle(); } 1955 1.1 mrg 1956 1.1 mrg void 1957 1.1 mrg open(const protocol_type& __protocol = protocol_type()) 1958 1.1 mrg { open(__protocol, __throw_on_error{"basic_socket_acceptor::open"}); } 1959 1.1 mrg 1960 1.1 mrg void 1961 1.1 mrg open(const protocol_type& __protocol, error_code& __ec) 1962 1.1 mrg { __base::open(__protocol, __ec); } 1963 1.1 mrg 1964 1.1 mrg void 1965 1.1 mrg assign(const protocol_type& __protocol, 1966 1.1 mrg const native_handle_type& __native_acceptor) 1967 1.1 mrg { 1968 1.1 mrg assign(__protocol, __native_acceptor, 1969 1.1 mrg __throw_on_error{"basic_socket_acceptor::assign"}); 1970 1.1 mrg } 1971 1.1 mrg 1972 1.1 mrg void 1973 1.1 mrg assign(const protocol_type& __protocol, 1974 1.1 mrg const native_handle_type& __native_acceptor, 1975 1.1 mrg error_code& __ec) 1976 1.1 mrg { __base::assign(__protocol, __native_acceptor, __ec); } 1977 1.1 mrg 1978 1.1.1.2 mrg native_handle_type release() 1979 1.1.1.2 mrg { return release(__throw_on_error{"basic_socket_acceptor::release"}); } 1980 1.1.1.2 mrg 1981 1.1.1.2 mrg native_handle_type release(error_code& __ec) 1982 1.1.1.2 mrg { return __base::release(__ec); } 1983 1.1.1.2 mrg 1984 1.1.1.2 mrg _GLIBCXX_NODISCARD bool 1985 1.1 mrg is_open() const noexcept { return __base::is_open(); } 1986 1.1 mrg 1987 1.1 mrg void 1988 1.1 mrg close() { close(__throw_on_error{"basic_socket_acceptor::close"}); } 1989 1.1 mrg 1990 1.1 mrg void 1991 1.1 mrg close(error_code& __ec) { __base::_close(__ec); } 1992 1.1 mrg 1993 1.1 mrg void 1994 1.1 mrg cancel() { cancel(__throw_on_error{"basic_socket_acceptor::cancel"}); } 1995 1.1 mrg 1996 1.1 mrg void 1997 1.1 mrg cancel(error_code& __ec) { __base::cancel(__ec); } 1998 1.1 mrg 1999 1.1 mrg template<typename _SettableSocketOption> 2000 1.1 mrg void 2001 1.1 mrg set_option(const _SettableSocketOption& __option) 2002 1.1 mrg { 2003 1.1 mrg set_option(__option, 2004 1.1 mrg __throw_on_error{"basic_socket_acceptor::set_option"}); 2005 1.1 mrg } 2006 1.1 mrg 2007 1.1 mrg template<typename _SettableSocketOption> 2008 1.1 mrg void 2009 1.1 mrg set_option(const _SettableSocketOption& __option, error_code& __ec) 2010 1.1 mrg { __base::set_option(__option, __ec); } 2011 1.1 mrg 2012 1.1 mrg template<typename _GettableSocketOption> 2013 1.1 mrg void 2014 1.1 mrg get_option(_GettableSocketOption& __option) const 2015 1.1 mrg { 2016 1.1 mrg get_option(__option, 2017 1.1 mrg __throw_on_error{"basic_socket_acceptor::get_option"}); 2018 1.1 mrg } 2019 1.1 mrg 2020 1.1 mrg template<typename _GettableSocketOption> 2021 1.1 mrg void 2022 1.1 mrg get_option(_GettableSocketOption& __option, error_code& __ec) const 2023 1.1 mrg { __base::get_option(__option, __ec); } 2024 1.1 mrg 2025 1.1 mrg template<typename _IoControlCommand> 2026 1.1 mrg void 2027 1.1 mrg io_control(_IoControlCommand& __command) 2028 1.1 mrg { 2029 1.1 mrg io_control(__command, 2030 1.1 mrg __throw_on_error{"basic_socket_acceptor::io_control"}); 2031 1.1 mrg } 2032 1.1 mrg 2033 1.1 mrg template<typename _IoControlCommand> 2034 1.1 mrg void 2035 1.1 mrg io_control(_IoControlCommand& __command, error_code& __ec) 2036 1.1 mrg { __base::io_control(__command, __ec); } 2037 1.1 mrg 2038 1.1 mrg void 2039 1.1 mrg non_blocking(bool __mode) 2040 1.1 mrg { 2041 1.1 mrg non_blocking(__mode, 2042 1.1 mrg __throw_on_error{"basic_socket_acceptor::non_blocking"}); 2043 1.1 mrg } 2044 1.1 mrg 2045 1.1 mrg void 2046 1.1 mrg non_blocking(bool __mode, error_code& __ec) 2047 1.1 mrg { __base::non_blocking(__mode, __ec); } 2048 1.1 mrg 2049 1.1 mrg bool non_blocking() const { return __base::non_blocking(); } 2050 1.1 mrg 2051 1.1 mrg void 2052 1.1 mrg native_non_blocking(bool __mode) 2053 1.1 mrg { 2054 1.1 mrg native_non_blocking(__mode, __throw_on_error{ 2055 1.1 mrg "basic_socket_acceptor::native_non_blocking"}); 2056 1.1 mrg } 2057 1.1 mrg 2058 1.1 mrg void 2059 1.1 mrg native_non_blocking(bool __mode, error_code& __ec) 2060 1.1 mrg { __base::native_non_blocking(__mode, __ec); } 2061 1.1 mrg 2062 1.1 mrg bool 2063 1.1 mrg native_non_blocking() const 2064 1.1 mrg { return __base::native_non_blocking(); } 2065 1.1 mrg 2066 1.1 mrg void 2067 1.1 mrg bind(const endpoint_type& __endpoint) 2068 1.1 mrg { 2069 1.1 mrg return bind(__endpoint, 2070 1.1 mrg __throw_on_error{"basic_socket_acceptor::bind"}); 2071 1.1 mrg } 2072 1.1 mrg 2073 1.1 mrg void 2074 1.1 mrg bind(const endpoint_type& __endpoint, error_code& __ec) 2075 1.1 mrg { __base::bind(__endpoint, __ec); } 2076 1.1 mrg 2077 1.1 mrg void 2078 1.1 mrg listen(int __backlog = max_listen_connections) 2079 1.1 mrg { 2080 1.1 mrg return listen(__backlog, 2081 1.1 mrg __throw_on_error{"basic_socket_acceptor::listen"}); 2082 1.1 mrg } 2083 1.1 mrg 2084 1.1 mrg void 2085 1.1 mrg listen(int __backlog, error_code& __ec) 2086 1.1 mrg { 2087 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 2088 1.1 mrg if (::listen(native_handle(), __backlog) == -1) 2089 1.1 mrg __ec.assign(errno, generic_category()); 2090 1.1 mrg else 2091 1.1 mrg __ec.clear(); 2092 1.1 mrg #else 2093 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 2094 1.1 mrg #endif 2095 1.1 mrg } 2096 1.1 mrg 2097 1.1 mrg endpoint_type 2098 1.1 mrg local_endpoint() const 2099 1.1 mrg { 2100 1.1 mrg return local_endpoint( 2101 1.1 mrg __throw_on_error{"basic_socket_acceptor::local_endpoint"}); 2102 1.1 mrg } 2103 1.1 mrg 2104 1.1 mrg endpoint_type 2105 1.1 mrg local_endpoint(error_code& __ec) const 2106 1.1 mrg { return __base::local_endpoint(__ec); } 2107 1.1 mrg 2108 1.1 mrg void 2109 1.1 mrg enable_connection_aborted(bool __mode) 2110 1.1 mrg { __base::_M_bits.enable_connection_aborted = __mode; } 2111 1.1 mrg 2112 1.1 mrg bool 2113 1.1 mrg enable_connection_aborted() const 2114 1.1 mrg { return __base::_M_bits.enable_connection_aborted; } 2115 1.1 mrg 2116 1.1 mrg socket_type 2117 1.1 mrg accept() 2118 1.1 mrg { return accept(__throw_on_error{"basic_socket_acceptor::accept"}); } 2119 1.1 mrg 2120 1.1 mrg socket_type 2121 1.1 mrg accept(error_code& __ec) 2122 1.1 mrg { return accept(get_executor().context(), __ec); } 2123 1.1 mrg 2124 1.1 mrg socket_type accept(io_context& __ctx) 2125 1.1 mrg { 2126 1.1 mrg return accept(__ctx, 2127 1.1 mrg __throw_on_error{"basic_socket_acceptor::accept"}); 2128 1.1 mrg } 2129 1.1 mrg 2130 1.1 mrg socket_type 2131 1.1 mrg accept(io_context& __ctx, error_code& __ec) 2132 1.1 mrg { 2133 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 2134 1.1 mrg do 2135 1.1 mrg { 2136 1.1 mrg int __h = ::accept(native_handle(), nullptr, 0); 2137 1.1 mrg if (__h != -1) 2138 1.1 mrg { 2139 1.1 mrg __ec.clear(); 2140 1.1 mrg return socket_type{__ctx, _M_protocol, __h}; 2141 1.1 mrg } 2142 1.1 mrg } while (errno == ECONNABORTED && enable_connection_aborted()); 2143 1.1 mrg __ec.assign(errno, generic_category()); 2144 1.1 mrg #else 2145 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 2146 1.1 mrg #endif 2147 1.1 mrg return socket_type{__ctx}; 2148 1.1 mrg } 2149 1.1 mrg 2150 1.1 mrg template<class _CompletionToken> 2151 1.1 mrg __deduced_t<_CompletionToken, void(error_code, socket_type)> 2152 1.1 mrg async_accept(_CompletionToken&& __token) 2153 1.1 mrg { 2154 1.1 mrg return async_accept(get_executor().context(), 2155 1.1 mrg std::forward<_CompletionToken>(__token)); 2156 1.1 mrg } 2157 1.1 mrg 2158 1.1 mrg template<class _CompletionToken> 2159 1.1 mrg __deduced_t<_CompletionToken, void(error_code, socket_type)> 2160 1.1 mrg async_accept(io_context& __ctx, _CompletionToken&& __token) 2161 1.1 mrg { 2162 1.1 mrg async_completion<_CompletionToken, void(error_code, socket_type)> 2163 1.1 mrg __init{__token}; 2164 1.1 mrg 2165 1.1.1.4 mrg __ctx.async_wait(native_handle(), 2166 1.1.1.4 mrg (int) socket_base::wait_read, 2167 1.1 mrg [__h = std::move(__init.completion_handler), 2168 1.1 mrg __connabort = enable_connection_aborted(), 2169 1.1 mrg __fd = native_handle(), 2170 1.1 mrg __protocol = _M_protocol, 2171 1.1 mrg &__ctx 2172 1.1 mrg ] 2173 1.1 mrg (error_code __ec) mutable { 2174 1.1 mrg if (__ec) 2175 1.1 mrg { 2176 1.1 mrg __h(__ec, socket_type(__ctx)); 2177 1.1 mrg return; 2178 1.1 mrg } 2179 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 2180 1.1 mrg do 2181 1.1 mrg { 2182 1.1 mrg int __newfd = ::accept(__fd, nullptr, 0); 2183 1.1 mrg if (__newfd != -1) 2184 1.1 mrg { 2185 1.1 mrg __ec.clear(); 2186 1.1 mrg __h(__ec, socket_type{__ctx, __protocol, __newfd}); 2187 1.1 mrg return; 2188 1.1 mrg } 2189 1.1 mrg } while (errno == ECONNABORTED && __connabort); 2190 1.1 mrg __ec.assign(errno, generic_category()); 2191 1.1 mrg __h(__ec, socket_type(__ctx)); 2192 1.1 mrg #else 2193 1.1 mrg __h(std::make_error_code(errc::operation_not_supported), 0); 2194 1.1 mrg #endif 2195 1.1 mrg }); 2196 1.1 mrg return __init.result.get(); 2197 1.1 mrg } 2198 1.1 mrg 2199 1.1 mrg socket_type 2200 1.1 mrg accept(endpoint_type& __endpoint) 2201 1.1 mrg { 2202 1.1 mrg return accept(get_executor().context(), __endpoint, 2203 1.1 mrg __throw_on_error{"basic_socket_acceptor::accept"}); 2204 1.1 mrg } 2205 1.1 mrg 2206 1.1 mrg socket_type 2207 1.1 mrg accept(endpoint_type& __endpoint, error_code& __ec) 2208 1.1 mrg { return accept(get_executor().context(), __endpoint, __ec); } 2209 1.1 mrg 2210 1.1 mrg socket_type 2211 1.1 mrg accept(io_context& __ctx, endpoint_type& __endpoint) 2212 1.1 mrg { 2213 1.1 mrg return accept(__ctx, __endpoint, 2214 1.1 mrg __throw_on_error{"basic_socket_acceptor::accept"}); 2215 1.1 mrg } 2216 1.1 mrg 2217 1.1 mrg socket_type 2218 1.1 mrg accept(io_context& __ctx, endpoint_type& __endpoint, error_code& __ec) 2219 1.1 mrg { 2220 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 2221 1.1 mrg do 2222 1.1 mrg { 2223 1.1 mrg socklen_t __len = __endpoint.capacity(); 2224 1.1 mrg int __h = ::accept(native_handle(), (sockaddr*)__endpoint.data(), 2225 1.1 mrg &__len); 2226 1.1 mrg if (__h != -1) 2227 1.1 mrg { 2228 1.1 mrg __endpoint.resize(__len); 2229 1.1 mrg return socket_type{__ctx, _M_protocol, __h}; 2230 1.1 mrg } 2231 1.1 mrg } while (errno == ECONNABORTED && enable_connection_aborted()); 2232 1.1 mrg __ec.assign(errno, generic_category()); 2233 1.1 mrg #else 2234 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 2235 1.1 mrg #endif 2236 1.1 mrg return socket_type{__ctx}; 2237 1.1 mrg } 2238 1.1 mrg 2239 1.1 mrg template<class _CompletionToken> 2240 1.1 mrg __deduced_t<_CompletionToken, void(error_code, socket_type)> 2241 1.1 mrg async_accept(endpoint_type& __endpoint, 2242 1.1 mrg _CompletionToken&& __token) 2243 1.1 mrg { 2244 1.1 mrg return async_accept(get_executor().context(), __endpoint, 2245 1.1 mrg std::forward<_CompletionToken>(__token)); 2246 1.1 mrg } 2247 1.1 mrg 2248 1.1 mrg template<class _CompletionToken> 2249 1.1 mrg __deduced_t<_CompletionToken, void(error_code, socket_type)> 2250 1.1 mrg async_accept(io_context& __ctx, endpoint_type& __endpoint, 2251 1.1 mrg _CompletionToken&& __token) 2252 1.1 mrg { 2253 1.1 mrg async_completion<_CompletionToken, void(error_code, socket_type)> 2254 1.1 mrg __init{__token}; 2255 1.1 mrg 2256 1.1.1.4 mrg __ctx.async_wait(native_handle(), 2257 1.1.1.4 mrg (int) socket_base::wait_read, 2258 1.1 mrg [__h = std::move(__init.completion_handler), 2259 1.1 mrg __ep = std::move(__endpoint), 2260 1.1 mrg __connabort = enable_connection_aborted(), 2261 1.1 mrg __fd = native_handle(), 2262 1.1 mrg &__ctx 2263 1.1 mrg ] 2264 1.1 mrg (error_code __ec) mutable { 2265 1.1 mrg if (__ec) 2266 1.1 mrg { 2267 1.1 mrg __h(__ec, socket_type(__ctx)); 2268 1.1 mrg return; 2269 1.1 mrg } 2270 1.1 mrg #ifdef _GLIBCXX_HAVE_SYS_SOCKET_H 2271 1.1 mrg do 2272 1.1 mrg { 2273 1.1 mrg socklen_t __len = __ep.capacity(); 2274 1.1 mrg int __newfd = ::accept(__fd, __ep.data, &__len); 2275 1.1 mrg if (__newfd != -1) 2276 1.1 mrg { 2277 1.1 mrg __ep.resize(__len); 2278 1.1 mrg auto __protocol = __ep.protocol(); 2279 1.1 mrg __ec.clear(); 2280 1.1 mrg __h(__ec, socket_type{__ctx, __protocol, __newfd}); 2281 1.1 mrg return; 2282 1.1 mrg } 2283 1.1 mrg } while (errno == ECONNABORTED && __connabort); 2284 1.1 mrg __ec.assign(errno, generic_category()); 2285 1.1 mrg #else 2286 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 2287 1.1 mrg #endif 2288 1.1 mrg __h(__ec, socket_type(__ctx)); 2289 1.1 mrg }); 2290 1.1 mrg return __init.result.get(); 2291 1.1 mrg } 2292 1.1 mrg 2293 1.1 mrg void 2294 1.1 mrg wait(wait_type __w) 2295 1.1 mrg { wait(__w, __throw_on_error{"basic_socket_acceptor::wait"}); } 2296 1.1 mrg 2297 1.1 mrg void 2298 1.1 mrg wait(wait_type __w, error_code& __ec) 2299 1.1 mrg { 2300 1.1 mrg #ifdef _GLIBCXX_HAVE_POLL_H 2301 1.1 mrg ::pollfd __fds; 2302 1.1 mrg __fds.fd = native_handle(); 2303 1.1 mrg __fds.events = __w; // __w | POLLIN; 2304 1.1 mrg if (::poll(&__fds, 1, -1) == -1) 2305 1.1 mrg __ec.assign(errno, generic_category()); 2306 1.1 mrg else 2307 1.1 mrg __ec.clear(); 2308 1.1 mrg #else 2309 1.1 mrg __ec = std::make_error_code(errc::operation_not_supported); 2310 1.1 mrg #endif 2311 1.1 mrg } 2312 1.1 mrg 2313 1.1 mrg template<class _CompletionToken> 2314 1.1 mrg __deduced_t<_CompletionToken, void(error_code)> 2315 1.1 mrg async_wait(wait_type __w, _CompletionToken&& __token) 2316 1.1 mrg { 2317 1.1 mrg async_completion<_CompletionToken, void(error_code)> __init{__token}; 2318 1.1 mrg get_executor().context().async_wait( native_handle(), 2319 1.1 mrg static_cast<int>(__w), 2320 1.1 mrg [__h = std::move(__init.completion_handler)] 2321 1.1 mrg (error_code __ec) mutable { 2322 1.1 mrg __h(__ec); 2323 1.1 mrg }); 2324 1.1 mrg return __init.result.get(); 2325 1.1 mrg } 2326 1.1 mrg 2327 1.1 mrg private: 2328 1.1 mrg protocol_type _M_protocol; 2329 1.1 mrg }; 2330 1.1 mrg 2331 1.1.1.3 mrg /// @} 2332 1.1 mrg 2333 1.1 mrg /** @brief Socket streams 2334 1.1 mrg * @{ 2335 1.1 mrg */ 2336 1.1 mrg 2337 1.1 mrg template<typename _Protocol, typename _Clock, typename _WaitTraits> 2338 1.1 mrg class basic_socket_streambuf : public basic_streambuf<char> 2339 1.1 mrg { 2340 1.1 mrg public: 2341 1.1 mrg // types: 2342 1.1 mrg 2343 1.1.1.4 mrg using protocol_type = _Protocol; 2344 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 2345 1.1.1.4 mrg using clock_type = _Clock; 2346 1.1.1.4 mrg using time_point = typename clock_type::time_point; 2347 1.1.1.4 mrg using duration = typename clock_type::duration; 2348 1.1.1.4 mrg using wait_traits_type = _WaitTraits; 2349 1.1 mrg 2350 1.1 mrg // construct / copy / destroy: 2351 1.1 mrg 2352 1.1 mrg basic_socket_streambuf() : _M_socket(_S_ctx()) { } 2353 1.1 mrg 2354 1.1 mrg explicit 2355 1.1 mrg basic_socket_streambuf(basic_stream_socket<protocol_type> __s) 2356 1.1 mrg : _M_socket(std::move(__s)) { } 2357 1.1 mrg 2358 1.1 mrg basic_socket_streambuf(const basic_socket_streambuf&) = delete; 2359 1.1 mrg 2360 1.1 mrg basic_socket_streambuf(basic_socket_streambuf&& __rhs); // TODO 2361 1.1 mrg 2362 1.1 mrg 2363 1.1 mrg virtual ~basic_socket_streambuf(); // TODO 2364 1.1 mrg 2365 1.1 mrg basic_socket_streambuf& operator=(const basic_socket_streambuf&) = delete; 2366 1.1 mrg 2367 1.1 mrg basic_socket_streambuf& operator=(basic_socket_streambuf&& __rhs); // TODO 2368 1.1 mrg 2369 1.1 mrg // members: 2370 1.1 mrg 2371 1.1 mrg basic_socket_streambuf* connect(const endpoint_type& __e); // TODO 2372 1.1 mrg 2373 1.1 mrg template<typename... _Args> 2374 1.1 mrg basic_socket_streambuf* connect(_Args&&... ); // TODO 2375 1.1 mrg 2376 1.1 mrg basic_socket_streambuf* close(); // TODO 2377 1.1 mrg 2378 1.1 mrg basic_socket<protocol_type>& socket() { return _M_socket; } 2379 1.1.1.2 mrg 2380 1.1.1.2 mrg error_code error() const noexcept { return _M_ec; } 2381 1.1 mrg 2382 1.1 mrg time_point expiry() const { return _M_expiry; } 2383 1.1 mrg 2384 1.1 mrg void 2385 1.1 mrg expires_at(const time_point& __t) 2386 1.1 mrg { _M_expiry = __t; } 2387 1.1 mrg 2388 1.1 mrg void 2389 1.1 mrg expires_after(const duration& __d) 2390 1.1 mrg { expires_at(clock_type::now() + __d); } 2391 1.1 mrg 2392 1.1 mrg protected: 2393 1.1 mrg // overridden virtual functions: // TODO 2394 1.1 mrg virtual int_type underflow() override; 2395 1.1 mrg virtual int_type pbackfail(int_type __c = traits_type::eof()) override; 2396 1.1 mrg virtual int_type overflow(int_type __c = traits_type::eof()) override; 2397 1.1 mrg virtual int sync() override; 2398 1.1 mrg virtual streambuf* setbuf(char_type* __s, streamsize __n) override; 2399 1.1 mrg 2400 1.1 mrg private: 2401 1.1 mrg static io_context& 2402 1.1 mrg _S_ctx() 2403 1.1 mrg { 2404 1.1 mrg static io_context __ctx; 2405 1.1 mrg return __ctx; 2406 1.1 mrg } 2407 1.1 mrg 2408 1.1 mrg basic_stream_socket<protocol_type> _M_socket; 2409 1.1 mrg error_code _M_ec; 2410 1.1 mrg time_point _M_expiry{ time_point::max() }; 2411 1.1 mrg }; 2412 1.1 mrg 2413 1.1 mrg template<typename _Protocol, class _Clock, typename _WaitTraits> 2414 1.1 mrg class basic_socket_iostream : public basic_iostream<char> 2415 1.1 mrg { 2416 1.1 mrg using __streambuf_type 2417 1.1 mrg = basic_socket_streambuf<_Protocol, _Clock, _WaitTraits>; 2418 1.1 mrg 2419 1.1 mrg public: 2420 1.1 mrg // types: 2421 1.1 mrg 2422 1.1.1.4 mrg using protocol_type = _Protocol; 2423 1.1.1.4 mrg using endpoint_type = typename protocol_type::endpoint; 2424 1.1.1.4 mrg using clock_type = _Clock; 2425 1.1.1.4 mrg using time_point = typename clock_type::time_point; 2426 1.1.1.4 mrg using duration = typename clock_type::duration; 2427 1.1.1.4 mrg using wait_traits_type = _WaitTraits; 2428 1.1 mrg 2429 1.1 mrg // construct / copy / destroy: 2430 1.1 mrg 2431 1.1 mrg // TODO base-from-member ? 2432 1.1 mrg basic_socket_iostream() : basic_iostream(nullptr), _M_sb() 2433 1.1 mrg { 2434 1.1 mrg this->init(std::addressof(_M_sb)); 2435 1.1 mrg this->setf(std::ios::unitbuf); 2436 1.1 mrg } 2437 1.1 mrg 2438 1.1 mrg explicit 2439 1.1 mrg basic_socket_iostream(basic_stream_socket<protocol_type> __s) 2440 1.1 mrg : basic_iostream(nullptr), _M_sb(std::move(__s)) 2441 1.1 mrg { 2442 1.1 mrg this->init(std::addressof(_M_sb)); 2443 1.1 mrg this->setf(std::ios::unitbuf); 2444 1.1 mrg } 2445 1.1 mrg 2446 1.1 mrg basic_socket_iostream(const basic_socket_iostream&) = delete; 2447 1.1 mrg 2448 1.1 mrg basic_socket_iostream(basic_socket_iostream&& __rhs) 2449 1.1 mrg : basic_iostream(nullptr), _M_sb(std::move(__rhs._M_sb)) 2450 1.1 mrg // XXX ??? ^^^^^^^ 2451 1.1 mrg { 2452 1.1 mrg // XXX ??? this->init(std::addressof(_M_sb)); 2453 1.1 mrg this->set_rbduf(std::addressof(_M_sb)); 2454 1.1 mrg } 2455 1.1 mrg 2456 1.1 mrg template<typename... _Args> 2457 1.1 mrg explicit 2458 1.1 mrg basic_socket_iostream(_Args&&... __args) 2459 1.1 mrg : basic_iostream(nullptr), _M_sb() 2460 1.1 mrg { 2461 1.1 mrg this->init(std::addressof(_M_sb)); 2462 1.1 mrg this->setf(std::ios::unitbuf); 2463 1.1 mrg connect(forward<_Args>(__args)...); 2464 1.1 mrg } 2465 1.1 mrg 2466 1.1 mrg basic_socket_iostream& operator=(const basic_socket_iostream&) = delete; 2467 1.1 mrg 2468 1.1 mrg basic_socket_iostream& operator=(basic_socket_iostream&& __rhs); // TODO 2469 1.1 mrg 2470 1.1 mrg // members: 2471 1.1 mrg 2472 1.1 mrg template<typename... _Args> 2473 1.1 mrg void 2474 1.1 mrg connect(_Args&&... __args) 2475 1.1 mrg { 2476 1.1 mrg if (rdbuf()->connect(forward<_Args>(__args)...) == nullptr) 2477 1.1 mrg this->setstate(failbit); 2478 1.1 mrg } 2479 1.1 mrg 2480 1.1 mrg void 2481 1.1 mrg close() 2482 1.1 mrg { 2483 1.1 mrg if (rdbuf()->close() == nullptr) 2484 1.1 mrg this->setstate(failbit); 2485 1.1 mrg } 2486 1.1 mrg 2487 1.1 mrg basic_socket_streambuf<protocol_type, clock_type, wait_traits_type>* 2488 1.1 mrg rdbuf() const 2489 1.1 mrg { return const_cast<__streambuf_type*>(std::addressof(_M_sb)); } 2490 1.1 mrg 2491 1.1 mrg basic_socket<protocol_type>& socket() { return rdbuf()->socket(); } 2492 1.1.1.2 mrg error_code error() const noexcept { return rdbuf()->error(); } 2493 1.1 mrg 2494 1.1 mrg time_point expiry() const { return rdbuf()->expiry(); } 2495 1.1 mrg void expires_at(const time_point& __t) { rdbuf()->expires_at(__t); } 2496 1.1 mrg void expires_after(const duration& __d) { rdbuf()->expires_after(__d); } 2497 1.1 mrg 2498 1.1 mrg private: 2499 1.1 mrg __streambuf_type _M_sb; 2500 1.1 mrg }; 2501 1.1 mrg 2502 1.1.1.3 mrg /// @} 2503 1.1 mrg 2504 1.1 mrg /** @brief synchronous connect operations 2505 1.1 mrg * @{ 2506 1.1 mrg */ 2507 1.1 mrg 2508 1.1 mrg template<typename _Protocol, typename _EndpointSequence, 2509 1.1 mrg typename _ConnectCondition> 2510 1.1 mrg inline typename _Protocol::endpoint 2511 1.1 mrg connect(basic_socket<_Protocol>& __s, 2512 1.1 mrg const _EndpointSequence& __endpoints, 2513 1.1 mrg _ConnectCondition __c, error_code& __ec) 2514 1.1 mrg { 2515 1.1 mrg __ec.clear(); 2516 1.1 mrg bool __found = false; 2517 1.1 mrg for (auto& __ep : __endpoints) 2518 1.1 mrg { 2519 1.1 mrg if (__c(__ec, __ep)) 2520 1.1 mrg { 2521 1.1 mrg __found = true; 2522 1.1 mrg __s.close(__ec); 2523 1.1 mrg if (!__ec) 2524 1.1 mrg __s.open(__ep.protocol(), __ec); 2525 1.1 mrg if (!__ec) 2526 1.1 mrg __s.connect(__ep, __ec); 2527 1.1 mrg if (!__ec) 2528 1.1 mrg return __ep; 2529 1.1 mrg } 2530 1.1 mrg } 2531 1.1 mrg if (!__found) 2532 1.1 mrg __ec = socket_errc::not_found; 2533 1.1 mrg return typename _Protocol::endpoint{}; 2534 1.1 mrg } 2535 1.1 mrg 2536 1.1 mrg template<typename _Protocol, typename _InputIterator, 2537 1.1 mrg typename _ConnectCondition> 2538 1.1 mrg inline _InputIterator 2539 1.1 mrg connect(basic_socket<_Protocol>& __s, 2540 1.1 mrg _InputIterator __first, _InputIterator __last, 2541 1.1 mrg _ConnectCondition __c, error_code& __ec) 2542 1.1 mrg { 2543 1.1 mrg __ec.clear(); 2544 1.1 mrg bool __found = false; 2545 1.1 mrg for (auto __i = __first; __i != __last; ++__i) 2546 1.1 mrg { 2547 1.1 mrg if (__c(__ec, *__i)) 2548 1.1 mrg { 2549 1.1 mrg __found = true; 2550 1.1 mrg __s.close(__ec); 2551 1.1 mrg if (!__ec) 2552 1.1 mrg __s.open(typename _Protocol::endpoint(*__i).protocol(), __ec); 2553 1.1 mrg if (!__ec) 2554 1.1 mrg __s.connect(*__i, __ec); 2555 1.1 mrg if (!__ec) 2556 1.1 mrg return __i; 2557 1.1 mrg } 2558 1.1 mrg } 2559 1.1 mrg if (!__found) 2560 1.1 mrg __ec = socket_errc::not_found; 2561 1.1 mrg return __last; 2562 1.1 mrg } 2563 1.1 mrg 2564 1.1 mrg template<typename _Protocol, typename _EndpointSequence, 2565 1.1 mrg typename _ConnectCondition> 2566 1.1 mrg inline typename _Protocol::endpoint 2567 1.1 mrg connect(basic_socket<_Protocol>& __s, 2568 1.1 mrg const _EndpointSequence& __endpoints, 2569 1.1 mrg _ConnectCondition __c) 2570 1.1 mrg { 2571 1.1 mrg return net::connect(__s, __endpoints, __c, __throw_on_error{"connect"}); 2572 1.1 mrg } 2573 1.1 mrg 2574 1.1 mrg template<typename _Protocol, typename _InputIterator, 2575 1.1 mrg typename _ConnectCondition> 2576 1.1 mrg inline _InputIterator 2577 1.1 mrg connect(basic_socket<_Protocol>& __s, 2578 1.1 mrg _InputIterator __first, _InputIterator __last, 2579 1.1 mrg _ConnectCondition __c) 2580 1.1 mrg { 2581 1.1 mrg return net::connect(__s, __first, __last, __c, 2582 1.1 mrg __throw_on_error{"connect"}); 2583 1.1 mrg } 2584 1.1 mrg 2585 1.1 mrg template<typename _Protocol, typename _EndpointSequence> 2586 1.1 mrg inline typename _Protocol::endpoint 2587 1.1 mrg connect(basic_socket<_Protocol>& __s, 2588 1.1 mrg const _EndpointSequence& __endpoints) 2589 1.1 mrg { 2590 1.1 mrg return net::connect(__s, __endpoints, [](auto, auto){ return true; }, 2591 1.1 mrg __throw_on_error{"connect"}); 2592 1.1 mrg } 2593 1.1 mrg 2594 1.1 mrg template<typename _Protocol, typename _EndpointSequence> 2595 1.1 mrg inline typename _Protocol::endpoint 2596 1.1 mrg connect(basic_socket<_Protocol>& __s, 2597 1.1 mrg const _EndpointSequence& __endpoints, 2598 1.1 mrg error_code& __ec) 2599 1.1 mrg { 2600 1.1 mrg return net::connect(__s, __endpoints, [](auto, auto){ return true; }, 2601 1.1 mrg __ec); 2602 1.1 mrg } 2603 1.1 mrg 2604 1.1 mrg template<typename _Protocol, typename _InputIterator> 2605 1.1 mrg inline _InputIterator 2606 1.1 mrg connect(basic_socket<_Protocol>& __s, 2607 1.1 mrg _InputIterator __first, _InputIterator __last) 2608 1.1 mrg { 2609 1.1 mrg return net::connect(__s, __first, __last, [](auto, auto){ return true; }, 2610 1.1 mrg __throw_on_error{"connect"}); 2611 1.1 mrg } 2612 1.1 mrg 2613 1.1 mrg template<typename _Protocol, typename _InputIterator> 2614 1.1 mrg inline _InputIterator 2615 1.1 mrg connect(basic_socket<_Protocol>& __s, 2616 1.1 mrg _InputIterator __first, _InputIterator __last, 2617 1.1 mrg error_code& __ec) 2618 1.1 mrg { 2619 1.1 mrg return net::connect(__s, __first, __last, [](auto, auto){ return true; }, 2620 1.1 mrg __ec); 2621 1.1 mrg } 2622 1.1 mrg 2623 1.1.1.3 mrg /// @} 2624 1.1 mrg 2625 1.1 mrg /** @brief asynchronous connect operations 2626 1.1 mrg * @{ 2627 1.1 mrg */ 2628 1.1 mrg 2629 1.1 mrg template<typename _Protocol, typename _EndpointSequence, 2630 1.1 mrg typename _ConnectCondition, typename _CompletionToken> 2631 1.1 mrg inline 2632 1.1 mrg __deduced_t<_CompletionToken, 2633 1.1 mrg void(error_code, typename _Protocol::endpoint)> 2634 1.1 mrg async_connect(basic_socket<_Protocol>& __s, 2635 1.1 mrg const _EndpointSequence& __endpoints, 2636 1.1 mrg _ConnectCondition __c, _CompletionToken&& __token); // TODO 2637 1.1 mrg 2638 1.1 mrg template<typename _Protocol, typename _EndpointSequence, 2639 1.1 mrg typename _CompletionToken> 2640 1.1 mrg inline 2641 1.1 mrg __deduced_t<_CompletionToken, 2642 1.1 mrg void(error_code, typename _Protocol::endpoint)> 2643 1.1 mrg async_connect(basic_socket<_Protocol>& __s, 2644 1.1 mrg const _EndpointSequence& __endpoints, 2645 1.1 mrg _CompletionToken&& __token) 2646 1.1 mrg { 2647 1.1 mrg return net::async_connect(__s, __endpoints, 2648 1.1 mrg [](auto, auto){ return true; }, 2649 1.1 mrg forward<_CompletionToken>(__token)); 2650 1.1 mrg } 2651 1.1 mrg 2652 1.1 mrg template<typename _Protocol, typename _InputIterator, 2653 1.1 mrg typename _ConnectCondition, typename _CompletionToken> 2654 1.1 mrg inline 2655 1.1 mrg __deduced_t<_CompletionToken, void(error_code, _InputIterator)> 2656 1.1 mrg async_connect(basic_socket<_Protocol>& __s, 2657 1.1 mrg _InputIterator __first, _InputIterator __last, 2658 1.1 mrg _ConnectCondition __c, _CompletionToken&& __token); // TODO 2659 1.1 mrg 2660 1.1 mrg template<typename _Protocol, typename _InputIterator, 2661 1.1 mrg typename _CompletionToken> 2662 1.1 mrg inline 2663 1.1 mrg __deduced_t<_CompletionToken, void(error_code, _InputIterator)> 2664 1.1 mrg async_connect(basic_socket<_Protocol>& __s, 2665 1.1 mrg _InputIterator __first, _InputIterator __last, 2666 1.1 mrg _CompletionToken&& __token) 2667 1.1 mrg { 2668 1.1 mrg return net::async_connect(__s, __first, __last, 2669 1.1 mrg [](auto, auto){ return true; }, 2670 1.1 mrg forward<_CompletionToken>(__token)); 2671 1.1 mrg } 2672 1.1 mrg 2673 1.1.1.3 mrg /// @} 2674 1.1 mrg 2675 1.1 mrg #endif // _GLIBCXX_HAVE_UNISTD_H 2676 1.1 mrg 2677 1.1.1.3 mrg /// @} 2678 1.1 mrg 2679 1.1 mrg } // namespace v1 2680 1.1 mrg } // namespace net 2681 1.1 mrg } // namespace experimental 2682 1.1 mrg 2683 1.1 mrg _GLIBCXX_END_NAMESPACE_VERSION 2684 1.1 mrg } // namespace std 2685 1.1 mrg 2686 1.1 mrg #endif // C++14 2687 1.1 mrg 2688 1.1 mrg #endif // _GLIBCXX_EXPERIMENTAL_SOCKET 2689