summaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2022-10-24 15:29:59 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2022-10-24 15:29:59 +0100
commitb7b1b264b58c2b7bbe0fc1aafc623e9d609d1f63 (patch)
treebdfb16d18772fc2b2e8af766aa42bb4fa284b60e /src/libutil
parentffc1272554c52d9020076c7b184c723aaee7e07d (diff)
downloadrspamd-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.cxx26
-rw-r--r--src/libutil/cxx/file_util.hxx10
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;
};
/**