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