From 493f50c697b17049b820e65664af9f4a7c9c0c2c Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Tue, 18 Aug 2026 00:25:29 +0200 Subject: kapi: implement seek support --- kapi/kapi/filesystem.hpp | 8 ++-- kapi/kapi/filesystem/seek.hpp | 30 +++++++++++++++ kapi/kapi/filesystem/seek_origin.hpp | 22 ----------- kernel/kapi/filesystem.cpp | 8 ++++ kernel/kapi/filesystem.tests.cpp | 19 ++++++++++ kernel/kernel/filesystem/open_file_descriptor.cpp | 46 +++++++++++++++++++++++ kernel/kernel/filesystem/open_file_descriptor.hpp | 11 ++++++ 7 files changed, 119 insertions(+), 25 deletions(-) create mode 100644 kapi/kapi/filesystem/seek.hpp delete mode 100644 kapi/kapi/filesystem/seek_origin.hpp diff --git a/kapi/kapi/filesystem.hpp b/kapi/kapi/filesystem.hpp index 8972f9d3..be754748 100644 --- a/kapi/kapi/filesystem.hpp +++ b/kapi/kapi/filesystem.hpp @@ -7,7 +7,7 @@ #include // IWYU pragma: export #include // IWYU pragma: export #include // IWYU pragma: export -#include // IWYU pragma: export +#include // IWYU pragma: export #include #include @@ -70,10 +70,12 @@ namespace kapi::filesystem //! Adjust the current position in the file. //! //! @param file_descriptor The file descriptor to seek. - //! @param offset The offset to seek to, relative to @p origin. + //! @param offset The offset to seek to, relative to the origin. + //! @param direction The direction to seek towards, relative to the origin. //! @param origin The origing to seek relatively to. //! @return The new position in the file on success, an error code otherwise. - auto seek(size_t file_descriptor, kstd::units::bytes offset, seek_origin origin) -> kstd::result; + auto seek(size_t file_descriptor, kstd::units::bytes offset, seek_direction direction, seek_origin origin) + -> kstd::result; //! Create a new directory at the specified path. //! diff --git a/kapi/kapi/filesystem/seek.hpp b/kapi/kapi/filesystem/seek.hpp new file mode 100644 index 00000000..f1006f31 --- /dev/null +++ b/kapi/kapi/filesystem/seek.hpp @@ -0,0 +1,30 @@ +#ifndef TEACHOS_KAPI_FILESYSTEM_SEEK_HPP +#define TEACHOS_KAPI_FILESYSTEM_SEEK_HPP + +// IWYU pragma: private, include + +namespace kapi::filesystem +{ + + //! The origin for a seek operation. + enum struct seek_origin + { + //! Seek from the beginning of the file. + beginning, + //! Seek from the current position. + current_position, + //! Seek from the end of the file. + end, + }; + + enum struct seek_direction + { + //! seek forward from the origin. + forward, + //! seek backward from the origin. + backward, + }; + +} // namespace kapi::filesystem + +#endif \ No newline at end of file diff --git a/kapi/kapi/filesystem/seek_origin.hpp b/kapi/kapi/filesystem/seek_origin.hpp deleted file mode 100644 index 4307f451..00000000 --- a/kapi/kapi/filesystem/seek_origin.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef TEACHOS_KAPI_FILESYSTEM_SEEK_ORIGIN_HPP -#define TEACHOS_KAPI_FILESYSTEM_SEEK_ORIGIN_HPP - -// IWYU pragma: private, include - -namespace kapi::filesystem -{ - - //! The origin for a seek operation. - enum class seek_origin - { - //! Seek from the beginning of the file. - beginning, - //! Seek from the current position. - current_position, - //! Seek from the end of the file. - end, - }; - -} // namespace kapi::filesystem - -#endif \ No newline at end of file diff --git a/kernel/kapi/filesystem.cpp b/kernel/kapi/filesystem.cpp index 5280b4fa..d37a4cf7 100644 --- a/kernel/kapi/filesystem.cpp +++ b/kernel/kapi/filesystem.cpp @@ -57,6 +57,14 @@ namespace kapi::filesystem }); } + auto seek(size_t file_descriptor, kstd::units::bytes offset, seek_direction direction, seek_origin origin) + -> kstd::result + { + return kernel::filesystem::open_file_table::get().file(file_descriptor).and_then([=](auto file) { + return file->seek(offset, direction, origin); + }); + } + auto mkdir(std::string_view path) -> kstd::result { return kernel::filesystem::vfs::get().mkdir(path); diff --git a/kernel/kapi/filesystem.tests.cpp b/kernel/kapi/filesystem.tests.cpp index 80fc7d3f..2f975bf8 100644 --- a/kernel/kapi/filesystem.tests.cpp +++ b/kernel/kapi/filesystem.tests.cpp @@ -3,6 +3,7 @@ #include #include +#include #include @@ -142,6 +143,24 @@ SCENARIO_METHOD(kernel::tests::filesystem::storage_boot_module_vfs_fixture, "Kap REQUIRE(kapi::filesystem::umount("/information")); } + AND_GIVEN("an open file") + { + auto file = kapi::filesystem::open("/closed.txt"); + REQUIRE(file); + + THEN("seeking forward from the beginning succeeds") + { + REQUIRE(kapi::filesystem::seek(*file, 100_B, kapi::filesystem::seek_direction::forward, + kapi::filesystem::seek_origin::beginning) == 100_B); + } + + THEN("seeking backward from the beginning fails") + { + REQUIRE_FALSE(kapi::filesystem::seek(*file, 100_B, kapi::filesystem::seek_direction::backward, + kapi::filesystem::seek_origin::beginning)); + } + } + THEN("device can be opened as file and read from") { auto fd = kapi::filesystem::open("/dev/ram0").value(); diff --git a/kernel/kernel/filesystem/open_file_descriptor.cpp b/kernel/kernel/filesystem/open_file_descriptor.cpp index 71dd172b..379b0708 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.cpp +++ b/kernel/kernel/filesystem/open_file_descriptor.cpp @@ -1,6 +1,9 @@ #include #include +#include + +#include #include #include @@ -50,6 +53,49 @@ namespace kernel::filesystem } } + auto open_file_descriptor::seek(kstd::units::bytes offset, kapi::filesystem::seek_direction direction, + kapi::filesystem::seek_origin origin) -> kstd::result + { + switch (origin) + { + case kapi::filesystem::seek_origin::beginning: + { + if (direction == kapi::filesystem::seek_direction::backward) + { + return kstd::failure(vfs_errc::invalid_argument); + } + return m_offset = offset; + } + case kapi::filesystem::seek_origin::current_position: + { + if (direction == kapi::filesystem::seek_direction::backward) + { + if (offset > m_offset) + { + return kstd::failure(vfs_errc::invalid_argument); + } + return m_offset -= offset; + } + return m_offset += offset; + } + case kapi::filesystem::seek_origin::end: + { + auto base = m_dentry->get_inode()->status()->size; + if (direction == kapi::filesystem::seek_direction::backward) + { + if (offset > base) + { + return kstd::failure(vfs_errc::invalid_argument); + } + return m_offset = base - offset; + } + return m_offset = base + offset; + } + } + + return kstd::failure(vfs_errc::invalid_argument); + } + auto open_file_descriptor::offset() const -> kstd::units::bytes { return m_offset; diff --git a/kernel/kernel/filesystem/open_file_descriptor.hpp b/kernel/kernel/filesystem/open_file_descriptor.hpp index 247108c1..f0b55d72 100644 --- a/kernel/kernel/filesystem/open_file_descriptor.hpp +++ b/kernel/kernel/filesystem/open_file_descriptor.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include #include @@ -47,6 +49,15 @@ namespace kernel::filesystem */ auto write(std::span buffer) -> kstd::result; + //! Move the read/write offset of the file. + //! + //! @param offset The offset to apply relative to the given origin. + //! @param offset The direction to seek in, relative to the given origin. + //! @param origin The origin of the offset. + //! @return the new offset on success, an error otherwise. + auto seek(kstd::units::bytes offset, kapi::filesystem::seek_direction direction, + kapi::filesystem::seek_origin origin) -> kstd::result; + /** @brief Returns the current file offset for this open file descriptor. @return The current file offset in bytes. -- cgit v1.2.3