descriptor_ops.ipp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. //
  2. // detail/impl/descriptor_ops.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP
  11. #define ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #include <cerrno>
  17. #include "asio/detail/descriptor_ops.hpp"
  18. #include "asio/error.hpp"
  19. #if !defined(ASIO_WINDOWS) \
  20. && !defined(ASIO_WINDOWS_RUNTIME) \
  21. && !defined(__CYGWIN__)
  22. #include "asio/detail/push_options.hpp"
  23. namespace asio {
  24. namespace detail {
  25. namespace descriptor_ops {
  26. int open(const char* path, int flags, asio::error_code& ec)
  27. {
  28. errno = 0;
  29. int result = error_wrapper(::open(path, flags), ec);
  30. if (result >= 0)
  31. ec = asio::error_code();
  32. return result;
  33. }
  34. int close(int d, state_type& state, asio::error_code& ec)
  35. {
  36. int result = 0;
  37. if (d != -1)
  38. {
  39. errno = 0;
  40. result = error_wrapper(::close(d), ec);
  41. if (result != 0
  42. && (ec == asio::error::would_block
  43. || ec == asio::error::try_again))
  44. {
  45. // According to UNIX Network Programming Vol. 1, it is possible for
  46. // close() to fail with EWOULDBLOCK under certain circumstances. What
  47. // isn't clear is the state of the descriptor after this error. The one
  48. // current OS where this behaviour is seen, Windows, says that the socket
  49. // remains open. Therefore we'll put the descriptor back into blocking
  50. // mode and have another attempt at closing it.
  51. #if defined(__SYMBIAN32__)
  52. int flags = ::fcntl(d, F_GETFL, 0);
  53. if (flags >= 0)
  54. ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK);
  55. #else // defined(__SYMBIAN32__)
  56. ioctl_arg_type arg = 0;
  57. ::ioctl(d, FIONBIO, &arg);
  58. #endif // defined(__SYMBIAN32__)
  59. state &= ~non_blocking;
  60. errno = 0;
  61. result = error_wrapper(::close(d), ec);
  62. }
  63. }
  64. if (result == 0)
  65. ec = asio::error_code();
  66. return result;
  67. }
  68. bool set_user_non_blocking(int d, state_type& state,
  69. bool value, asio::error_code& ec)
  70. {
  71. if (d == -1)
  72. {
  73. ec = asio::error::bad_descriptor;
  74. return false;
  75. }
  76. errno = 0;
  77. #if defined(__SYMBIAN32__)
  78. int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
  79. if (result >= 0)
  80. {
  81. errno = 0;
  82. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  83. result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
  84. }
  85. #else // defined(__SYMBIAN32__)
  86. ioctl_arg_type arg = (value ? 1 : 0);
  87. int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
  88. #endif // defined(__SYMBIAN32__)
  89. if (result >= 0)
  90. {
  91. ec = asio::error_code();
  92. if (value)
  93. state |= user_set_non_blocking;
  94. else
  95. {
  96. // Clearing the user-set non-blocking mode always overrides any
  97. // internally-set non-blocking flag. Any subsequent asynchronous
  98. // operations will need to re-enable non-blocking I/O.
  99. state &= ~(user_set_non_blocking | internal_non_blocking);
  100. }
  101. return true;
  102. }
  103. return false;
  104. }
  105. bool set_internal_non_blocking(int d, state_type& state,
  106. bool value, asio::error_code& ec)
  107. {
  108. if (d == -1)
  109. {
  110. ec = asio::error::bad_descriptor;
  111. return false;
  112. }
  113. if (!value && (state & user_set_non_blocking))
  114. {
  115. // It does not make sense to clear the internal non-blocking flag if the
  116. // user still wants non-blocking behaviour. Return an error and let the
  117. // caller figure out whether to update the user-set non-blocking flag.
  118. ec = asio::error::invalid_argument;
  119. return false;
  120. }
  121. errno = 0;
  122. #if defined(__SYMBIAN32__)
  123. int result = error_wrapper(::fcntl(d, F_GETFL, 0), ec);
  124. if (result >= 0)
  125. {
  126. errno = 0;
  127. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  128. result = error_wrapper(::fcntl(d, F_SETFL, flag), ec);
  129. }
  130. #else // defined(__SYMBIAN32__)
  131. ioctl_arg_type arg = (value ? 1 : 0);
  132. int result = error_wrapper(::ioctl(d, FIONBIO, &arg), ec);
  133. #endif // defined(__SYMBIAN32__)
  134. if (result >= 0)
  135. {
  136. ec = asio::error_code();
  137. if (value)
  138. state |= internal_non_blocking;
  139. else
  140. state &= ~internal_non_blocking;
  141. return true;
  142. }
  143. return false;
  144. }
  145. std::size_t sync_read(int d, state_type state, buf* bufs,
  146. std::size_t count, bool all_empty, asio::error_code& ec)
  147. {
  148. if (d == -1)
  149. {
  150. ec = asio::error::bad_descriptor;
  151. return 0;
  152. }
  153. // A request to read 0 bytes on a stream is a no-op.
  154. if (all_empty)
  155. {
  156. ec = asio::error_code();
  157. return 0;
  158. }
  159. // Read some data.
  160. for (;;)
  161. {
  162. // Try to complete the operation without blocking.
  163. errno = 0;
  164. signed_size_type bytes = error_wrapper(::readv(
  165. d, bufs, static_cast<int>(count)), ec);
  166. // Check if operation succeeded.
  167. if (bytes > 0)
  168. return bytes;
  169. // Check for EOF.
  170. if (bytes == 0)
  171. {
  172. ec = asio::error::eof;
  173. return 0;
  174. }
  175. // Operation failed.
  176. if ((state & user_set_non_blocking)
  177. || (ec != asio::error::would_block
  178. && ec != asio::error::try_again))
  179. return 0;
  180. // Wait for descriptor to become ready.
  181. if (descriptor_ops::poll_read(d, 0, ec) < 0)
  182. return 0;
  183. }
  184. }
  185. bool non_blocking_read(int d, buf* bufs, std::size_t count,
  186. asio::error_code& ec, std::size_t& bytes_transferred)
  187. {
  188. for (;;)
  189. {
  190. // Read some data.
  191. errno = 0;
  192. signed_size_type bytes = error_wrapper(::readv(
  193. d, bufs, static_cast<int>(count)), ec);
  194. // Check for end of stream.
  195. if (bytes == 0)
  196. {
  197. ec = asio::error::eof;
  198. return true;
  199. }
  200. // Retry operation if interrupted by signal.
  201. if (ec == asio::error::interrupted)
  202. continue;
  203. // Check if we need to run the operation again.
  204. if (ec == asio::error::would_block
  205. || ec == asio::error::try_again)
  206. return false;
  207. // Operation is complete.
  208. if (bytes > 0)
  209. {
  210. ec = asio::error_code();
  211. bytes_transferred = bytes;
  212. }
  213. else
  214. bytes_transferred = 0;
  215. return true;
  216. }
  217. }
  218. std::size_t sync_write(int d, state_type state, const buf* bufs,
  219. std::size_t count, bool all_empty, asio::error_code& ec)
  220. {
  221. if (d == -1)
  222. {
  223. ec = asio::error::bad_descriptor;
  224. return 0;
  225. }
  226. // A request to write 0 bytes on a stream is a no-op.
  227. if (all_empty)
  228. {
  229. ec = asio::error_code();
  230. return 0;
  231. }
  232. // Write some data.
  233. for (;;)
  234. {
  235. // Try to complete the operation without blocking.
  236. errno = 0;
  237. signed_size_type bytes = error_wrapper(::writev(
  238. d, bufs, static_cast<int>(count)), ec);
  239. // Check if operation succeeded.
  240. if (bytes > 0)
  241. return bytes;
  242. // Operation failed.
  243. if ((state & user_set_non_blocking)
  244. || (ec != asio::error::would_block
  245. && ec != asio::error::try_again))
  246. return 0;
  247. // Wait for descriptor to become ready.
  248. if (descriptor_ops::poll_write(d, 0, ec) < 0)
  249. return 0;
  250. }
  251. }
  252. bool non_blocking_write(int d, const buf* bufs, std::size_t count,
  253. asio::error_code& ec, std::size_t& bytes_transferred)
  254. {
  255. for (;;)
  256. {
  257. // Write some data.
  258. errno = 0;
  259. signed_size_type bytes = error_wrapper(::writev(
  260. d, bufs, static_cast<int>(count)), ec);
  261. // Retry operation if interrupted by signal.
  262. if (ec == asio::error::interrupted)
  263. continue;
  264. // Check if we need to run the operation again.
  265. if (ec == asio::error::would_block
  266. || ec == asio::error::try_again)
  267. return false;
  268. // Operation is complete.
  269. if (bytes >= 0)
  270. {
  271. ec = asio::error_code();
  272. bytes_transferred = bytes;
  273. }
  274. else
  275. bytes_transferred = 0;
  276. return true;
  277. }
  278. }
  279. int ioctl(int d, state_type& state, long cmd,
  280. ioctl_arg_type* arg, asio::error_code& ec)
  281. {
  282. if (d == -1)
  283. {
  284. ec = asio::error::bad_descriptor;
  285. return -1;
  286. }
  287. errno = 0;
  288. int result = error_wrapper(::ioctl(d, cmd, arg), ec);
  289. if (result >= 0)
  290. {
  291. ec = asio::error_code();
  292. // When updating the non-blocking mode we always perform the ioctl syscall,
  293. // even if the flags would otherwise indicate that the descriptor is
  294. // already in the correct state. This ensures that the underlying
  295. // descriptor is put into the state that has been requested by the user. If
  296. // the ioctl syscall was successful then we need to update the flags to
  297. // match.
  298. if (cmd == static_cast<long>(FIONBIO))
  299. {
  300. if (*arg)
  301. {
  302. state |= user_set_non_blocking;
  303. }
  304. else
  305. {
  306. // Clearing the non-blocking mode always overrides any internally-set
  307. // non-blocking flag. Any subsequent asynchronous operations will need
  308. // to re-enable non-blocking I/O.
  309. state &= ~(user_set_non_blocking | internal_non_blocking);
  310. }
  311. }
  312. }
  313. return result;
  314. }
  315. int fcntl(int d, int cmd, asio::error_code& ec)
  316. {
  317. if (d == -1)
  318. {
  319. ec = asio::error::bad_descriptor;
  320. return -1;
  321. }
  322. errno = 0;
  323. int result = error_wrapper(::fcntl(d, cmd), ec);
  324. if (result != -1)
  325. ec = asio::error_code();
  326. return result;
  327. }
  328. int fcntl(int d, int cmd, long arg, asio::error_code& ec)
  329. {
  330. if (d == -1)
  331. {
  332. ec = asio::error::bad_descriptor;
  333. return -1;
  334. }
  335. errno = 0;
  336. int result = error_wrapper(::fcntl(d, cmd, arg), ec);
  337. if (result != -1)
  338. ec = asio::error_code();
  339. return result;
  340. }
  341. int poll_read(int d, state_type state, asio::error_code& ec)
  342. {
  343. if (d == -1)
  344. {
  345. ec = asio::error::bad_descriptor;
  346. return -1;
  347. }
  348. pollfd fds;
  349. fds.fd = d;
  350. fds.events = POLLIN;
  351. fds.revents = 0;
  352. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  353. errno = 0;
  354. int result = error_wrapper(::poll(&fds, 1, timeout), ec);
  355. if (result == 0)
  356. ec = (state & user_set_non_blocking)
  357. ? asio::error::would_block : asio::error_code();
  358. else if (result > 0)
  359. ec = asio::error_code();
  360. return result;
  361. }
  362. int poll_write(int d, state_type state, asio::error_code& ec)
  363. {
  364. if (d == -1)
  365. {
  366. ec = asio::error::bad_descriptor;
  367. return -1;
  368. }
  369. pollfd fds;
  370. fds.fd = d;
  371. fds.events = POLLOUT;
  372. fds.revents = 0;
  373. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  374. errno = 0;
  375. int result = error_wrapper(::poll(&fds, 1, timeout), ec);
  376. if (result == 0)
  377. ec = (state & user_set_non_blocking)
  378. ? asio::error::would_block : asio::error_code();
  379. else if (result > 0)
  380. ec = asio::error_code();
  381. return result;
  382. }
  383. } // namespace descriptor_ops
  384. } // namespace detail
  385. } // namespace asio
  386. #include "asio/detail/pop_options.hpp"
  387. #endif // !defined(ASIO_WINDOWS)
  388. // && !defined(ASIO_WINDOWS_RUNTIME)
  389. // && !defined(__CYGWIN__)
  390. #endif // ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP