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