Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0967504 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add static assert to check if FuseBuffer is standard layout union."

parents e1d24f84 0d97be4d
Loading
Loading
Loading
Loading
+19 −11
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <unistd.h>

#include <algorithm>
#include <type_traits>

#include <android-base/logging.h>
#include <android-base/macros.h>
@@ -28,9 +29,14 @@
namespace android {
namespace fuse {

template <typename T, typename Header>
bool FuseMessage<T, Header>::CheckHeaderLength() const {
  if (sizeof(Header) <= header.len && header.len <= sizeof(T)) {
static_assert(
    std::is_standard_layout<FuseBuffer>::value,
    "FuseBuffer must be standard layout union.");

template <typename T>
bool FuseMessage<T>::CheckHeaderLength() const {
  const auto& header = static_cast<const T*>(this)->header;
  if (sizeof(header) <= header.len && header.len <= sizeof(T)) {
    return true;
  } else {
    LOG(ERROR) << "Packet size is invalid=" << header.len;
@@ -38,9 +44,10 @@ bool FuseMessage<T, Header>::CheckHeaderLength() const {
  }
}

template <typename T, typename Header>
bool FuseMessage<T, Header>::CheckResult(
template <typename T>
bool FuseMessage<T>::CheckResult(
    int result, const char* operation_name) const {
  const auto& header = static_cast<const T*>(this)->header;
  if (result >= 0 && static_cast<uint32_t>(result) == header.len) {
    return true;
  } else {
@@ -51,14 +58,15 @@ bool FuseMessage<T, Header>::CheckResult(
  }
}

template <typename T, typename Header>
bool FuseMessage<T, Header>::Read(int fd) {
template <typename T>
bool FuseMessage<T>::Read(int fd) {
  const ssize_t result = TEMP_FAILURE_RETRY(::read(fd, this, sizeof(T)));
  return CheckHeaderLength() && CheckResult(result, "read");
}

template <typename T, typename Header>
bool FuseMessage<T, Header>::Write(int fd) const {
template <typename T>
bool FuseMessage<T>::Write(int fd) const {
  const auto& header = static_cast<const T*>(this)->header;
  if (!CheckHeaderLength()) {
    return false;
  }
@@ -66,8 +74,8 @@ bool FuseMessage<T, Header>::Write(int fd) const {
  return CheckResult(result, "write");
}

template struct FuseMessage<FuseRequest, fuse_in_header>;
template struct FuseMessage<FuseResponse, fuse_out_header>;
template class FuseMessage<FuseRequest>;
template class FuseMessage<FuseResponse>;

void FuseRequest::Reset(
    uint32_t data_length, uint32_t opcode, uint64_t unique) {
+7 −5
Original line number Diff line number Diff line
@@ -28,9 +28,9 @@ constexpr size_t kFuseMaxWrite = 256 * 1024;
constexpr size_t kFuseMaxRead = 128 * 1024;
constexpr int32_t kFuseSuccess = 0;

template<typename T, typename Header>
struct FuseMessage {
  Header header;
template<typename T>
class FuseMessage {
 public:
  bool Read(int fd);
  bool Write(int fd) const;
 private:
@@ -40,7 +40,8 @@ struct FuseMessage {

// FuseRequest represents file operation requests from /dev/fuse. It starts
// from fuse_in_header. The body layout depends on the operation code.
struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> {
struct FuseRequest : public FuseMessage<FuseRequest> {
  fuse_in_header header;
  union {
    // for FUSE_WRITE
    struct {
@@ -61,7 +62,8 @@ struct FuseRequest final : public FuseMessage<FuseRequest, fuse_in_header> {

// FuseResponse represents file operation responses to /dev/fuse. It starts
// from fuse_out_header. The body layout depends on the operation code.
struct FuseResponse final : public FuseMessage<FuseResponse, fuse_out_header> {
struct FuseResponse : public FuseMessage<FuseResponse> {
  fuse_out_header header;
  union {
    // for FUSE_INIT
    fuse_init_out init_out;