diff --git a/src/lib.rs b/src/lib.rs index 3f05937..7021003 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -44,16 +44,32 @@ cfg_if! { } } -#[derive(Clone, Default)] +#[derive(Clone)] /// Struct used to configure different parameters before creating a shared memory mapping pub struct ShmemConf { owner: bool, + writable: bool, os_id: Option, overwrite_flink: bool, flink_path: Option, size: usize, ext: os_impl::ShmemConfExt, } + +impl Default for ShmemConf { + fn default() -> Self { + Self { + owner: false, + writable: true, + os_id: None, + overwrite_flink: false, + flink_path: None, + size: Default::default(), + ext: Default::default(), + } + } +} + impl Drop for ShmemConf { fn drop(&mut self) { // Delete the flink if we are the owner of the mapping @@ -100,6 +116,14 @@ impl ShmemConf { self } + /// Specifies whether the region should be writable by this process. + /// + /// Enabled by default. + pub fn writable(mut self, writable: bool) -> Self { + self.writable = writable; + self + } + /// Create a new mapping using the current configuration pub fn create(mut self) -> Result { if self.size == 0 { @@ -118,7 +142,7 @@ impl ShmemConf { // Generate random ID until one works loop { let cur_id = format!("/shmem_{:X}", rand::random::()); - match os_impl::create_mapping(&cur_id, self.size) { + match os_impl::create_mapping(&cur_id, self.size, self.writable) { Err(ShmemError::MappingIdExists) => continue, Ok(m) => break m, Err(e) => { @@ -127,7 +151,9 @@ impl ShmemConf { }; } } - Some(ref specific_id) => os_impl::create_mapping(specific_id, self.size)?, + Some(ref specific_id) => { + os_impl::create_mapping(specific_id, self.size, self.writable)? + } }; debug!("Created shared memory mapping '{}'", mapping.unique_id); @@ -204,7 +230,7 @@ impl ShmemConf { flink_uid.as_str() }; - match os_impl::open_mapping(unique_id, self.size, &self.ext) { + match os_impl::open_mapping(unique_id, self.size, &self.ext, self.writable) { Ok(m) => { self.size = m.map_size; self.owner = false; diff --git a/src/unix.rs b/src/unix.rs index 86b40c0..29214df 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -81,7 +81,11 @@ impl MapData { } /// Creates a mapping specified by the uid and size -pub fn create_mapping(unique_id: &str, map_size: usize) -> Result { +pub fn create_mapping( + unique_id: &str, + map_size: usize, + writable: bool, +) -> Result { //Create shared memory file descriptor debug!("Creating persistent mapping at {}", unique_id); @@ -124,21 +128,26 @@ pub fn create_mapping(unique_id: &str, map_size: usize) -> Result { trace!( "mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}", new_map.map_size, - ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, + access, MapFlags::MAP_SHARED, new_map.map_fd, v @@ -156,6 +165,7 @@ pub fn open_mapping( unique_id: &str, _map_size: usize, _ext: &ShmemConfExt, + writable: bool, ) -> Result { //Open shared memory debug!("Openning persistent mapping at {}", unique_id); @@ -195,21 +205,26 @@ pub fn open_mapping( //Map memory into our address space debug!("Loading mapping into address space"); + let access = if writable { + ProtFlags::PROT_READ | ProtFlags::PROT_WRITE + } else { + ProtFlags::PROT_READ + }; new_map.map_ptr = match unsafe { mmap( - None, //Desired addr - nz_map_size, //size of mapping - ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages - MapFlags::MAP_SHARED, //What kind of mapping - new_map.map_fd, //fd - 0, //Offset into fd + None, //Desired addr + nz_map_size, //size of mapping + access, //Permissions on pages + MapFlags::MAP_SHARED, //What kind of mapping + new_map.map_fd, //fd + 0, //Offset into fd ) } { Ok(v) => { trace!( "mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}", new_map.map_size, - ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, + access, MapFlags::MAP_SHARED, new_map.map_fd, v diff --git a/src/windows.rs b/src/windows.rs index 96f4a59..6e3453e 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -136,6 +136,7 @@ fn new_map( mut map_size: usize, create: bool, allow_raw: bool, + writable: bool, ) -> Result { // Create file to back the shared memory let mut file_path = get_tmp_dir()?; @@ -230,12 +231,13 @@ fn new_map( //Map mapping into address space debug!("Loading mapping into address space"); - trace!( - "MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)", - map_h, - (FILE_MAP_READ | FILE_MAP_WRITE).0, - ); - let map_ptr = match MapViewOfFile(map_h.as_handle(), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0) { + let access = if writable { + FILE_MAP_READ | FILE_MAP_WRITE + } else { + FILE_MAP_READ + }; + trace!("MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)", map_h, access.0,); + let map_ptr = match MapViewOfFile(map_h.as_handle(), access, 0, 0, 0) { Ok(v) => v, Err(e) => { return Err(if create { @@ -267,8 +269,12 @@ fn new_map( } //Creates a mapping specified by the uid and size -pub fn create_mapping(unique_id: &str, map_size: usize) -> Result { - new_map(unique_id, map_size, true, false) +pub fn create_mapping( + unique_id: &str, + map_size: usize, + writable: bool, +) -> Result { + new_map(unique_id, map_size, true, false, writable) } //Opens an existing mapping specified by its uid @@ -276,6 +282,7 @@ pub fn open_mapping( unique_id: &str, map_size: usize, ext: &ShmemConfExt, + writable: bool, ) -> Result { - new_map(unique_id, map_size, false, ext.allow_raw) + new_map(unique_id, map_size, false, ext.allow_raw, writable) }