From f62a3cb19b4a48d6e8b3f92323ec504d9e66fc6d Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Wed, 10 May 2023 13:01:24 +0200 Subject: [PATCH] Add MmapOptions::map_raw_read_only to avoid intermediate invalid Mmap instances. --- src/lib.rs | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 94019a92..8cc609b6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -497,6 +497,21 @@ impl MmapOptions { MmapInner::map_mut(self.get_len(&file)?, desc.0, self.offset, self.populate) .map(|inner| MmapRaw { inner }) } + + /// Creates a read-only raw memory map + /// + /// This is primarily useful to avoid intermediate `Mmap` instances when + /// read-only access to files modified elsewhere are required. + /// + /// # Errors + /// + /// This method returns an error when the underlying system call fails + pub fn map_raw_read_only(&self, file: T) -> Result { + let desc = file.as_raw_desc(); + + MmapInner::map(self.get_len(&file)?, desc.0, self.offset, self.populate) + .map(|inner| MmapRaw { inner }) + } } /// A handle to an immutable memory mapped buffer. @@ -1166,7 +1181,7 @@ mod test { #[cfg(unix)] use crate::advice::Advice; - use std::fs::OpenOptions; + use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; #[cfg(unix)] use std::os::unix::io::AsRawFd; @@ -1633,6 +1648,22 @@ mod test { assert_eq!(unsafe { std::ptr::read(mmap.as_ptr()) }, b'a'); } + #[test] + fn raw_read_only() { + let tempdir = tempfile::tempdir().unwrap(); + let path = tempdir.path().join("mmaprawro"); + + File::create(&path).unwrap().write_all(b"abc123").unwrap(); + + let mmap = MmapOptions::new() + .map_raw_read_only(&File::open(&path).unwrap()) + .unwrap(); + + assert_eq!(mmap.len(), 6); + assert!(!mmap.as_ptr().is_null()); + assert_eq!(unsafe { std::ptr::read(mmap.as_ptr()) }, b'a'); + } + /// Something that relies on StableDeref #[test] #[cfg(feature = "stable_deref_trait")]