@@ -204,5 +204,61 @@ class LineReader {
204204
205205void 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