descriptor_ops.ipp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970
  1. //
  2. // detail/impl/descriptor_ops.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 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. int result = ::open(path, flags);
  29. get_last_error(ec, result < 0);
  30. return result;
  31. }
  32. int open(const char* path, int flags,
  33. unsigned mode, asio::error_code& ec)
  34. {
  35. int result = ::open(path, flags, mode);
  36. get_last_error(ec, result < 0);
  37. return result;
  38. }
  39. int close(int d, state_type& state, asio::error_code& ec)
  40. {
  41. int result = 0;
  42. if (d != -1)
  43. {
  44. result = ::close(d);
  45. get_last_error(ec, result < 0);
  46. if (result != 0
  47. && (ec == asio::error::would_block
  48. || ec == asio::error::try_again))
  49. {
  50. // According to UNIX Network Programming Vol. 1, it is possible for
  51. // close() to fail with EWOULDBLOCK under certain circumstances. What
  52. // isn't clear is the state of the descriptor after this error. The one
  53. // current OS where this behaviour is seen, Windows, says that the socket
  54. // remains open. Therefore we'll put the descriptor back into blocking
  55. // mode and have another attempt at closing it.
  56. #if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  57. int flags = ::fcntl(d, F_GETFL, 0);
  58. if (flags >= 0)
  59. ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK);
  60. #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  61. ioctl_arg_type arg = 0;
  62. # if defined(ENOTTY)
  63. result = ::ioctl(d, FIONBIO, &arg);
  64. get_last_error(ec, result < 0);
  65. if (ec.value() == ENOTTY)
  66. {
  67. int flags = ::fcntl(d, F_GETFL, 0);
  68. if (flags >= 0)
  69. ::fcntl(d, F_SETFL, flags & ~O_NONBLOCK);
  70. }
  71. # else // defined(ENOTTY)
  72. ::ioctl(d, FIONBIO, &arg);
  73. # endif // defined(ENOTTY)
  74. #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  75. state &= ~non_blocking;
  76. result = ::close(d);
  77. get_last_error(ec, result < 0);
  78. }
  79. }
  80. return result;
  81. }
  82. bool set_user_non_blocking(int d, state_type& state,
  83. bool value, asio::error_code& ec)
  84. {
  85. if (d == -1)
  86. {
  87. ec = asio::error::bad_descriptor;
  88. return false;
  89. }
  90. #if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  91. int result = ::fcntl(d, F_GETFL, 0);
  92. get_last_error(ec, result < 0);
  93. if (result >= 0)
  94. {
  95. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  96. result = ::fcntl(d, F_SETFL, flag);
  97. get_last_error(ec, result < 0);
  98. }
  99. #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  100. ioctl_arg_type arg = (value ? 1 : 0);
  101. int result = ::ioctl(d, FIONBIO, &arg);
  102. get_last_error(ec, result < 0);
  103. # if defined(ENOTTY)
  104. if (ec.value() == ENOTTY)
  105. {
  106. result = ::fcntl(d, F_GETFL, 0);
  107. get_last_error(ec, result < 0);
  108. if (result >= 0)
  109. {
  110. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  111. result = ::fcntl(d, F_SETFL, flag);
  112. get_last_error(ec, result < 0);
  113. }
  114. }
  115. # endif // defined(ENOTTY)
  116. #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  117. if (result >= 0)
  118. {
  119. if (value)
  120. state |= user_set_non_blocking;
  121. else
  122. {
  123. // Clearing the user-set non-blocking mode always overrides any
  124. // internally-set non-blocking flag. Any subsequent asynchronous
  125. // operations will need to re-enable non-blocking I/O.
  126. state &= ~(user_set_non_blocking | internal_non_blocking);
  127. }
  128. return true;
  129. }
  130. return false;
  131. }
  132. bool set_internal_non_blocking(int d, state_type& state,
  133. bool value, asio::error_code& ec)
  134. {
  135. if (d == -1)
  136. {
  137. ec = asio::error::bad_descriptor;
  138. return false;
  139. }
  140. if (!value && (state & user_set_non_blocking))
  141. {
  142. // It does not make sense to clear the internal non-blocking flag if the
  143. // user still wants non-blocking behaviour. Return an error and let the
  144. // caller figure out whether to update the user-set non-blocking flag.
  145. ec = asio::error::invalid_argument;
  146. return false;
  147. }
  148. #if defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  149. int result = ::fcntl(d, F_GETFL, 0);
  150. get_last_error(ec, result < 0);
  151. if (result >= 0)
  152. {
  153. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  154. result = ::fcntl(d, F_SETFL, flag);
  155. get_last_error(ec, result < 0);
  156. }
  157. #else // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  158. ioctl_arg_type arg = (value ? 1 : 0);
  159. int result = ::ioctl(d, FIONBIO, &arg);
  160. get_last_error(ec, result < 0);
  161. # if defined(ENOTTY)
  162. if (ec.value() == ENOTTY)
  163. {
  164. result = ::fcntl(d, F_GETFL, 0);
  165. get_last_error(ec, result < 0);
  166. if (result >= 0)
  167. {
  168. int flag = (value ? (result | O_NONBLOCK) : (result & ~O_NONBLOCK));
  169. result = ::fcntl(d, F_SETFL, flag);
  170. get_last_error(ec, result < 0);
  171. }
  172. }
  173. # endif // defined(ENOTTY)
  174. #endif // defined(__SYMBIAN32__) || defined(__EMSCRIPTEN__)
  175. if (result >= 0)
  176. {
  177. if (value)
  178. state |= internal_non_blocking;
  179. else
  180. state &= ~internal_non_blocking;
  181. return true;
  182. }
  183. return false;
  184. }
  185. std::size_t sync_read(int d, state_type state, buf* bufs,
  186. std::size_t count, bool all_empty, asio::error_code& ec)
  187. {
  188. if (d == -1)
  189. {
  190. ec = asio::error::bad_descriptor;
  191. return 0;
  192. }
  193. // A request to read 0 bytes on a stream is a no-op.
  194. if (all_empty)
  195. {
  196. asio::error::clear(ec);
  197. return 0;
  198. }
  199. // Read some data.
  200. for (;;)
  201. {
  202. // Try to complete the operation without blocking.
  203. signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
  204. get_last_error(ec, bytes < 0);
  205. // Check if operation succeeded.
  206. if (bytes > 0)
  207. return bytes;
  208. // Check for EOF.
  209. if (bytes == 0)
  210. {
  211. ec = asio::error::eof;
  212. return 0;
  213. }
  214. // Operation failed.
  215. if ((state & user_set_non_blocking)
  216. || (ec != asio::error::would_block
  217. && ec != asio::error::try_again))
  218. return 0;
  219. // Wait for descriptor to become ready.
  220. if (descriptor_ops::poll_read(d, 0, ec) < 0)
  221. return 0;
  222. }
  223. }
  224. std::size_t sync_read1(int d, state_type state, void* data,
  225. std::size_t size, asio::error_code& ec)
  226. {
  227. if (d == -1)
  228. {
  229. ec = asio::error::bad_descriptor;
  230. return 0;
  231. }
  232. // A request to read 0 bytes on a stream is a no-op.
  233. if (size == 0)
  234. {
  235. asio::error::clear(ec);
  236. return 0;
  237. }
  238. // Read some data.
  239. for (;;)
  240. {
  241. // Try to complete the operation without blocking.
  242. signed_size_type bytes = ::read(d, data, size);
  243. get_last_error(ec, bytes < 0);
  244. // Check if operation succeeded.
  245. if (bytes > 0)
  246. return bytes;
  247. // Check for EOF.
  248. if (bytes == 0)
  249. {
  250. ec = asio::error::eof;
  251. return 0;
  252. }
  253. // Operation failed.
  254. if ((state & user_set_non_blocking)
  255. || (ec != asio::error::would_block
  256. && ec != asio::error::try_again))
  257. return 0;
  258. // Wait for descriptor to become ready.
  259. if (descriptor_ops::poll_read(d, 0, ec) < 0)
  260. return 0;
  261. }
  262. }
  263. bool non_blocking_read(int d, buf* bufs, std::size_t count,
  264. asio::error_code& ec, std::size_t& bytes_transferred)
  265. {
  266. for (;;)
  267. {
  268. // Read some data.
  269. signed_size_type bytes = ::readv(d, bufs, static_cast<int>(count));
  270. get_last_error(ec, bytes < 0);
  271. // Check for end of stream.
  272. if (bytes == 0)
  273. {
  274. ec = asio::error::eof;
  275. return true;
  276. }
  277. // Check if operation succeeded.
  278. if (bytes > 0)
  279. {
  280. bytes_transferred = bytes;
  281. return true;
  282. }
  283. // Retry operation if interrupted by signal.
  284. if (ec == asio::error::interrupted)
  285. continue;
  286. // Check if we need to run the operation again.
  287. if (ec == asio::error::would_block
  288. || ec == asio::error::try_again)
  289. return false;
  290. // Operation failed.
  291. bytes_transferred = 0;
  292. return true;
  293. }
  294. }
  295. bool non_blocking_read1(int d, void* data, std::size_t size,
  296. asio::error_code& ec, std::size_t& bytes_transferred)
  297. {
  298. for (;;)
  299. {
  300. // Read some data.
  301. signed_size_type bytes = ::read(d, data, size);
  302. get_last_error(ec, bytes < 0);
  303. // Check for end of stream.
  304. if (bytes == 0)
  305. {
  306. ec = asio::error::eof;
  307. return true;
  308. }
  309. // Check if operation succeeded.
  310. if (bytes > 0)
  311. {
  312. bytes_transferred = bytes;
  313. return true;
  314. }
  315. // Retry operation if interrupted by signal.
  316. if (ec == asio::error::interrupted)
  317. continue;
  318. // Check if we need to run the operation again.
  319. if (ec == asio::error::would_block
  320. || ec == asio::error::try_again)
  321. return false;
  322. // Operation failed.
  323. bytes_transferred = 0;
  324. return true;
  325. }
  326. }
  327. std::size_t sync_write(int d, state_type state, const buf* bufs,
  328. std::size_t count, bool all_empty, asio::error_code& ec)
  329. {
  330. if (d == -1)
  331. {
  332. ec = asio::error::bad_descriptor;
  333. return 0;
  334. }
  335. // A request to write 0 bytes on a stream is a no-op.
  336. if (all_empty)
  337. {
  338. asio::error::clear(ec);
  339. return 0;
  340. }
  341. // Write some data.
  342. for (;;)
  343. {
  344. // Try to complete the operation without blocking.
  345. signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
  346. get_last_error(ec, bytes < 0);
  347. // Check if operation succeeded.
  348. if (bytes > 0)
  349. return bytes;
  350. // Operation failed.
  351. if ((state & user_set_non_blocking)
  352. || (ec != asio::error::would_block
  353. && ec != asio::error::try_again))
  354. return 0;
  355. // Wait for descriptor to become ready.
  356. if (descriptor_ops::poll_write(d, 0, ec) < 0)
  357. return 0;
  358. }
  359. }
  360. std::size_t sync_write1(int d, state_type state, const void* data,
  361. std::size_t size, asio::error_code& ec)
  362. {
  363. if (d == -1)
  364. {
  365. ec = asio::error::bad_descriptor;
  366. return 0;
  367. }
  368. // A request to write 0 bytes on a stream is a no-op.
  369. if (size == 0)
  370. {
  371. asio::error::clear(ec);
  372. return 0;
  373. }
  374. // Write some data.
  375. for (;;)
  376. {
  377. // Try to complete the operation without blocking.
  378. signed_size_type bytes = ::write(d, data, size);
  379. get_last_error(ec, bytes < 0);
  380. // Check if operation succeeded.
  381. if (bytes > 0)
  382. return bytes;
  383. // Operation failed.
  384. if ((state & user_set_non_blocking)
  385. || (ec != asio::error::would_block
  386. && ec != asio::error::try_again))
  387. return 0;
  388. // Wait for descriptor to become ready.
  389. if (descriptor_ops::poll_write(d, 0, ec) < 0)
  390. return 0;
  391. }
  392. }
  393. bool non_blocking_write(int d, const buf* bufs, std::size_t count,
  394. asio::error_code& ec, std::size_t& bytes_transferred)
  395. {
  396. for (;;)
  397. {
  398. // Write some data.
  399. signed_size_type bytes = ::writev(d, bufs, static_cast<int>(count));
  400. get_last_error(ec, bytes < 0);
  401. // Check if operation succeeded.
  402. if (bytes >= 0)
  403. {
  404. bytes_transferred = bytes;
  405. return true;
  406. }
  407. // Retry operation if interrupted by signal.
  408. if (ec == asio::error::interrupted)
  409. continue;
  410. // Check if we need to run the operation again.
  411. if (ec == asio::error::would_block
  412. || ec == asio::error::try_again)
  413. return false;
  414. // Operation failed.
  415. bytes_transferred = 0;
  416. return true;
  417. }
  418. }
  419. bool non_blocking_write1(int d, const void* data, std::size_t size,
  420. asio::error_code& ec, std::size_t& bytes_transferred)
  421. {
  422. for (;;)
  423. {
  424. // Write some data.
  425. signed_size_type bytes = ::write(d, data, size);
  426. get_last_error(ec, bytes < 0);
  427. // Check if operation succeeded.
  428. if (bytes >= 0)
  429. {
  430. bytes_transferred = bytes;
  431. return true;
  432. }
  433. // Retry operation if interrupted by signal.
  434. if (ec == asio::error::interrupted)
  435. continue;
  436. // Check if we need to run the operation again.
  437. if (ec == asio::error::would_block
  438. || ec == asio::error::try_again)
  439. return false;
  440. // Operation failed.
  441. bytes_transferred = 0;
  442. return true;
  443. }
  444. }
  445. #if defined(ASIO_HAS_FILE)
  446. std::size_t sync_read_at(int d, state_type state, uint64_t offset,
  447. buf* bufs, std::size_t count, bool all_empty, asio::error_code& ec)
  448. {
  449. if (d == -1)
  450. {
  451. ec = asio::error::bad_descriptor;
  452. return 0;
  453. }
  454. // A request to read 0 bytes on a stream is a no-op.
  455. if (all_empty)
  456. {
  457. asio::error::clear(ec);
  458. return 0;
  459. }
  460. // Read some data.
  461. for (;;)
  462. {
  463. // Try to complete the operation without blocking.
  464. signed_size_type bytes = ::preadv(d, bufs, static_cast<int>(count), offset);
  465. get_last_error(ec, bytes < 0);
  466. // Check if operation succeeded.
  467. if (bytes > 0)
  468. return bytes;
  469. // Check for EOF.
  470. if (bytes == 0)
  471. {
  472. ec = asio::error::eof;
  473. return 0;
  474. }
  475. // Operation failed.
  476. if ((state & user_set_non_blocking)
  477. || (ec != asio::error::would_block
  478. && ec != asio::error::try_again))
  479. return 0;
  480. // Wait for descriptor to become ready.
  481. if (descriptor_ops::poll_read(d, 0, ec) < 0)
  482. return 0;
  483. }
  484. }
  485. std::size_t sync_read_at1(int d, state_type state, uint64_t offset,
  486. void* data, std::size_t size, asio::error_code& ec)
  487. {
  488. if (d == -1)
  489. {
  490. ec = asio::error::bad_descriptor;
  491. return 0;
  492. }
  493. // A request to read 0 bytes on a stream is a no-op.
  494. if (size == 0)
  495. {
  496. asio::error::clear(ec);
  497. return 0;
  498. }
  499. // Read some data.
  500. for (;;)
  501. {
  502. // Try to complete the operation without blocking.
  503. signed_size_type bytes = ::pread(d, data, size, offset);
  504. get_last_error(ec, bytes < 0);
  505. // Check if operation succeeded.
  506. if (bytes > 0)
  507. return bytes;
  508. // Check for EOF.
  509. if (bytes == 0)
  510. {
  511. ec = asio::error::eof;
  512. return 0;
  513. }
  514. // Operation failed.
  515. if ((state & user_set_non_blocking)
  516. || (ec != asio::error::would_block
  517. && ec != asio::error::try_again))
  518. return 0;
  519. // Wait for descriptor to become ready.
  520. if (descriptor_ops::poll_read(d, 0, ec) < 0)
  521. return 0;
  522. }
  523. }
  524. bool non_blocking_read_at(int d, uint64_t offset, buf* bufs, std::size_t count,
  525. asio::error_code& ec, std::size_t& bytes_transferred)
  526. {
  527. for (;;)
  528. {
  529. // Read some data.
  530. signed_size_type bytes = ::preadv(d, bufs, static_cast<int>(count), offset);
  531. get_last_error(ec, bytes < 0);
  532. // Check for EOF.
  533. if (bytes == 0)
  534. {
  535. ec = asio::error::eof;
  536. return true;
  537. }
  538. // Check if operation succeeded.
  539. if (bytes > 0)
  540. {
  541. bytes_transferred = bytes;
  542. return true;
  543. }
  544. // Retry operation if interrupted by signal.
  545. if (ec == asio::error::interrupted)
  546. continue;
  547. // Check if we need to run the operation again.
  548. if (ec == asio::error::would_block
  549. || ec == asio::error::try_again)
  550. return false;
  551. // Operation failed.
  552. bytes_transferred = 0;
  553. return true;
  554. }
  555. }
  556. bool non_blocking_read_at1(int d, uint64_t offset, void* data, std::size_t size,
  557. asio::error_code& ec, std::size_t& bytes_transferred)
  558. {
  559. for (;;)
  560. {
  561. // Read some data.
  562. signed_size_type bytes = ::pread(d, data, size, offset);
  563. get_last_error(ec, bytes < 0);
  564. // Check for EOF.
  565. if (bytes == 0)
  566. {
  567. ec = asio::error::eof;
  568. return true;
  569. }
  570. // Check if operation succeeded.
  571. if (bytes > 0)
  572. {
  573. bytes_transferred = bytes;
  574. return true;
  575. }
  576. // Retry operation if interrupted by signal.
  577. if (ec == asio::error::interrupted)
  578. continue;
  579. // Check if we need to run the operation again.
  580. if (ec == asio::error::would_block
  581. || ec == asio::error::try_again)
  582. return false;
  583. // Operation failed.
  584. bytes_transferred = 0;
  585. return true;
  586. }
  587. }
  588. std::size_t sync_write_at(int d, state_type state, uint64_t offset,
  589. const buf* bufs, std::size_t count, bool all_empty,
  590. asio::error_code& ec)
  591. {
  592. if (d == -1)
  593. {
  594. ec = asio::error::bad_descriptor;
  595. return 0;
  596. }
  597. // A request to write 0 bytes on a stream is a no-op.
  598. if (all_empty)
  599. {
  600. asio::error::clear(ec);
  601. return 0;
  602. }
  603. // Write some data.
  604. for (;;)
  605. {
  606. // Try to complete the operation without blocking.
  607. signed_size_type bytes = ::pwritev(d,
  608. bufs, static_cast<int>(count), offset);
  609. get_last_error(ec, bytes < 0);
  610. // Check if operation succeeded.
  611. if (bytes > 0)
  612. return bytes;
  613. // Operation failed.
  614. if ((state & user_set_non_blocking)
  615. || (ec != asio::error::would_block
  616. && ec != asio::error::try_again))
  617. return 0;
  618. // Wait for descriptor to become ready.
  619. if (descriptor_ops::poll_write(d, 0, ec) < 0)
  620. return 0;
  621. }
  622. }
  623. std::size_t sync_write_at1(int d, state_type state, uint64_t offset,
  624. const void* data, std::size_t size, asio::error_code& ec)
  625. {
  626. if (d == -1)
  627. {
  628. ec = asio::error::bad_descriptor;
  629. return 0;
  630. }
  631. // A request to write 0 bytes on a stream is a no-op.
  632. if (size == 0)
  633. {
  634. asio::error::clear(ec);
  635. return 0;
  636. }
  637. // Write some data.
  638. for (;;)
  639. {
  640. // Try to complete the operation without blocking.
  641. signed_size_type bytes = ::pwrite(d, data, size, offset);
  642. get_last_error(ec, bytes < 0);
  643. // Check if operation succeeded.
  644. if (bytes > 0)
  645. return bytes;
  646. // Operation failed.
  647. if ((state & user_set_non_blocking)
  648. || (ec != asio::error::would_block
  649. && ec != asio::error::try_again))
  650. return 0;
  651. // Wait for descriptor to become ready.
  652. if (descriptor_ops::poll_write(d, 0, ec) < 0)
  653. return 0;
  654. }
  655. }
  656. bool non_blocking_write_at(int d, uint64_t offset,
  657. const buf* bufs, std::size_t count,
  658. asio::error_code& ec, std::size_t& bytes_transferred)
  659. {
  660. for (;;)
  661. {
  662. // Write some data.
  663. signed_size_type bytes = ::pwritev(d,
  664. bufs, static_cast<int>(count), offset);
  665. get_last_error(ec, bytes < 0);
  666. // Check if operation succeeded.
  667. if (bytes >= 0)
  668. {
  669. bytes_transferred = bytes;
  670. return true;
  671. }
  672. // Retry operation if interrupted by signal.
  673. if (ec == asio::error::interrupted)
  674. continue;
  675. // Check if we need to run the operation again.
  676. if (ec == asio::error::would_block
  677. || ec == asio::error::try_again)
  678. return false;
  679. // Operation failed.
  680. bytes_transferred = 0;
  681. return true;
  682. }
  683. }
  684. bool non_blocking_write_at1(int d, uint64_t offset,
  685. const void* data, std::size_t size,
  686. asio::error_code& ec, std::size_t& bytes_transferred)
  687. {
  688. for (;;)
  689. {
  690. // Write some data.
  691. signed_size_type bytes = ::pwrite(d, data, size, offset);
  692. get_last_error(ec, bytes < 0);
  693. // Check if operation succeeded.
  694. if (bytes >= 0)
  695. {
  696. bytes_transferred = bytes;
  697. return true;
  698. }
  699. // Retry operation if interrupted by signal.
  700. if (ec == asio::error::interrupted)
  701. continue;
  702. // Check if we need to run the operation again.
  703. if (ec == asio::error::would_block
  704. || ec == asio::error::try_again)
  705. return false;
  706. // Operation failed.
  707. bytes_transferred = 0;
  708. return true;
  709. }
  710. }
  711. #endif // defined(ASIO_HAS_FILE)
  712. int ioctl(int d, state_type& state, long cmd,
  713. ioctl_arg_type* arg, asio::error_code& ec)
  714. {
  715. if (d == -1)
  716. {
  717. ec = asio::error::bad_descriptor;
  718. return -1;
  719. }
  720. int result = ::ioctl(d, cmd, arg);
  721. get_last_error(ec, result < 0);
  722. if (result >= 0)
  723. {
  724. // When updating the non-blocking mode we always perform the ioctl syscall,
  725. // even if the flags would otherwise indicate that the descriptor is
  726. // already in the correct state. This ensures that the underlying
  727. // descriptor is put into the state that has been requested by the user. If
  728. // the ioctl syscall was successful then we need to update the flags to
  729. // match.
  730. if (cmd == static_cast<long>(FIONBIO))
  731. {
  732. if (*arg)
  733. {
  734. state |= user_set_non_blocking;
  735. }
  736. else
  737. {
  738. // Clearing the non-blocking mode always overrides any internally-set
  739. // non-blocking flag. Any subsequent asynchronous operations will need
  740. // to re-enable non-blocking I/O.
  741. state &= ~(user_set_non_blocking | internal_non_blocking);
  742. }
  743. }
  744. }
  745. return result;
  746. }
  747. int fcntl(int d, int cmd, asio::error_code& ec)
  748. {
  749. if (d == -1)
  750. {
  751. ec = asio::error::bad_descriptor;
  752. return -1;
  753. }
  754. int result = ::fcntl(d, cmd);
  755. get_last_error(ec, result < 0);
  756. return result;
  757. }
  758. int fcntl(int d, int cmd, long arg, asio::error_code& ec)
  759. {
  760. if (d == -1)
  761. {
  762. ec = asio::error::bad_descriptor;
  763. return -1;
  764. }
  765. int result = ::fcntl(d, cmd, arg);
  766. get_last_error(ec, result < 0);
  767. return result;
  768. }
  769. int poll_read(int d, state_type state, asio::error_code& ec)
  770. {
  771. if (d == -1)
  772. {
  773. ec = asio::error::bad_descriptor;
  774. return -1;
  775. }
  776. pollfd fds;
  777. fds.fd = d;
  778. fds.events = POLLIN;
  779. fds.revents = 0;
  780. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  781. int result = ::poll(&fds, 1, timeout);
  782. get_last_error(ec, result < 0);
  783. if (result == 0)
  784. if (state & user_set_non_blocking)
  785. ec = asio::error::would_block;
  786. return result;
  787. }
  788. int poll_write(int d, state_type state, asio::error_code& ec)
  789. {
  790. if (d == -1)
  791. {
  792. ec = asio::error::bad_descriptor;
  793. return -1;
  794. }
  795. pollfd fds;
  796. fds.fd = d;
  797. fds.events = POLLOUT;
  798. fds.revents = 0;
  799. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  800. int result = ::poll(&fds, 1, timeout);
  801. get_last_error(ec, result < 0);
  802. if (result == 0)
  803. if (state & user_set_non_blocking)
  804. ec = asio::error::would_block;
  805. return result;
  806. }
  807. int poll_error(int d, state_type state, asio::error_code& ec)
  808. {
  809. if (d == -1)
  810. {
  811. ec = asio::error::bad_descriptor;
  812. return -1;
  813. }
  814. pollfd fds;
  815. fds.fd = d;
  816. fds.events = POLLPRI | POLLERR | POLLHUP;
  817. fds.revents = 0;
  818. int timeout = (state & user_set_non_blocking) ? 0 : -1;
  819. int result = ::poll(&fds, 1, timeout);
  820. get_last_error(ec, result < 0);
  821. if (result == 0)
  822. if (state & user_set_non_blocking)
  823. ec = asio::error::would_block;
  824. return result;
  825. }
  826. } // namespace descriptor_ops
  827. } // namespace detail
  828. } // namespace asio
  829. #include "asio/detail/pop_options.hpp"
  830. #endif // !defined(ASIO_WINDOWS)
  831. // && !defined(ASIO_WINDOWS_RUNTIME)
  832. // && !defined(__CYGWIN__)
  833. #endif // ASIO_DETAIL_IMPL_DESCRIPTOR_OPS_IPP