diff --git a/base/cvd/cuttlefish/common/libs/fs/shared_fd.cpp b/base/cvd/cuttlefish/common/libs/fs/shared_fd.cpp index 070add1ee4c..2ba85ed8be6 100644 --- a/base/cvd/cuttlefish/common/libs/fs/shared_fd.cpp +++ b/base/cvd/cuttlefish/common/libs/fs/shared_fd.cpp @@ -934,6 +934,12 @@ ssize_t FileInstance::Read(void* buf, size_t count) { return TEMP_FAILURE_RETRY(read(fd_, buf, count)); } +ssize_t FileInstance::PRead(void* buf, size_t count, size_t offset) { + LocalErrno record_errno(errno_); + + return TEMP_FAILURE_RETRY(pread(fd_, buf, count, offset)); +} + #ifdef __linux__ int FileInstance::EventfdRead(eventfd_t* value) { LocalErrno record_errno(errno_); @@ -1028,6 +1034,12 @@ ssize_t FileInstance::Write(const void* buf, size_t count) { return TEMP_FAILURE_RETRY(write(fd_, buf, count)); } +ssize_t FileInstance::PWrite(const void* buf, size_t count, size_t offset) { + LocalErrno record_errno(errno_); + + return TEMP_FAILURE_RETRY(pwrite(fd_, buf, count, offset)); +} + #ifdef __linux__ int FileInstance::EventfdWrite(eventfd_t value) { LocalErrno record_errno(errno_); diff --git a/base/cvd/cuttlefish/common/libs/fs/shared_fd.h b/base/cvd/cuttlefish/common/libs/fs/shared_fd.h index 7390d3a85c9..99d7e79e5a0 100644 --- a/base/cvd/cuttlefish/common/libs/fs/shared_fd.h +++ b/base/cvd/cuttlefish/common/libs/fs/shared_fd.h @@ -358,6 +358,7 @@ class FileInstance { ssize_t Recv(void* buf, size_t len, int flags); ssize_t RecvMsg(struct msghdr* msg, int flags); ssize_t Read(void* buf, size_t count); + ssize_t PRead(void* buf, size_t count, size_t offset); #ifdef __linux__ int EventfdRead(eventfd_t* value); #endif @@ -391,6 +392,7 @@ class FileInstance { * */ ssize_t Write(const void* buf, size_t count); + ssize_t PWrite(const void* buf, size_t count, size_t offset); #ifdef __linux__ int EventfdWrite(eventfd_t value); #endif diff --git a/base/cvd/cuttlefish/io/BUILD.bazel b/base/cvd/cuttlefish/io/BUILD.bazel new file mode 100644 index 00000000000..6e7b32c7885 --- /dev/null +++ b/base/cvd/cuttlefish/io/BUILD.bazel @@ -0,0 +1,25 @@ +load("//cuttlefish/bazel:rules.bzl", "cf_cc_library") + +package( + default_visibility = ["//:android_cuttlefish"], +) + +cf_cc_library( + name = "io", + hdrs = ["io.h"], + deps = [ + "//cuttlefish/result:result_type", + ], +) + +cf_cc_library( + name = "shared_fd", + srcs = ["shared_fd.cc"], + hdrs = ["shared_fd.h"], + deps = [ + "//cuttlefish/common/libs/fs", + "//cuttlefish/io", + "//cuttlefish/result:expect", + "//cuttlefish/result:result_type", + ], +) diff --git a/base/cvd/cuttlefish/io/io.h b/base/cvd/cuttlefish/io/io.h new file mode 100644 index 00000000000..e61992de52e --- /dev/null +++ b/base/cvd/cuttlefish/io/io.h @@ -0,0 +1,58 @@ +// +// Copyright (C) 2026 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#include "cuttlefish/result/result_type.h" + +namespace cuttlefish { + +class Reader { + public: + virtual Result Read(void* buf, size_t count) = 0; +}; + +class Writer { + public: + virtual Result Write(const void* buf, size_t count) = 0; +}; + +class Seeker { + public: + virtual Result SeekSet(size_t offset) = 0; + virtual Result SeekCur(ssize_t offset) = 0; + virtual Result SeekEnd(ssize_t offset) = 0; +}; + +class ReaderSeeker : virtual public Reader, virtual public Seeker { + public: + virtual Result PRead(void* buf, size_t count, + size_t offset) const = 0; +}; + +class SeekerWriter : virtual public Seeker, virtual public Writer { + public: + virtual Result PWrite(const void* buf, size_t count, + size_t offset) const = 0; +}; + +class ReaderWriter : virtual public Reader, virtual public Writer {}; + +class ReaderSeekerWriter : virtual public ReaderSeeker, + virtual public SeekerWriter {}; + +} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/io/shared_fd.cc b/base/cvd/cuttlefish/io/shared_fd.cc new file mode 100644 index 00000000000..c2ef16f6fe6 --- /dev/null +++ b/base/cvd/cuttlefish/io/shared_fd.cc @@ -0,0 +1,73 @@ +// +// Copyright (C) 2026 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "cuttlefish/io/shared_fd.h" + +#include +#include + +#include + +#include "cuttlefish/common/libs/fs/shared_fd.h" +#include "cuttlefish/result/expect.h" +#include "cuttlefish/result/result_type.h" + +namespace cuttlefish { + +SharedFdIo::SharedFdIo(SharedFD fd) : fd_(std::move(fd)) {} + +Result SharedFdIo::Read(void* buf, size_t count) { + ssize_t data_read = fd_->Read(buf, count); + CF_EXPECT_GE(data_read, 0, fd_->StrError()); + return data_read; +} + +Result SharedFdIo::Write(const void* buf, size_t count) { + ssize_t data_written = fd_->Write(buf, count); + CF_EXPECT_GE(data_written, 0, fd_->StrError()); + return data_written; +} + +Result SharedFdIo::SeekSet(size_t offset) { + CF_EXPECT_EQ(fd_->LSeek(offset, SEEK_SET), offset, fd_->StrError()); + return offset; +} + +Result SharedFdIo::SeekCur(ssize_t offset) { + ssize_t new_offset = fd_->LSeek(offset, SEEK_CUR); + CF_EXPECT_GE(new_offset, 0, fd_->StrError()); + return new_offset; +} + +Result SharedFdIo::SeekEnd(ssize_t offset) { + ssize_t new_offset = fd_->LSeek(offset, SEEK_END); + CF_EXPECT_GE(new_offset, 0, fd_->StrError()); + return new_offset; +} + +Result SharedFdIo::PRead(void* buf, size_t count, size_t offset) const { + ssize_t data_read = fd_->PRead(buf, count, offset); + CF_EXPECT_GE(data_read, 0, fd_->StrError()); + return data_read; +} + +Result SharedFdIo::PWrite(const void* buf, size_t count, + size_t offset) const { + ssize_t data_written = fd_->PWrite(buf, count, offset); + CF_EXPECT_GE(data_written, 0, fd_->StrError()); + return data_written; +} + +} // namespace cuttlefish diff --git a/base/cvd/cuttlefish/io/shared_fd.h b/base/cvd/cuttlefish/io/shared_fd.h new file mode 100644 index 00000000000..c80694d3562 --- /dev/null +++ b/base/cvd/cuttlefish/io/shared_fd.h @@ -0,0 +1,43 @@ +// +// Copyright (C) 2026 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include + +#include "cuttlefish/common/libs/fs/shared_fd.h" +#include "cuttlefish/io/io.h" +#include "cuttlefish/result/result_type.h" + +namespace cuttlefish { + +class SharedFdIo : public ReaderSeekerWriter { + public: + explicit SharedFdIo(SharedFD); + + Result Read(void* buf, size_t count) override; + Result Write(const void* buf, size_t count) override; + Result SeekSet(size_t offset) override; + Result SeekCur(ssize_t offset) override; + Result SeekEnd(ssize_t offset) override; + Result PRead(void* buf, size_t count, size_t offset) const override; + Result PWrite(const void* buf, size_t count, + size_t offset) const override; + + private: + SharedFD fd_; +}; + +} // namespace cuttlefish