You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2646 lines
75KB

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