From 4b6706a6955b111fb9366fdea2f87c81a9d2edd1 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 2 Apr 2022 13:33:10 +0100 Subject: [PATCH] [Minor] Also allow mmaps to be RAII protected --- src/libutil/cxx/locked_file.cxx | 54 +++++++++++++++++++++++++++- src/libutil/cxx/locked_file.hxx | 63 +++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/src/libutil/cxx/locked_file.cxx b/src/libutil/cxx/locked_file.cxx index 8bbb51bf3..9d47304a9 100644 --- a/src/libutil/cxx/locked_file.cxx +++ b/src/libutil/cxx/locked_file.cxx @@ -7,6 +7,8 @@ #include "libutil/util.h" #include "libutil/unix-std.h" +namespace rspamd::util { + auto raii_locked_file::open(const char *fname, int flags) -> tl::expected { int oflags = flags; @@ -24,7 +26,13 @@ auto raii_locked_file::open(const char *fname, int flags) -> tl::expected tl::expected +{ + void *map; + + map = mmap(NULL, file.get_stat().st_size, flags, MAP_SHARED, file.get_fd(), 0); + + if (map == MAP_FAILED) { + return tl::make_unexpected(fmt::format("cannot mmap file at fd: {}: {}", + file.get_fd(), ::strerror(errno))); + + } + + return raii_mmaped_locked_file{std::move(file), map}; +} + +auto raii_mmaped_locked_file::mmap_shared(const char *fname, int open_flags, + int mmap_flags) -> tl::expected +{ + auto file = raii_locked_file::open(fname, open_flags); + + if (!file.has_value()) { + return tl::make_unexpected(file.error()); + } + + return raii_mmaped_locked_file::mmap_shared(std::move(file.value()), mmap_flags); +} + +raii_mmaped_locked_file::~raii_mmaped_locked_file() +{ + munmap(map, file.get_stat().st_size); +} + +raii_mmaped_locked_file::raii_mmaped_locked_file(raii_mmaped_locked_file &&other) noexcept + : file(std::move(other.file)) +{ + std::swap(map, other.map); +} + +} diff --git a/src/libutil/cxx/locked_file.hxx b/src/libutil/cxx/locked_file.hxx index 63239fcd9..712c75a19 100644 --- a/src/libutil/cxx/locked_file.hxx +++ b/src/libutil/cxx/locked_file.hxx @@ -19,17 +19,80 @@ #include "contrib/expected/expected.hpp" #include +#include +namespace rspamd::util { /** * A simple RAII object to contain a file descriptor with an flock wrap * A file is unlocked and closed when not needed */ struct raii_locked_file final { ~raii_locked_file(); + static auto open(const char *fname, int flags) -> tl::expected; + + auto get_fd() const -> int + { + return fd; + } + + auto get_stat() const -> const struct stat& + { + return st; + }; + + raii_locked_file& operator=(raii_locked_file &&other) noexcept { + std::swap(fd, other.fd); + std::swap(st, other.st); + + return *this; + } + + raii_locked_file(raii_locked_file &&other) noexcept { + *this = std::move(other); + } + + /* Do not allow copy/default ctor */ + const raii_locked_file& operator=(const raii_locked_file &other) = delete; + raii_locked_file() = delete; + raii_locked_file(const raii_locked_file &other) = delete; private: int fd; + struct stat st; + explicit raii_locked_file(int _fd) : fd(_fd) {} }; +/** + * A mmap wrapper on top of a locked file + */ +struct raii_mmaped_locked_file final { + ~raii_mmaped_locked_file(); + static auto mmap_shared(raii_locked_file &&file, int flags) -> tl::expected; + static auto mmap_shared(const char *fname, int open_flags, int mmap_flags) -> tl::expected; + auto get_map() const -> void* {return map;} + auto get_size() const -> std::size_t { return file.get_stat().st_size; } + + raii_mmaped_locked_file& operator=(raii_mmaped_locked_file &&other) noexcept { + std::swap(map, other.map); + file = std::move(other.file); + + return *this; + } + + raii_mmaped_locked_file(raii_mmaped_locked_file &&other) noexcept; + + /* Do not allow copy/default ctor */ + const raii_mmaped_locked_file& operator=(const raii_mmaped_locked_file &other) = delete; + raii_mmaped_locked_file() = delete; + raii_mmaped_locked_file(const raii_mmaped_locked_file &other) = delete; +private: + /* Is intended to be used with map_shared */ + explicit raii_mmaped_locked_file(raii_locked_file &&_file, void *_map); + raii_locked_file file; + void *map{}; +}; + +} + #endif //RSPAMD_LOCKED_FILE_HXX -- 2.39.5