descriptor_ops.ipp 24 KB

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