Skip to content

Commit d12ef21

Browse files
authored
Merge pull request #1 from phil-opp/read-only
Add support for read-only mapping
2 parents fda4134 + dac0794 commit d12ef21

3 files changed

Lines changed: 76 additions & 28 deletions

File tree

src/lib.rs

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,32 @@ cfg_if! {
4444
}
4545
}
4646

47-
#[derive(Clone, Default)]
47+
#[derive(Clone)]
4848
/// Struct used to configure different parameters before creating a shared memory mapping
4949
pub struct ShmemConf {
5050
owner: bool,
51+
writable: bool,
5152
os_id: Option<String>,
5253
overwrite_flink: bool,
5354
flink_path: Option<PathBuf>,
5455
size: usize,
5556
ext: os_impl::ShmemConfExt,
5657
}
58+
59+
impl Default for ShmemConf {
60+
fn default() -> Self {
61+
Self {
62+
owner: false,
63+
writable: true,
64+
os_id: None,
65+
overwrite_flink: false,
66+
flink_path: None,
67+
size: Default::default(),
68+
ext: Default::default(),
69+
}
70+
}
71+
}
72+
5773
impl Drop for ShmemConf {
5874
fn drop(&mut self) {
5975
// Delete the flink if we are the owner of the mapping
@@ -100,6 +116,14 @@ impl ShmemConf {
100116
self
101117
}
102118

119+
/// Specifies whether the region should be writable by this process.
120+
///
121+
/// Enabled by default.
122+
pub fn writable(mut self, writable: bool) -> Self {
123+
self.writable = writable;
124+
self
125+
}
126+
103127
/// Create a new mapping using the current configuration
104128
pub fn create(mut self) -> Result<Shmem, ShmemError> {
105129
if self.size == 0 {
@@ -118,7 +142,7 @@ impl ShmemConf {
118142
// Generate random ID until one works
119143
loop {
120144
let cur_id = format!("/shmem_{:X}", rand::random::<u64>());
121-
match os_impl::create_mapping(&cur_id, self.size) {
145+
match os_impl::create_mapping(&cur_id, self.size, self.writable) {
122146
Err(ShmemError::MappingIdExists) => continue,
123147
Ok(m) => break m,
124148
Err(e) => {
@@ -127,7 +151,9 @@ impl ShmemConf {
127151
};
128152
}
129153
}
130-
Some(ref specific_id) => os_impl::create_mapping(specific_id, self.size)?,
154+
Some(ref specific_id) => {
155+
os_impl::create_mapping(specific_id, self.size, self.writable)?
156+
}
131157
};
132158
debug!("Created shared memory mapping '{}'", mapping.unique_id);
133159

@@ -204,7 +230,7 @@ impl ShmemConf {
204230
flink_uid.as_str()
205231
};
206232

207-
match os_impl::open_mapping(unique_id, self.size, &self.ext) {
233+
match os_impl::open_mapping(unique_id, self.size, &self.ext, self.writable) {
208234
Ok(m) => {
209235
self.size = m.map_size;
210236
self.owner = false;

src/unix.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ impl MapData {
8181
}
8282

8383
/// Creates a mapping specified by the uid and size
84-
pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, ShmemError> {
84+
pub fn create_mapping(
85+
unique_id: &str,
86+
map_size: usize,
87+
writable: bool,
88+
) -> Result<MapData, ShmemError> {
8589
//Create shared memory file descriptor
8690
debug!("Creating persistent mapping at {}", unique_id);
8791

@@ -124,21 +128,26 @@ pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, Shmem
124128

125129
//Put the mapping in our address space
126130
debug!("Loading mapping into address space");
131+
let access = if writable {
132+
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE
133+
} else {
134+
ProtFlags::PROT_READ
135+
};
127136
new_map.map_ptr = match unsafe {
128137
mmap(
129-
None, //Desired addr
130-
nz_map_size, //size of mapping
131-
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages
132-
MapFlags::MAP_SHARED, //What kind of mapping
133-
new_map.map_fd, //fd
134-
0, //Offset into fd
138+
None, //Desired addr
139+
nz_map_size, //size of mapping
140+
access, //Permissions on pages
141+
MapFlags::MAP_SHARED, //What kind of mapping
142+
new_map.map_fd, //fd
143+
0, //Offset into fd
135144
)
136145
} {
137146
Ok(v) => {
138147
trace!(
139148
"mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}",
140149
new_map.map_size,
141-
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
150+
access,
142151
MapFlags::MAP_SHARED,
143152
new_map.map_fd,
144153
v
@@ -156,6 +165,7 @@ pub fn open_mapping(
156165
unique_id: &str,
157166
_map_size: usize,
158167
_ext: &ShmemConfExt,
168+
writable: bool,
159169
) -> Result<MapData, ShmemError> {
160170
//Open shared memory
161171
debug!("Openning persistent mapping at {}", unique_id);
@@ -195,21 +205,26 @@ pub fn open_mapping(
195205

196206
//Map memory into our address space
197207
debug!("Loading mapping into address space");
208+
let access = if writable {
209+
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE
210+
} else {
211+
ProtFlags::PROT_READ
212+
};
198213
new_map.map_ptr = match unsafe {
199214
mmap(
200-
None, //Desired addr
201-
nz_map_size, //size of mapping
202-
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages
203-
MapFlags::MAP_SHARED, //What kind of mapping
204-
new_map.map_fd, //fd
205-
0, //Offset into fd
215+
None, //Desired addr
216+
nz_map_size, //size of mapping
217+
access, //Permissions on pages
218+
MapFlags::MAP_SHARED, //What kind of mapping
219+
new_map.map_fd, //fd
220+
0, //Offset into fd
206221
)
207222
} {
208223
Ok(v) => {
209224
trace!(
210225
"mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}",
211226
new_map.map_size,
212-
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
227+
access,
213228
MapFlags::MAP_SHARED,
214229
new_map.map_fd,
215230
v

src/windows.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ fn new_map(
136136
mut map_size: usize,
137137
create: bool,
138138
allow_raw: bool,
139+
writable: bool,
139140
) -> Result<MapData, ShmemError> {
140141
// Create file to back the shared memory
141142
let mut file_path = get_tmp_dir()?;
@@ -230,12 +231,13 @@ fn new_map(
230231

231232
//Map mapping into address space
232233
debug!("Loading mapping into address space");
233-
trace!(
234-
"MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)",
235-
map_h,
236-
(FILE_MAP_READ | FILE_MAP_WRITE).0,
237-
);
238-
let map_ptr = match MapViewOfFile(map_h.as_handle(), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0) {
234+
let access = if writable {
235+
FILE_MAP_READ | FILE_MAP_WRITE
236+
} else {
237+
FILE_MAP_READ
238+
};
239+
trace!("MapViewOfFile(0x{:X}, {:X}, 0, 0, 0)", map_h, access.0,);
240+
let map_ptr = match MapViewOfFile(map_h.as_handle(), access, 0, 0, 0) {
239241
Ok(v) => v,
240242
Err(e) => {
241243
return Err(if create {
@@ -267,15 +269,20 @@ fn new_map(
267269
}
268270

269271
//Creates a mapping specified by the uid and size
270-
pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, ShmemError> {
271-
new_map(unique_id, map_size, true, false)
272+
pub fn create_mapping(
273+
unique_id: &str,
274+
map_size: usize,
275+
writable: bool,
276+
) -> Result<MapData, ShmemError> {
277+
new_map(unique_id, map_size, true, false, writable)
272278
}
273279

274280
//Opens an existing mapping specified by its uid
275281
pub fn open_mapping(
276282
unique_id: &str,
277283
map_size: usize,
278284
ext: &ShmemConfExt,
285+
writable: bool,
279286
) -> Result<MapData, ShmemError> {
280-
new_map(unique_id, map_size, false, ext.allow_raw)
287+
new_map(unique_id, map_size, false, ext.allow_raw, writable)
281288
}

0 commit comments

Comments
 (0)