From 273ed4f9042fbdb8fc4f8335638b09058bb5def0 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sun, 21 Feb 2016 20:03:36 -0500 Subject: Implement write --- src/operations.cc | 18 +++++++++++++++++- src/posix_extras.cc | 15 +++++++++++++++ src/posix_extras.h | 5 +++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/operations.cc b/src/operations.cc index 4428632..b62fdf0 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -157,7 +157,22 @@ int Read(const char*, char* const buffer, const size_t bytes, } } -int Utimens(const char* const path, const timespec times[2]) noexcept { +int Write(const char*, const char* const buffer, const size_t bytes, + const off_t offset, fuse_file_info* const file_info) noexcept { + try { + auto* const file = reinterpret_cast(file_info->fh); + const std::vector to_write(buffer, buffer + bytes); + file->Write(offset, to_write); + return static_cast(bytes); + } catch (const std::system_error& e) { + return -e.code().value(); + } catch (...) { + LOG(ERROR) << "read: caught unexpected value"; + return -ENOTRECOVERABLE; + } +} + +int Utimens(const char* const c_path, const timespec times[2]) noexcept { try { const std::string path(c_path); root_->UTimeNs(path == "/" ? "." : EncodePath(path).c_str(), times[0], @@ -254,6 +269,7 @@ fuse_operations FuseOperations(File* const root) { result.mknod = &Mknod; result.open = &Open; result.read = &Read; + result.write = &Write; result.utimens = &Utimens; result.release = &Release; result.unlink = &Unlink; diff --git a/src/posix_extras.cc b/src/posix_extras.cc index ac6e3b2..7b82f0a 100644 --- a/src/posix_extras.cc +++ b/src/posix_extras.cc @@ -141,6 +141,21 @@ void File::UTimeNs(const char* const path, const timespec& access, } } +size_t File::Write(const off_t offset, + const std::vector& to_write) { + size_t bytes_written = 0; + while (bytes_written < to_write.size()) { + const ssize_t pwrite_result = pwrite( + fd_, to_write.data() + bytes_written, to_write.size() - bytes_written, + offset + static_cast(bytes_written)); + if (pwrite_result == -1) { + throw SystemError(); + } + bytes_written += static_cast(pwrite_result); + } + return bytes_written; +} + int File::Duplicate() const { int result; if ((result = dup(fd_)) == -1) { diff --git a/src/posix_extras.h b/src/posix_extras.h index 5571da6..f92bff7 100644 --- a/src/posix_extras.h +++ b/src/posix_extras.h @@ -95,6 +95,11 @@ class File { void UTimeNs(const char* path, const timespec& access, const timespec& modification) const; + // Writes the specified byte vector to the file at the given offset. Returns + // the number of bytes written, which will always be the number of bytes given + // as input. + size_t Write(off_t, const std::vector&); + private: File() {} -- cgit v1.2.3