aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-21 20:03:36 -0500
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2016-02-21 20:38:12 -0500
commit273ed4f9042fbdb8fc4f8335638b09058bb5def0 (patch)
tree21d0691f23004d7ec6577cc6b63590dce644372d
parent3552d8db64aa685e658c25ce61761a3974bdcc54 (diff)
Implement write
-rw-r--r--src/operations.cc18
-rw-r--r--src/posix_extras.cc15
-rw-r--r--src/posix_extras.h5
3 files changed, 37 insertions, 1 deletions
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*>(file_info->fh);
+ const std::vector<std::uint8_t> to_write(buffer, buffer + bytes);
+ file->Write(offset, to_write);
+ return static_cast<int>(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<std::uint8_t>& 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<off_t>(bytes_written));
+ if (pwrite_result == -1) {
+ throw SystemError();
+ }
+ bytes_written += static_cast<size_t>(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<std::uint8_t>&);
+
private:
File() {}