Skip to content

Commit b59d21b

Browse files
committed
Proper handling of memory maps
1 parent 1111686 commit b59d21b

File tree

3 files changed

+62
-7
lines changed

3 files changed

+62
-7
lines changed

src/command_line.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -559,15 +559,14 @@ void CommandLine::mergeConfigFile(const std::filesystem::path & path) {
559559
return;
560560
}
561561

562-
void * content = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, c_fd(file), 0);
563-
if (content == MAP_FAILED) {
564-
ec = std::error_code(errno, std::system_category());
562+
ptl::MemoryMap content(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, file, 0, ec);
563+
if (ec) {
565564
WSDLOG_WARN("Cannot map config file {}, error: {}", path.c_str(), ec.message());
566565
return;
567566
}
568567

569568
try {
570-
auto cfg = toml::parse(std::string_view((const char *)content, st.st_size), path.string());
569+
auto cfg = toml::parse(std::string_view((const char *)content.data(), content.size()), path.string());
571570

572571
for (auto && [key, value] : cfg) {
573572

src/config_samba.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,14 +82,14 @@ static auto paramsFromSmbConf(const std::filesystem::path & path) -> std::option
8282
if (ec)
8383
return {};
8484

85-
void * bytes = mmap(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, c_fd(file), 0);
86-
if (bytes == MAP_FAILED)
85+
ptl::MemoryMap bytes(nullptr, st.st_size, PROT_READ, MAP_PRIVATE, c_fd(file), 0, ec);
86+
if (ec)
8787
return {};
8888

8989

9090
WSDLOG_TRACE("reading smb.conf");
9191

92-
std::string_view content((const char *)bytes, st.st_size);
92+
std::string_view content((const char *)bytes.data(), bytes.size());
9393

9494
std::regex sectionRe(R"##(\s*\[([^\]]*)\].*)##", std::regex_constants::ECMAScript);
9595
std::regex entryRe(R"##(\s*([^ \t#;=][^=#;]*)\s*=\s*((?:[^ \t#;][^#;]*)?).*)##", std::regex_constants::ECMAScript);

src/sys_util.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,61 @@ class LineReader {
204204

205205
void shell(const ptl::StringRefArray & args, bool suppressStdErr, std::function<void (const ptl::FileDescriptor & fd)> reader);
206206

207+
namespace ptl {
208+
class MemoryMap {
209+
public:
210+
MemoryMap() noexcept = default;
211+
212+
MemoryMap(void * addr, size_t length,
213+
int prot, int flags,
214+
ptl::FileDescriptorLike auto && desc,
215+
off_t offset,
216+
PTL_ERROR_REF_ARG(err)) requires(PTL_ERROR_REQ(err)) :
217+
m_ptr(::mmap(addr, length, prot, flags, c_fd(std::forward<decltype(desc)>(desc)), offset))
218+
{
219+
220+
if (m_ptr == MAP_FAILED) {
221+
handleError(PTL_ERROR_REF(err), errno, "mmap({}, {}, {}, {}, {}, {}) failed",
222+
addr, length, prot, flags, c_fd(std::forward<decltype(desc)>(desc)), offset);
223+
} else {
224+
m_size = length;
225+
clearError(PTL_ERROR_REF(err));
226+
}
227+
}
228+
~MemoryMap() {
229+
if (m_ptr != MAP_FAILED)
230+
munmap(m_ptr, m_size);
231+
}
232+
MemoryMap(const MemoryMap &) = delete;
233+
234+
MemoryMap(MemoryMap && src) :
235+
m_ptr(std::exchange(src.m_ptr, MAP_FAILED)),
236+
m_size(std::exchange(src.m_size, 0))
237+
{}
238+
239+
MemoryMap & operator=(MemoryMap src) noexcept {
240+
swap(src, *this);
241+
return *this;
242+
}
243+
244+
void close() noexcept {
245+
*this = MemoryMap();
246+
}
247+
248+
friend void swap(MemoryMap & lhs, MemoryMap & rhs) noexcept {
249+
std::swap(lhs.m_ptr, rhs.m_ptr);
250+
std::swap(lhs.m_size, rhs.m_size);
251+
}
252+
253+
auto data() const -> void *
254+
{ return m_ptr; }
255+
auto size() const -> size_t
256+
{ return m_size; }
257+
private:
258+
void * m_ptr = MAP_FAILED;
259+
size_t m_size = 0;
260+
};
261+
262+
}
207263

208264
#endif

0 commit comments

Comments
 (0)