basic_file.hpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. //
  2. // basic_file.hpp
  3. // ~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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_BASIC_FILE_HPP
  11. #define ASIO_BASIC_FILE_HPP
  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. #if defined(ASIO_HAS_FILE) \
  17. || defined(GENERATING_DOCUMENTATION)
  18. #include <string>
  19. #include "asio/any_io_executor.hpp"
  20. #include "asio/async_result.hpp"
  21. #include "asio/detail/cstdint.hpp"
  22. #include "asio/detail/handler_type_requirements.hpp"
  23. #include "asio/detail/io_object_impl.hpp"
  24. #include "asio/detail/non_const_lvalue.hpp"
  25. #include "asio/detail/throw_error.hpp"
  26. #include "asio/detail/type_traits.hpp"
  27. #include "asio/error.hpp"
  28. #include "asio/execution_context.hpp"
  29. #include "asio/post.hpp"
  30. #include "asio/file_base.hpp"
  31. #if defined(ASIO_HAS_IOCP)
  32. # include "asio/detail/win_iocp_file_service.hpp"
  33. #elif defined(ASIO_HAS_IO_URING)
  34. # include "asio/detail/io_uring_file_service.hpp"
  35. #endif
  36. #if defined(ASIO_HAS_MOVE)
  37. # include <utility>
  38. #endif // defined(ASIO_HAS_MOVE)
  39. #include "asio/detail/push_options.hpp"
  40. namespace asio {
  41. #if !defined(ASIO_BASIC_FILE_FWD_DECL)
  42. #define ASIO_BASIC_FILE_FWD_DECL
  43. // Forward declaration with defaulted arguments.
  44. template <typename Executor = any_io_executor>
  45. class basic_file;
  46. #endif // !defined(ASIO_BASIC_FILE_FWD_DECL)
  47. /// Provides file functionality.
  48. /**
  49. * The basic_file class template provides functionality that is common to both
  50. * stream-oriented and random-access files.
  51. *
  52. * @par Thread Safety
  53. * @e Distinct @e objects: Safe.@n
  54. * @e Shared @e objects: Unsafe.
  55. */
  56. template <typename Executor>
  57. class basic_file
  58. : public file_base
  59. {
  60. public:
  61. /// The type of the executor associated with the object.
  62. typedef Executor executor_type;
  63. /// Rebinds the file type to another executor.
  64. template <typename Executor1>
  65. struct rebind_executor
  66. {
  67. /// The file type when rebound to the specified executor.
  68. typedef basic_file<Executor1> other;
  69. };
  70. /// The native representation of a file.
  71. #if defined(GENERATING_DOCUMENTATION)
  72. typedef implementation_defined native_handle_type;
  73. #elif defined(ASIO_HAS_IOCP)
  74. typedef detail::win_iocp_file_service::native_handle_type native_handle_type;
  75. #elif defined(ASIO_HAS_IO_URING)
  76. typedef detail::io_uring_file_service::native_handle_type native_handle_type;
  77. #endif
  78. /// Construct a basic_file without opening it.
  79. /**
  80. * This constructor initialises a file without opening it.
  81. *
  82. * @param ex The I/O executor that the file will use, by default, to
  83. * dispatch handlers for any asynchronous operations performed on the file.
  84. */
  85. explicit basic_file(const executor_type& ex)
  86. : impl_(0, ex)
  87. {
  88. }
  89. /// Construct a basic_file without opening it.
  90. /**
  91. * This constructor initialises a file without opening it.
  92. *
  93. * @param context An execution context which provides the I/O executor that
  94. * the file will use, by default, to dispatch handlers for any asynchronous
  95. * operations performed on the file.
  96. */
  97. template <typename ExecutionContext>
  98. explicit basic_file(ExecutionContext& context,
  99. typename constraint<
  100. is_convertible<ExecutionContext&, execution_context&>::value,
  101. defaulted_constraint
  102. >::type = defaulted_constraint())
  103. : impl_(0, 0, context)
  104. {
  105. }
  106. /// Construct and open a basic_file.
  107. /**
  108. * This constructor initialises a file and opens it.
  109. *
  110. * @param ex The I/O executor that the file will use, by default, to
  111. * dispatch handlers for any asynchronous operations performed on the file.
  112. *
  113. * @param path The path name identifying the file to be opened.
  114. *
  115. * @param open_flags A set of flags that determine how the file should be
  116. * opened.
  117. */
  118. explicit basic_file(const executor_type& ex,
  119. const char* path, file_base::flags open_flags)
  120. : impl_(0, ex)
  121. {
  122. asio::error_code ec;
  123. impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
  124. asio::detail::throw_error(ec, "open");
  125. }
  126. /// Construct a basic_file without opening it.
  127. /**
  128. * This constructor initialises a file and opens it.
  129. *
  130. * @param context An execution context which provides the I/O executor that
  131. * the file will use, by default, to dispatch handlers for any asynchronous
  132. * operations performed on the file.
  133. *
  134. * @param path The path name identifying the file to be opened.
  135. *
  136. * @param open_flags A set of flags that determine how the file should be
  137. * opened.
  138. */
  139. template <typename ExecutionContext>
  140. explicit basic_file(ExecutionContext& context,
  141. const char* path, file_base::flags open_flags,
  142. typename constraint<
  143. is_convertible<ExecutionContext&, execution_context&>::value,
  144. defaulted_constraint
  145. >::type = defaulted_constraint())
  146. : impl_(0, 0, context)
  147. {
  148. asio::error_code ec;
  149. impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
  150. asio::detail::throw_error(ec, "open");
  151. }
  152. /// Construct and open a basic_file.
  153. /**
  154. * This constructor initialises a file and opens it.
  155. *
  156. * @param ex The I/O executor that the file will use, by default, to
  157. * dispatch handlers for any asynchronous operations performed on the file.
  158. *
  159. * @param path The path name identifying the file to be opened.
  160. *
  161. * @param open_flags A set of flags that determine how the file should be
  162. * opened.
  163. */
  164. explicit basic_file(const executor_type& ex,
  165. const std::string& path, file_base::flags open_flags)
  166. : impl_(0, ex)
  167. {
  168. asio::error_code ec;
  169. impl_.get_service().open(impl_.get_implementation(),
  170. path.c_str(), open_flags, ec);
  171. asio::detail::throw_error(ec, "open");
  172. }
  173. /// Construct a basic_file without opening it.
  174. /**
  175. * This constructor initialises a file and opens it.
  176. *
  177. * @param context An execution context which provides the I/O executor that
  178. * the file will use, by default, to dispatch handlers for any asynchronous
  179. * operations performed on the file.
  180. *
  181. * @param path The path name identifying the file to be opened.
  182. *
  183. * @param open_flags A set of flags that determine how the file should be
  184. * opened.
  185. */
  186. template <typename ExecutionContext>
  187. explicit basic_file(ExecutionContext& context,
  188. const std::string& path, file_base::flags open_flags,
  189. typename constraint<
  190. is_convertible<ExecutionContext&, execution_context&>::value,
  191. defaulted_constraint
  192. >::type = defaulted_constraint())
  193. : impl_(0, 0, context)
  194. {
  195. asio::error_code ec;
  196. impl_.get_service().open(impl_.get_implementation(),
  197. path.c_str(), open_flags, ec);
  198. asio::detail::throw_error(ec, "open");
  199. }
  200. /// Construct a basic_file on an existing native file handle.
  201. /**
  202. * This constructor initialises a file object to hold an existing native file.
  203. *
  204. * @param ex The I/O executor that the file will use, by default, to
  205. * dispatch handlers for any asynchronous operations performed on the file.
  206. *
  207. * @param native_file A native file handle.
  208. *
  209. * @throws asio::system_error Thrown on failure.
  210. */
  211. basic_file(const executor_type& ex, const native_handle_type& native_file)
  212. : impl_(0, ex)
  213. {
  214. asio::error_code ec;
  215. impl_.get_service().assign(
  216. impl_.get_implementation(), native_file, ec);
  217. asio::detail::throw_error(ec, "assign");
  218. }
  219. /// Construct a basic_file on an existing native file.
  220. /**
  221. * This constructor initialises a file object to hold an existing native file.
  222. *
  223. * @param context An execution context which provides the I/O executor that
  224. * the file will use, by default, to dispatch handlers for any asynchronous
  225. * operations performed on the file.
  226. *
  227. * @param native_file A native file.
  228. *
  229. * @throws asio::system_error Thrown on failure.
  230. */
  231. template <typename ExecutionContext>
  232. basic_file(ExecutionContext& context, const native_handle_type& native_file,
  233. typename constraint<
  234. is_convertible<ExecutionContext&, execution_context&>::value,
  235. defaulted_constraint
  236. >::type = defaulted_constraint())
  237. : impl_(0, 0, context)
  238. {
  239. asio::error_code ec;
  240. impl_.get_service().assign(
  241. impl_.get_implementation(), native_file, ec);
  242. asio::detail::throw_error(ec, "assign");
  243. }
  244. #if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  245. /// Move-construct a basic_file from another.
  246. /**
  247. * This constructor moves a file from one object to another.
  248. *
  249. * @param other The other basic_file object from which the move will
  250. * occur.
  251. *
  252. * @note Following the move, the moved-from object is in the same state as if
  253. * constructed using the @c basic_file(const executor_type&) constructor.
  254. */
  255. basic_file(basic_file&& other) ASIO_NOEXCEPT
  256. : impl_(std::move(other.impl_))
  257. {
  258. }
  259. /// Move-assign a basic_file from another.
  260. /**
  261. * This assignment operator moves a file from one object to another.
  262. *
  263. * @param other The other basic_file object from which the move will
  264. * occur.
  265. *
  266. * @note Following the move, the moved-from object is in the same state as if
  267. * constructed using the @c basic_file(const executor_type&) constructor.
  268. */
  269. basic_file& operator=(basic_file&& other)
  270. {
  271. impl_ = std::move(other.impl_);
  272. return *this;
  273. }
  274. // All files have access to each other's implementations.
  275. template <typename Executor1>
  276. friend class basic_file;
  277. /// Move-construct a basic_file from a file of another executor type.
  278. /**
  279. * This constructor moves a file from one object to another.
  280. *
  281. * @param other The other basic_file object from which the move will
  282. * occur.
  283. *
  284. * @note Following the move, the moved-from object is in the same state as if
  285. * constructed using the @c basic_file(const executor_type&) constructor.
  286. */
  287. template <typename Executor1>
  288. basic_file(basic_file<Executor1>&& other,
  289. typename constraint<
  290. is_convertible<Executor1, Executor>::value,
  291. defaulted_constraint
  292. >::type = defaulted_constraint())
  293. : impl_(std::move(other.impl_))
  294. {
  295. }
  296. /// Move-assign a basic_file from a file of another executor type.
  297. /**
  298. * This assignment operator moves a file from one object to another.
  299. *
  300. * @param other The other basic_file object from which the move will
  301. * occur.
  302. *
  303. * @note Following the move, the moved-from object is in the same state as if
  304. * constructed using the @c basic_file(const executor_type&) constructor.
  305. */
  306. template <typename Executor1>
  307. typename constraint<
  308. is_convertible<Executor1, Executor>::value,
  309. basic_file&
  310. >::type operator=(basic_file<Executor1> && other)
  311. {
  312. basic_file tmp(std::move(other));
  313. impl_ = std::move(tmp.impl_);
  314. return *this;
  315. }
  316. #endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
  317. /// Get the executor associated with the object.
  318. executor_type get_executor() ASIO_NOEXCEPT
  319. {
  320. return impl_.get_executor();
  321. }
  322. /// Open the file using the specified path.
  323. /**
  324. * This function opens the file so that it will use the specified path.
  325. *
  326. * @param path The path name identifying the file to be opened.
  327. *
  328. * @param open_flags A set of flags that determine how the file should be
  329. * opened.
  330. *
  331. * @throws asio::system_error Thrown on failure.
  332. *
  333. * @par Example
  334. * @code
  335. * asio::stream_file file(my_context);
  336. * file.open("/path/to/my/file", asio::stream_file::read_only);
  337. * @endcode
  338. */
  339. void open(const char* path, file_base::flags open_flags)
  340. {
  341. asio::error_code ec;
  342. impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
  343. asio::detail::throw_error(ec, "open");
  344. }
  345. /// Open the file using the specified path.
  346. /**
  347. * This function opens the file so that it will use the specified path.
  348. *
  349. * @param path The path name identifying the file to be opened.
  350. *
  351. * @param open_flags A set of flags that determine how the file should be
  352. * opened.
  353. *
  354. * @param ec Set to indicate what error occurred, if any.
  355. *
  356. * @par Example
  357. * @code
  358. * asio::stream_file file(my_context);
  359. * asio::error_code ec;
  360. * file.open("/path/to/my/file", asio::stream_file::read_only, ec);
  361. * if (ec)
  362. * {
  363. * // An error occurred.
  364. * }
  365. * @endcode
  366. */
  367. ASIO_SYNC_OP_VOID open(const char* path,
  368. file_base::flags open_flags, asio::error_code& ec)
  369. {
  370. impl_.get_service().open(impl_.get_implementation(), path, open_flags, ec);
  371. ASIO_SYNC_OP_VOID_RETURN(ec);
  372. }
  373. /// Open the file using the specified path.
  374. /**
  375. * This function opens the file so that it will use the specified path.
  376. *
  377. * @param path The path name identifying the file to be opened.
  378. *
  379. * @param open_flags A set of flags that determine how the file should be
  380. * opened.
  381. *
  382. * @throws asio::system_error Thrown on failure.
  383. *
  384. * @par Example
  385. * @code
  386. * asio::stream_file file(my_context);
  387. * file.open("/path/to/my/file", asio::stream_file::read_only);
  388. * @endcode
  389. */
  390. void open(const std::string& path, file_base::flags open_flags)
  391. {
  392. asio::error_code ec;
  393. impl_.get_service().open(impl_.get_implementation(),
  394. path.c_str(), open_flags, ec);
  395. asio::detail::throw_error(ec, "open");
  396. }
  397. /// Open the file using the specified path.
  398. /**
  399. * This function opens the file so that it will use the specified path.
  400. *
  401. * @param path The path name identifying the file to be opened.
  402. *
  403. * @param open_flags A set of flags that determine how the file should be
  404. * opened.
  405. *
  406. * @param ec Set to indicate what error occurred, if any.
  407. *
  408. * @par Example
  409. * @code
  410. * asio::stream_file file(my_context);
  411. * asio::error_code ec;
  412. * file.open("/path/to/my/file", asio::stream_file::read_only, ec);
  413. * if (ec)
  414. * {
  415. * // An error occurred.
  416. * }
  417. * @endcode
  418. */
  419. ASIO_SYNC_OP_VOID open(const std::string& path,
  420. file_base::flags open_flags, asio::error_code& ec)
  421. {
  422. impl_.get_service().open(impl_.get_implementation(),
  423. path.c_str(), open_flags, ec);
  424. ASIO_SYNC_OP_VOID_RETURN(ec);
  425. }
  426. /// Assign an existing native file to the file.
  427. /*
  428. * This function opens the file to hold an existing native file.
  429. *
  430. * @param native_file A native file.
  431. *
  432. * @throws asio::system_error Thrown on failure.
  433. */
  434. void assign(const native_handle_type& native_file)
  435. {
  436. asio::error_code ec;
  437. impl_.get_service().assign(
  438. impl_.get_implementation(), native_file, ec);
  439. asio::detail::throw_error(ec, "assign");
  440. }
  441. /// Assign an existing native file to the file.
  442. /*
  443. * This function opens the file to hold an existing native file.
  444. *
  445. * @param native_file A native file.
  446. *
  447. * @param ec Set to indicate what error occurred, if any.
  448. */
  449. ASIO_SYNC_OP_VOID assign(const native_handle_type& native_file,
  450. asio::error_code& ec)
  451. {
  452. impl_.get_service().assign(
  453. impl_.get_implementation(), native_file, ec);
  454. ASIO_SYNC_OP_VOID_RETURN(ec);
  455. }
  456. /// Determine whether the file is open.
  457. bool is_open() const
  458. {
  459. return impl_.get_service().is_open(impl_.get_implementation());
  460. }
  461. /// Close the file.
  462. /**
  463. * This function is used to close the file. Any asynchronous read or write
  464. * operations will be cancelled immediately, and will complete with the
  465. * asio::error::operation_aborted error.
  466. *
  467. * @throws asio::system_error Thrown on failure. Note that, even if
  468. * the function indicates an error, the underlying descriptor is closed.
  469. */
  470. void close()
  471. {
  472. asio::error_code ec;
  473. impl_.get_service().close(impl_.get_implementation(), ec);
  474. asio::detail::throw_error(ec, "close");
  475. }
  476. /// Close the file.
  477. /**
  478. * This function is used to close the file. Any asynchronous read or write
  479. * operations will be cancelled immediately, and will complete with the
  480. * asio::error::operation_aborted error.
  481. *
  482. * @param ec Set to indicate what error occurred, if any. Note that, even if
  483. * the function indicates an error, the underlying descriptor is closed.
  484. *
  485. * @par Example
  486. * @code
  487. * asio::stream_file file(my_context);
  488. * ...
  489. * asio::error_code ec;
  490. * file.close(ec);
  491. * if (ec)
  492. * {
  493. * // An error occurred.
  494. * }
  495. * @endcode
  496. */
  497. ASIO_SYNC_OP_VOID close(asio::error_code& ec)
  498. {
  499. impl_.get_service().close(impl_.get_implementation(), ec);
  500. ASIO_SYNC_OP_VOID_RETURN(ec);
  501. }
  502. /// Release ownership of the underlying native file.
  503. /**
  504. * This function causes all outstanding asynchronous read and write
  505. * operations to finish immediately, and the handlers for cancelled
  506. * operations will be passed the asio::error::operation_aborted error.
  507. * Ownership of the native file is then transferred to the caller.
  508. *
  509. * @throws asio::system_error Thrown on failure.
  510. *
  511. * @note This function is unsupported on Windows versions prior to Windows
  512. * 8.1, and will fail with asio::error::operation_not_supported on
  513. * these platforms.
  514. */
  515. #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
  516. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
  517. __declspec(deprecated("This function always fails with "
  518. "operation_not_supported when used on Windows versions "
  519. "prior to Windows 8.1."))
  520. #endif
  521. native_handle_type release()
  522. {
  523. asio::error_code ec;
  524. native_handle_type s = impl_.get_service().release(
  525. impl_.get_implementation(), ec);
  526. asio::detail::throw_error(ec, "release");
  527. return s;
  528. }
  529. /// Release ownership of the underlying native file.
  530. /**
  531. * This function causes all outstanding asynchronous read and write
  532. * operations to finish immediately, and the handlers for cancelled
  533. * operations will be passed the asio::error::operation_aborted error.
  534. * Ownership of the native file is then transferred to the caller.
  535. *
  536. * @param ec Set to indicate what error occurred, if any.
  537. *
  538. * @note This function is unsupported on Windows versions prior to Windows
  539. * 8.1, and will fail with asio::error::operation_not_supported on
  540. * these platforms.
  541. */
  542. #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
  543. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0603)
  544. __declspec(deprecated("This function always fails with "
  545. "operation_not_supported when used on Windows versions "
  546. "prior to Windows 8.1."))
  547. #endif
  548. native_handle_type release(asio::error_code& ec)
  549. {
  550. return impl_.get_service().release(impl_.get_implementation(), ec);
  551. }
  552. /// Get the native file representation.
  553. /**
  554. * This function may be used to obtain the underlying representation of the
  555. * file. This is intended to allow access to native file functionality
  556. * that is not otherwise provided.
  557. */
  558. native_handle_type native_handle()
  559. {
  560. return impl_.get_service().native_handle(impl_.get_implementation());
  561. }
  562. /// Cancel all asynchronous operations associated with the file.
  563. /**
  564. * This function causes all outstanding asynchronous read and write
  565. * operations to finish immediately, and the handlers for cancelled
  566. * operations will be passed the asio::error::operation_aborted error.
  567. *
  568. * @throws asio::system_error Thrown on failure.
  569. *
  570. * @note Calls to cancel() will always fail with
  571. * asio::error::operation_not_supported when run on Windows XP, Windows
  572. * Server 2003, and earlier versions of Windows, unless
  573. * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
  574. * two issues that should be considered before enabling its use:
  575. *
  576. * @li It will only cancel asynchronous operations that were initiated in the
  577. * current thread.
  578. *
  579. * @li It can appear to complete without error, but the request to cancel the
  580. * unfinished operations may be silently ignored by the operating system.
  581. * Whether it works or not seems to depend on the drivers that are installed.
  582. *
  583. * For portable cancellation, consider using the close() function to
  584. * simultaneously cancel the outstanding operations and close the file.
  585. *
  586. * When running on Windows Vista, Windows Server 2008, and later, the
  587. * CancelIoEx function is always used. This function does not have the
  588. * problems described above.
  589. */
  590. #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
  591. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
  592. && !defined(ASIO_ENABLE_CANCELIO)
  593. __declspec(deprecated("By default, this function always fails with "
  594. "operation_not_supported when used on Windows XP, Windows Server 2003, "
  595. "or earlier. Consult documentation for details."))
  596. #endif
  597. void cancel()
  598. {
  599. asio::error_code ec;
  600. impl_.get_service().cancel(impl_.get_implementation(), ec);
  601. asio::detail::throw_error(ec, "cancel");
  602. }
  603. /// Cancel all asynchronous operations associated with the file.
  604. /**
  605. * This function causes all outstanding asynchronous read and write
  606. * operations to finish immediately, and the handlers for cancelled
  607. * operations will be passed the asio::error::operation_aborted error.
  608. *
  609. * @param ec Set to indicate what error occurred, if any.
  610. *
  611. * @note Calls to cancel() will always fail with
  612. * asio::error::operation_not_supported when run on Windows XP, Windows
  613. * Server 2003, and earlier versions of Windows, unless
  614. * ASIO_ENABLE_CANCELIO is defined. However, the CancelIo function has
  615. * two issues that should be considered before enabling its use:
  616. *
  617. * @li It will only cancel asynchronous operations that were initiated in the
  618. * current thread.
  619. *
  620. * @li It can appear to complete without error, but the request to cancel the
  621. * unfinished operations may be silently ignored by the operating system.
  622. * Whether it works or not seems to depend on the drivers that are installed.
  623. *
  624. * For portable cancellation, consider using the close() function to
  625. * simultaneously cancel the outstanding operations and close the file.
  626. *
  627. * When running on Windows Vista, Windows Server 2008, and later, the
  628. * CancelIoEx function is always used. This function does not have the
  629. * problems described above.
  630. */
  631. #if defined(ASIO_MSVC) && (ASIO_MSVC >= 1400) \
  632. && (!defined(_WIN32_WINNT) || _WIN32_WINNT < 0x0600) \
  633. && !defined(ASIO_ENABLE_CANCELIO)
  634. __declspec(deprecated("By default, this function always fails with "
  635. "operation_not_supported when used on Windows XP, Windows Server 2003, "
  636. "or earlier. Consult documentation for details."))
  637. #endif
  638. ASIO_SYNC_OP_VOID cancel(asio::error_code& ec)
  639. {
  640. impl_.get_service().cancel(impl_.get_implementation(), ec);
  641. ASIO_SYNC_OP_VOID_RETURN(ec);
  642. }
  643. /// Get the size of the file.
  644. /**
  645. * This function determines the size of the file, in bytes.
  646. *
  647. * @throws asio::system_error Thrown on failure.
  648. */
  649. uint64_t size() const
  650. {
  651. asio::error_code ec;
  652. uint64_t s = impl_.get_service().size(impl_.get_implementation(), ec);
  653. asio::detail::throw_error(ec, "size");
  654. return s;
  655. }
  656. /// Get the size of the file.
  657. /**
  658. * This function determines the size of the file, in bytes.
  659. *
  660. * @param ec Set to indicate what error occurred, if any.
  661. */
  662. uint64_t size(asio::error_code& ec) const
  663. {
  664. return impl_.get_service().size(impl_.get_implementation(), ec);
  665. }
  666. /// Alter the size of the file.
  667. /**
  668. * This function resizes the file to the specified size, in bytes. If the
  669. * current file size exceeds @c n then any extra data is discarded. If the
  670. * current size is less than @c n then the file is extended and filled with
  671. * zeroes.
  672. *
  673. * @param n The new size for the file.
  674. *
  675. * @throws asio::system_error Thrown on failure.
  676. */
  677. void resize(uint64_t n)
  678. {
  679. asio::error_code ec;
  680. impl_.get_service().resize(impl_.get_implementation(), n, ec);
  681. asio::detail::throw_error(ec, "resize");
  682. }
  683. /// Alter the size of the file.
  684. /**
  685. * This function resizes the file to the specified size, in bytes. If the
  686. * current file size exceeds @c n then any extra data is discarded. If the
  687. * current size is less than @c n then the file is extended and filled with
  688. * zeroes.
  689. *
  690. * @param n The new size for the file.
  691. *
  692. * @param ec Set to indicate what error occurred, if any.
  693. */
  694. ASIO_SYNC_OP_VOID resize(uint64_t n, asio::error_code& ec)
  695. {
  696. impl_.get_service().resize(impl_.get_implementation(), n, ec);
  697. ASIO_SYNC_OP_VOID_RETURN(ec);
  698. }
  699. /// Synchronise the file to disk.
  700. /**
  701. * This function synchronises the file data and metadata to disk. Note that
  702. * the semantics of this synchronisation vary between operation systems.
  703. *
  704. * @throws asio::system_error Thrown on failure.
  705. */
  706. void sync_all()
  707. {
  708. asio::error_code ec;
  709. impl_.get_service().sync_all(impl_.get_implementation(), ec);
  710. asio::detail::throw_error(ec, "sync_all");
  711. }
  712. /// Synchronise the file to disk.
  713. /**
  714. * This function synchronises the file data and metadata to disk. Note that
  715. * the semantics of this synchronisation vary between operation systems.
  716. *
  717. * @param ec Set to indicate what error occurred, if any.
  718. */
  719. ASIO_SYNC_OP_VOID sync_all(asio::error_code& ec)
  720. {
  721. impl_.get_service().sync_all(impl_.get_implementation(), ec);
  722. ASIO_SYNC_OP_VOID_RETURN(ec);
  723. }
  724. /// Synchronise the file data to disk.
  725. /**
  726. * This function synchronises the file data to disk. Note that the semantics
  727. * of this synchronisation vary between operation systems.
  728. *
  729. * @throws asio::system_error Thrown on failure.
  730. */
  731. void sync_data()
  732. {
  733. asio::error_code ec;
  734. impl_.get_service().sync_data(impl_.get_implementation(), ec);
  735. asio::detail::throw_error(ec, "sync_data");
  736. }
  737. /// Synchronise the file data to disk.
  738. /**
  739. * This function synchronises the file data to disk. Note that the semantics
  740. * of this synchronisation vary between operation systems.
  741. *
  742. * @param ec Set to indicate what error occurred, if any.
  743. */
  744. ASIO_SYNC_OP_VOID sync_data(asio::error_code& ec)
  745. {
  746. impl_.get_service().sync_data(impl_.get_implementation(), ec);
  747. ASIO_SYNC_OP_VOID_RETURN(ec);
  748. }
  749. protected:
  750. /// Protected destructor to prevent deletion through this type.
  751. /**
  752. * This function destroys the file, cancelling any outstanding asynchronous
  753. * operations associated with the file as if by calling @c cancel.
  754. */
  755. ~basic_file()
  756. {
  757. }
  758. #if defined(ASIO_HAS_IOCP)
  759. detail::io_object_impl<detail::win_iocp_file_service, Executor> impl_;
  760. #elif defined(ASIO_HAS_IO_URING)
  761. detail::io_object_impl<detail::io_uring_file_service, Executor> impl_;
  762. #endif
  763. private:
  764. // Disallow copying and assignment.
  765. basic_file(const basic_file&) ASIO_DELETED;
  766. basic_file& operator=(const basic_file&) ASIO_DELETED;
  767. };
  768. } // namespace asio
  769. #include "asio/detail/pop_options.hpp"
  770. #endif // defined(ASIO_HAS_FILE)
  771. // || defined(GENERATING_DOCUMENTATION)
  772. #endif // ASIO_BASIC_FILE_HPP