diff options
author | Daichi Hirono <hirono@google.com> | 2016-11-10 09:17:17 +0900 |
---|---|---|
committer | Daichi Hirono <hirono@google.com> | 2016-11-15 10:18:37 +0900 |
commit | 0d97be4d7db1baa831d0432229dec08c87193919 (patch) | |
tree | 7f0bd712b7e52ed12b56c89fb4e743073003d05c /libappfuse | |
parent | a0aecda12b9a76aa15a8c5175e15538574a05af7 (diff) | |
download | core-0d97be4d7db1baa831d0432229dec08c87193919.tar.gz core-0d97be4d7db1baa831d0432229dec08c87193919.tar.bz2 core-0d97be4d7db1baa831d0432229dec08c87193919.zip |
Add static assert to check if FuseBuffer is standard layout union.
Bug: 32260320
Test: libappfuse_test
Change-Id: I6430c11fdeb2405996410c97044b4260c25209b8
Diffstat (limited to 'libappfuse')
-rw-r--r-- | libappfuse/FuseBuffer.cc | 30 | ||||
-rw-r--r-- | libappfuse/include/libappfuse/FuseBuffer.h | 12 |
2 files changed, 26 insertions, 16 deletions
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc index ca47aa8c7..74fe756a9 100644 --- a/libappfuse/FuseBuffer.cc +++ b/libappfuse/FuseBuffer.cc @@ -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) { diff --git a/libappfuse/include/libappfuse/FuseBuffer.h b/libappfuse/include/libappfuse/FuseBuffer.h index 1464142c4..e7f620cb6 100644 --- a/libappfuse/include/libappfuse/FuseBuffer.h +++ b/libappfuse/include/libappfuse/FuseBuffer.h @@ -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; |