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