From 4d5080388a5da740ce60017728d046c424e1771e Mon Sep 17 00:00:00 2001 From: Sam Atkins Date: Thu, 3 Feb 2022 19:21:51 +0000 Subject: [PATCH] LibCore+Tests: Add SeekableStream::truncate() --- Tests/LibCore/TestLibCoreStream.cpp | 12 ++++++++++++ Userland/Libraries/LibCore/MemoryStream.h | 2 ++ Userland/Libraries/LibCore/Stream.cpp | 5 +++++ Userland/Libraries/LibCore/Stream.h | 8 ++++++++ 4 files changed, 27 insertions(+) diff --git a/Tests/LibCore/TestLibCoreStream.cpp b/Tests/LibCore/TestLibCoreStream.cpp index e0fcf16aab..37d559bcb0 100644 --- a/Tests/LibCore/TestLibCoreStream.cpp +++ b/Tests/LibCore/TestLibCoreStream.cpp @@ -135,6 +135,18 @@ TEST_CASE(file_adopt_invalid_fd) EXPECT_EQ(maybe_file.error().code(), EBADF); } +TEST_CASE(file_truncate) +{ + auto maybe_file = Core::Stream::File::open("/tmp/file-truncate-test.txt", Core::Stream::OpenMode::Write); + auto file = maybe_file.release_value(); + + EXPECT(!file->truncate(999).is_error()); + EXPECT_EQ(file->size().release_value(), 999); + + EXPECT(!file->truncate(42).is_error()); + EXPECT_EQ(file->size().release_value(), 42); +} + // TCPSocket tests TEST_CASE(should_error_when_connection_fails) diff --git a/Userland/Libraries/LibCore/MemoryStream.h b/Userland/Libraries/LibCore/MemoryStream.h index aee618313a..5eeb066acf 100644 --- a/Userland/Libraries/LibCore/MemoryStream.h +++ b/Userland/Libraries/LibCore/MemoryStream.h @@ -26,6 +26,8 @@ public: virtual bool is_open() const override { return true; } // FIXME: It doesn't make sense to close an memory stream. Therefore, we don't do anything here. Is that fine? virtual void close() override { } + // FIXME: It doesn't make sense to truncate a memory stream. Therefore, we don't do anything here. Is that fine? + virtual ErrorOr truncate(off_t) override { return Error::from_errno(ENOTSUP); } virtual ErrorOr read(Bytes bytes) override { diff --git a/Userland/Libraries/LibCore/Stream.cpp b/Userland/Libraries/LibCore/Stream.cpp index 0498ab3f46..0fce083488 100644 --- a/Userland/Libraries/LibCore/Stream.cpp +++ b/Userland/Libraries/LibCore/Stream.cpp @@ -215,6 +215,11 @@ ErrorOr File::seek(i64 offset, SeekMode mode) return seek_result; } +ErrorOr File::truncate(off_t length) +{ + return System::ftruncate(m_fd, length); +} + ErrorOr Socket::create_fd(SocketDomain domain, SocketType type) { int socket_domain; diff --git a/Userland/Libraries/LibCore/Stream.h b/Userland/Libraries/LibCore/Stream.h index 3757115425..8aba029f45 100644 --- a/Userland/Libraries/LibCore/Stream.h +++ b/Userland/Libraries/LibCore/Stream.h @@ -81,6 +81,9 @@ public: /// Returns the total size of the stream, or an errno in the case of an /// error. May not preserve the original position on the stream on failure. virtual ErrorOr size(); + /// Shrinks or extends the stream to the given size. Returns an errno in + /// the case of an error. + virtual ErrorOr truncate(off_t length) = 0; }; /// The Socket class is the base class for all concrete BSD-style socket @@ -197,6 +200,7 @@ public: virtual bool is_open() const override; virtual void close() override; virtual ErrorOr seek(i64 offset, SeekMode) override; + virtual ErrorOr truncate(off_t length) override; virtual ~File() override { close(); } @@ -757,6 +761,10 @@ public: m_helper.clear_buffer(); return result; } + virtual ErrorOr truncate(off_t length) override + { + return m_helper.stream().truncate(length); + } ErrorOr read_line(Bytes buffer) { return m_helper.read_line(move(buffer)); } ErrorOr read_until(Bytes buffer, StringView candidate) { return m_helper.read_until(move(buffer), move(candidate)); }