aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kapi/kapi/filesystem.hpp8
-rw-r--r--kapi/kapi/filesystem/seek.hpp (renamed from kapi/kapi/filesystem/seek_origin.hpp)14
-rw-r--r--kernel/kapi/filesystem.cpp8
-rw-r--r--kernel/kapi/filesystem.tests.cpp19
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.cpp46
-rw-r--r--kernel/kernel/filesystem/open_file_descriptor.hpp11
6 files changed, 100 insertions, 6 deletions
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 <kapi/filesystem/device_number.hpp> // IWYU pragma: export
#include <kapi/filesystem/file_status.hpp> // IWYU pragma: export
#include <kapi/filesystem/file_type.hpp> // IWYU pragma: export
-#include <kapi/filesystem/seek_origin.hpp> // IWYU pragma: export
+#include <kapi/filesystem/seek.hpp> // IWYU pragma: export
#include <kstd/result.hpp>
#include <kstd/system_error.hpp>
@@ -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<kstd::units::bytes>;
+ auto seek(size_t file_descriptor, kstd::units::bytes offset, seek_direction direction, seek_origin origin)
+ -> kstd::result<kstd::units::bytes>;
//! Create a new directory at the specified path.
//!
diff --git a/kapi/kapi/filesystem/seek_origin.hpp b/kapi/kapi/filesystem/seek.hpp
index 4307f451..f1006f31 100644
--- a/kapi/kapi/filesystem/seek_origin.hpp
+++ b/kapi/kapi/filesystem/seek.hpp
@@ -1,5 +1,5 @@
-#ifndef TEACHOS_KAPI_FILESYSTEM_SEEK_ORIGIN_HPP
-#define TEACHOS_KAPI_FILESYSTEM_SEEK_ORIGIN_HPP
+#ifndef TEACHOS_KAPI_FILESYSTEM_SEEK_HPP
+#define TEACHOS_KAPI_FILESYSTEM_SEEK_HPP
// IWYU pragma: private, include <kapi/filesystem.hpp>
@@ -7,7 +7,7 @@ namespace kapi::filesystem
{
//! The origin for a seek operation.
- enum class seek_origin
+ enum struct seek_origin
{
//! Seek from the beginning of the file.
beginning,
@@ -17,6 +17,14 @@ namespace kapi::filesystem
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/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<kstd::units::bytes>
+ {
+ 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<void>
{
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 <kernel/test_support/filesystem/storage_boot_module_vfs_fixture.hpp>
#include <kstd/system_error.hpp>
+#include <kstd/units.hpp>
#include <catch2/catch_test_macros.hpp>
@@ -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 <kernel/filesystem/open_file_descriptor.hpp>
#include <kernel/filesystem/dentry.hpp>
+#include <kernel/filesystem/error.hpp>
+
+#include <kapi/filesystem.hpp>
#include <kstd/memory.hpp>
#include <kstd/os/error.hpp>
@@ -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<kstd::units::bytes>
+ {
+ 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 <kernel/filesystem/dentry.hpp>
+#include <kapi/filesystem.hpp>
+
#include <kstd/memory.hpp>
#include <kstd/result.hpp>
#include <kstd/units.hpp>
@@ -47,6 +49,15 @@ namespace kernel::filesystem
*/
auto write(std::span<std::byte const> buffer) -> kstd::result<kstd::units::bytes>;
+ //! 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<kstd::units::bytes>;
+
/**
@brief Returns the current file offset for this open file descriptor.
@return The current file offset in bytes.