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