diff options
-rw-r--r-- | src/operations.cc | 33 | ||||
-rw-r--r-- | src/posix_extras.cc | 18 | ||||
-rw-r--r-- | src/posix_extras.h | 7 |
3 files changed, 58 insertions, 0 deletions
diff --git a/src/operations.cc b/src/operations.cc index 355ffc3..897b193 100644 --- a/src/operations.cc +++ b/src/operations.cc @@ -25,8 +25,10 @@ #include <new> #include <system_error> #include <type_traits> +#include <vector> #include <dirent.h> +#include <fcntl.h> #include <glog/logging.h> #include <sys/stat.h> #include <sys/types.h> @@ -75,6 +77,19 @@ int Getattr(const char* const path, struct stat* output) noexcept { } } +int Fgetattr(const char*, struct stat* const output, + struct fuse_file_info* const file_info) noexcept { + try { + *output = reinterpret_cast<File*>(file_info->fh)->Stat(); + return 0; + } catch (const std::system_error& e) { + return -e.code().value(); + } catch (...) { + LOG(ERROR) << "getattr: caught unexpected value"; + return -ENOTRECOVERABLE; + } +} + template <typename T> int OpenResource(const char* const path, const int flags, uint64_t* const handle) noexcept { @@ -131,6 +146,22 @@ int Open(const char* const path, fuse_file_info* const file_info) noexcept { return OpenResource<File>(path, file_info->flags, &file_info->fh); } +int Read(const char*, char* const buffer, const size_t bytes, + const off_t offset, fuse_file_info* const file_info) noexcept { + LOG(INFO) << "read with offset " << offset; + try { + auto* const file = reinterpret_cast<File*>(file_info->fh); + const std::vector<std::uint8_t> read = file->Read(offset, bytes); + std::memcpy(buffer, read.data(), read.size()); + return static_cast<int>(read.size()); + } catch (const std::system_error& e) { + return -e.code().value(); + } catch (...) { + LOG(ERROR) << "read: caught unexpected value"; + return -ENOTRECOVERABLE; + } +} + int Utimens(const char* const path, const timespec times[2]) noexcept { try { root_->UTimeNs( @@ -230,9 +261,11 @@ fuse_operations FuseOperations(File* const root) { result.destroy = &Destroy; result.getattr = &Getattr; + result.fgetattr = &Fgetattr; result.mknod = &Mknod; result.open = &Open; + result.read = &Read; result.utimens = &Utimens; result.release = &Release; result.unlink = &Unlink; diff --git a/src/posix_extras.cc b/src/posix_extras.cc index 7529251..ac6e3b2 100644 --- a/src/posix_extras.cc +++ b/src/posix_extras.cc @@ -16,9 +16,11 @@ #include <array> #include <cerrno> +#include <cstdint> #include <experimental/optional> #include <stdexcept> #include <system_error> +#include <vector> #include <dirent.h> #include <fcntl.h> @@ -101,6 +103,22 @@ File File::OpenAt(const char* const path, const int flags, return result; } +std::vector<std::uint8_t> File::Read(off_t offset, size_t bytes) const { + std::vector<std::uint8_t> result(bytes, 0); + size_t cursor = 0; + ssize_t bytes_read; + while (0 < (bytes_read = pread(fd_, result.data() + cursor, bytes, offset))) { + cursor += static_cast<size_t>(bytes_read); + offset += bytes_read; + bytes -= static_cast<size_t>(bytes_read); + } + if (bytes_read == -1) { + throw SystemError(); + } + result.resize(cursor); + return result; +} + void File::UnlinkAt(const char* const path) const { if (path[0] == '/') { throw std::invalid_argument("absolute path"); diff --git a/src/posix_extras.h b/src/posix_extras.h index a73f9fe..5571da6 100644 --- a/src/posix_extras.h +++ b/src/posix_extras.h @@ -15,8 +15,10 @@ #ifndef POSIX_EXTRAS_H_ #define POSIX_EXTRAS_H_ +#include <cstdint> #include <experimental/optional> #include <string> +#include <vector> #include <dirent.h> #include <sys/stat.h> @@ -78,6 +80,11 @@ class File { } File OpenAt(const char* path, int flags, mode_t mode) const; + // Reads exactly the specified number of bytes from the file at the given + // offset, unless doing so would run past the end of the file, in which case + // fewer bytes are returned. + std::vector<std::uint8_t> Read(off_t, size_t) const; + // Removes the file at the path relative to the file descriptor. The path // must indeed be relative (i.e., it must not start with '/'). void UnlinkAt(const char* path) const; |