From 8c29702473530e54e59d0223e36143ead5303782 Mon Sep 17 00:00:00 2001 From: gubnik Date: Thu, 6 Aug 2026 12:06:34 +0300 Subject: [PATCH 1/3] Add non-throwing overloads for stream_file --- include/boost/corosio/stream_file.hpp | 61 +++++++++++++- src/corosio/src/stream_file.cpp | 115 +++++++++++++++++++++----- 2 files changed, 154 insertions(+), 22 deletions(-) diff --git a/include/boost/corosio/stream_file.hpp b/include/boost/corosio/stream_file.hpp index 292908ae2..73967ae45 100644 --- a/include/boost/corosio/stream_file.hpp +++ b/include/boost/corosio/stream_file.hpp @@ -163,6 +163,18 @@ class BOOST_COROSIO_DECL stream_file : public io_stream std::filesystem::path const& path, file_base::flags mode = file_base::read_only); + /** Open a file. + + @param path The filesystem path to open. + @param mode Bitmask of @ref file_base::flags specifying + access mode and creation behavior. + @param ec Output error code. + */ + void open( + std::filesystem::path const& path, + file_base::flags mode, + std::error_code& ec); + /** Close the file. Releases file resources. Any pending operations complete @@ -203,6 +215,12 @@ class BOOST_COROSIO_DECL stream_file : public io_stream */ std::uint64_t size() const; + /** Return the file size in bytes. + + @param ec Output error code. + */ + std::uint64_t size(std::error_code& ec) const; + /** Resize the file to @p new_size bytes. @param new_size The new file size. @@ -210,34 +228,63 @@ class BOOST_COROSIO_DECL stream_file : public io_stream */ void resize(std::uint64_t new_size); + /** Resize the file to @p new_size bytes. + + @param new_size The new file size. + @param ec Output error code. + */ + void resize(std::uint64_t new_size, std::error_code& ec); + /** Synchronize file data to stable storage. @throws std::system_error on failure. */ void sync_data(); + /** Synchronize file data to stable storage. + + @param ec Output error code. + */ + void sync_data(std::error_code& ec); + /** Synchronize file data and metadata to stable storage. @throws std::system_error on failure. */ void sync_all(); + /** Synchronize file data and metadata to stable storage. + + @param ec Output error code. + */ + void sync_all(std::error_code& ec); + /** Release ownership of the native handle. The file object becomes not-open. The caller is responsible for closing the returned handle. @return The native file descriptor or handle. + @throws std::system_error on failure. */ native_handle_type release(); + /** Release ownership of the native handle. + + The file object becomes not-open. The caller is + responsible for closing the returned handle. + + @param ec Output error code. + @return The native file descriptor or handle. + */ + native_handle_type release(std::error_code& ec); + /** Adopt an existing native handle. Closes any currently open file before adopting. The file object takes ownership of the handle. @param handle The native file descriptor or handle. - @throws std::system_error on failure. */ void assign(native_handle_type handle); @@ -252,6 +299,18 @@ class BOOST_COROSIO_DECL stream_file : public io_stream seek(std::int64_t offset, file_base::seek_basis origin = file_base::seek_set); + /** Move the file position. + + @param offset Signed offset from @p origin. + @param origin The reference point for the seek. + @param ec Output error code. + @return The new absolute position. + */ + std::uint64_t + seek(std::int64_t offset, + file_base::seek_basis origin, + std::error_code& ec); + protected: /// Default-construct (for derived types that initialize io_object directly). stream_file() noexcept = default; diff --git a/src/corosio/src/stream_file.cpp b/src/corosio/src/stream_file.cpp index d0003c064..5a7eb0940 100644 --- a/src/corosio/src/stream_file.cpp +++ b/src/corosio/src/stream_file.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #if BOOST_COROSIO_HAS_IOCP #include @@ -33,16 +34,31 @@ stream_file::stream_file(capy::execution_context& ctx) { } +void +stream_file::open(std::filesystem::path const& path, file_base::flags mode) +{ + std::error_code ec; + open(path, mode, ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::open"); + } +} + void stream_file::open( - std::filesystem::path const& path, file_base::flags mode) + std::filesystem::path const& path, + file_base::flags mode, + std::error_code& oec) { if (is_open()) close(); auto& svc = static_cast(h_.service()); std::error_code ec = svc.open_file(get(), path, mode); - if (ec) - detail::throw_system_error(ec, "stream_file::open"); + if (oec) + { + oec = ec; + } } void @@ -77,51 +93,97 @@ stream_file::native_handle() const noexcept std::uint64_t stream_file::size() const +{ + std::error_code ec; + std::uint64_t sz = size(ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::size"); + } + return sz; +} + +std::uint64_t +stream_file::size(std::error_code& ec) const { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::size"); + ec = make_error_code(std::errc::bad_file_descriptor); return get().size(); } void stream_file::resize(std::uint64_t new_size) +{ + std::error_code ec; + resize(new_size, ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::resize"); + } +} + +void +stream_file::resize(std::uint64_t new_size, std::error_code& ec) { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::resize"); + ec = make_error_code(std::errc::bad_file_descriptor); get().resize(new_size); } void stream_file::sync_data() +{ + std::error_code ec; + sync_data(ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::sync_data"); + } +} + +void +stream_file::sync_data(std::error_code& ec) { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::sync_data"); + ec = make_error_code(std::errc::bad_file_descriptor); get().sync_data(); } void stream_file::sync_all() +{ + std::error_code ec; + sync_all(ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::sync_all"); + } +} + +void +stream_file::sync_all(std::error_code& ec) { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::sync_all"); + ec = make_error_code(std::errc::bad_file_descriptor); get().sync_all(); } native_handle_type stream_file::release() +{ + std::error_code ec; + native_handle_type h = release(ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::release"); + } + return h; +} +native_handle_type +stream_file::release(std::error_code& ec) { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::release"); + ec = make_error_code(std::errc::bad_file_descriptor); return get().release(); } @@ -135,11 +197,22 @@ stream_file::assign(native_handle_type handle) std::uint64_t stream_file::seek(std::int64_t offset, file_base::seek_basis origin) +{ + std::error_code ec; + std::uint64_t pos = seek(offset, origin, ec); + if (ec) + { + detail::throw_system_error(ec, "stream_file::seek"); + } + return pos; +} + +std::uint64_t +stream_file::seek( + std::int64_t offset, file_base::seek_basis origin, std::error_code& ec) { if (!is_open()) - detail::throw_system_error( - make_error_code(std::errc::bad_file_descriptor), - "stream_file::seek"); + ec = make_error_code(std::errc::bad_file_descriptor); return get().seek(offset, origin); } From 92a1d9591f5bd642e47ae2f2fdf7a906c3e15ac4 Mon Sep 17 00:00:00 2001 From: gubnik Date: Thu, 6 Aug 2026 12:38:30 +0300 Subject: [PATCH 2/3] Fix open procedure --- src/corosio/src/stream_file.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/corosio/src/stream_file.cpp b/src/corosio/src/stream_file.cpp index 5a7eb0940..771964a3e 100644 --- a/src/corosio/src/stream_file.cpp +++ b/src/corosio/src/stream_file.cpp @@ -49,16 +49,12 @@ void stream_file::open( std::filesystem::path const& path, file_base::flags mode, - std::error_code& oec) + std::error_code& ec) { if (is_open()) close(); - auto& svc = static_cast(h_.service()); - std::error_code ec = svc.open_file(get(), path, mode); - if (oec) - { - oec = ec; - } + auto& svc = static_cast(h_.service()); + ec = svc.open_file(get(), path, mode); } void From 4b1e828963befc4fcf496db4e976b40f67d8db56 Mon Sep 17 00:00:00 2001 From: gubnik Date: Thu, 6 Aug 2026 12:40:04 +0300 Subject: [PATCH 3/3] Clear error code in non-throwing overload --- src/corosio/src/stream_file.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/corosio/src/stream_file.cpp b/src/corosio/src/stream_file.cpp index 771964a3e..3b22c19ad 100644 --- a/src/corosio/src/stream_file.cpp +++ b/src/corosio/src/stream_file.cpp @@ -51,6 +51,7 @@ stream_file::open( file_base::flags mode, std::error_code& ec) { + ec.clear(); if (is_open()) close(); auto& svc = static_cast(h_.service()); @@ -102,6 +103,7 @@ stream_file::size() const std::uint64_t stream_file::size(std::error_code& ec) const { + ec.clear(); if (!is_open()) ec = make_error_code(std::errc::bad_file_descriptor); return get().size(); @@ -121,6 +123,7 @@ stream_file::resize(std::uint64_t new_size) void stream_file::resize(std::uint64_t new_size, std::error_code& ec) { + ec.clear(); if (!is_open()) ec = make_error_code(std::errc::bad_file_descriptor); get().resize(new_size); @@ -159,6 +162,7 @@ stream_file::sync_all() void stream_file::sync_all(std::error_code& ec) { + ec.clear(); if (!is_open()) ec = make_error_code(std::errc::bad_file_descriptor); get().sync_all(); @@ -178,6 +182,7 @@ stream_file::release() native_handle_type stream_file::release(std::error_code& ec) { + ec.clear(); if (!is_open()) ec = make_error_code(std::errc::bad_file_descriptor); return get().release(); @@ -207,6 +212,7 @@ std::uint64_t stream_file::seek( std::int64_t offset, file_base::seek_basis origin, std::error_code& ec) { + ec.clear(); if (!is_open()) ec = make_error_code(std::errc::bad_file_descriptor); return get().seek(offset, origin);