diff options
author | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-10-24 15:29:59 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rspamd.com> | 2022-10-24 15:29:59 +0100 |
commit | b7b1b264b58c2b7bbe0fc1aafc623e9d609d1f63 (patch) | |
tree | bdfb16d18772fc2b2e8af766aa42bb4fa284b60e /src/libutil | |
parent | ffc1272554c52d9020076c7b184c723aaee7e07d (diff) | |
download | rspamd-b7b1b264b58c2b7bbe0fc1aafc623e9d609d1f63.tar.gz rspamd-b7b1b264b58c2b7bbe0fc1aafc623e9d609d1f63.zip |
[Minor] Allow to map files at some offset
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/cxx/file_util.cxx | 26 | ||||
-rw-r--r-- | src/libutil/cxx/file_util.hxx | 10 |
2 files changed, 22 insertions, 14 deletions
diff --git a/src/libutil/cxx/file_util.cxx b/src/libutil/cxx/file_util.cxx index 1993ff666..f457a4cd7 100644 --- a/src/libutil/cxx/file_util.cxx +++ b/src/libutil/cxx/file_util.cxx @@ -181,31 +181,36 @@ auto raii_locked_file::unlock() -> raii_file { return raii_file{static_cast<raii_file&&>(std::move(*this))}; } -raii_mmaped_file::raii_mmaped_file(raii_file &&_file, void *_map) - : file(std::move(_file)), map(_map) +raii_mmaped_file::raii_mmaped_file(raii_file &&file, void *map, std::size_t sz) + : file(std::move(file)), map(map), map_size(sz) { } auto raii_mmaped_file::mmap_shared(raii_file &&file, - int flags) -> tl::expected<raii_mmaped_file, error> + int flags, std::int64_t offset) -> tl::expected<raii_mmaped_file, error> { void *map; + if (file.get_stat().st_size < offset || offset < 0) { + return tl::make_unexpected(error { + fmt::format("cannot mmap file {} due to incorrect offset; offset={}, size={}", + file.get_name(), offset, file.get_size()), EINVAL}); + } /* Update stat on file to ensure it is up-to-date */ file.update_stat(); - map = mmap(NULL, file.get_stat().st_size, flags, MAP_SHARED, file.get_fd(), 0); + map = mmap(nullptr, file.get_size() - offset, flags, MAP_SHARED, file.get_fd(), offset); if (map == MAP_FAILED) { - return tl::make_unexpected(error { fmt::format("cannot mmap file at fd: {}: {}", - file.get_fd(), ::strerror(errno)), errno }); + return tl::make_unexpected(error { fmt::format("cannot mmap file {}: {}", + file.get_name(), ::strerror(errno)), errno }); } - return raii_mmaped_file{std::move(file), map}; + return raii_mmaped_file{std::move(file), map, file.get_size() - offset}; } auto raii_mmaped_file::mmap_shared(const char *fname, int open_flags, - int mmap_flags) -> tl::expected<raii_mmaped_file, error> + int mmap_flags, std::int64_t offset) -> tl::expected<raii_mmaped_file, error> { auto file = raii_file::open(fname, open_flags); @@ -213,13 +218,13 @@ auto raii_mmaped_file::mmap_shared(const char *fname, int open_flags, return tl::make_unexpected(file.error()); } - return raii_mmaped_file::mmap_shared(std::move(file.value()), mmap_flags); + return raii_mmaped_file::mmap_shared(std::move(file.value()), mmap_flags, offset); } raii_mmaped_file::~raii_mmaped_file() { if (map != nullptr) { - munmap(map, file.get_stat().st_size); + munmap(map, map_size); } } @@ -227,6 +232,7 @@ raii_mmaped_file::raii_mmaped_file(raii_mmaped_file &&other) noexcept : file(std::move(other.file)) { std::swap(map, other.map); + std::swap(map_size, other.map_size); } auto raii_file_sink::create(const char *fname, int flags, int perms, diff --git a/src/libutil/cxx/file_util.hxx b/src/libutil/cxx/file_util.hxx index 9fbcda540..06073dbab 100644 --- a/src/libutil/cxx/file_util.hxx +++ b/src/libutil/cxx/file_util.hxx @@ -196,14 +196,14 @@ private: */ struct raii_mmaped_file final { ~raii_mmaped_file(); - static auto mmap_shared(raii_file &&file, int flags) -> tl::expected<raii_mmaped_file, error>; - static auto mmap_shared(const char *fname, int open_flags, int mmap_flags) -> tl::expected<raii_mmaped_file, error>; + static auto mmap_shared(raii_file &&file, int flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>; + static auto mmap_shared(const char *fname, int open_flags, int mmap_flags, std::int64_t offset = 0) -> tl::expected<raii_mmaped_file, error>; // Returns a constant pointer to the underlying map auto get_map() const -> void* {return map;} auto get_file() const -> const raii_file& { return file; } // Passes the ownership of the mmaped memory to the callee auto steal_map() -> std::tuple<void *, std::size_t> { - auto ret = std::make_tuple(this->map, file.get_stat().st_size); + auto ret = std::make_tuple(this->map, map_size); this->map = nullptr; return ret; } @@ -212,6 +212,7 @@ struct raii_mmaped_file final { raii_mmaped_file& operator=(raii_mmaped_file &&other) noexcept { std::swap(map, other.map); + std::swap(map_size, other.map_size); file = std::move(other.file); return *this; @@ -225,9 +226,10 @@ struct raii_mmaped_file final { raii_mmaped_file(const raii_mmaped_file &other) = delete; private: /* Is intended to be used with map_shared */ - explicit raii_mmaped_file(raii_file &&_file, void *_map); + explicit raii_mmaped_file(raii_file &&_file, void *_map, std::size_t sz); raii_file file; void *map = nullptr; + std::size_t map_size; }; /** |