Skip to content

Commit e7e9809

Browse files
authored
sys::mman: adding MREMAP_DONTUNMAP flag for mremap on Linux. (#2555)
Is meant to be used with `MREMAP_MAYMOVE` and allow to not unmapping `old_address`.
1 parent 5c542f4 commit e7e9809

File tree

3 files changed

+42
-0
lines changed

3 files changed

+42
-0
lines changed

changelog/2555.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add `MremapFlags::MREMAP_DONTUNMAP` to `sys::mman::mremap` for linux target.

src/sys/mman.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ libc_bitflags! {
205205
/// Place the mapping at exactly the address specified in `new_address`.
206206
#[cfg(target_os = "linux")]
207207
MREMAP_FIXED;
208+
/// Works in conjunction with `MREMAP_MAYMOVE` but does not unmap `old_address`.
209+
/// Note that, in this case, `old_size` and `new_size` must be the same.
210+
#[cfg(target_os = "linux")]
211+
MREMAP_DONTUNMAP;
208212
/// Place the mapping at exactly the address specified in `new_address`.
209213
#[cfg(target_os = "netbsd")]
210214
MAP_FIXED;

test/sys/test_mman.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,40 @@ fn test_mremap_shrink() {
119119
// The first KB should still be accessible and have the old data in it.
120120
assert_eq!(slice[ONE_K - 1], 0xFF);
121121
}
122+
123+
#[test]
124+
#[cfg(target_os = "linux")]
125+
fn test_mremap_dontunmap() {
126+
use nix::libc::size_t;
127+
use nix::sys::mman::{mremap, MRemapFlags};
128+
use std::num::NonZeroUsize;
129+
use std::ptr::NonNull;
130+
131+
const ONE_K: size_t = 1024;
132+
let one_k_non_zero = NonZeroUsize::new(ONE_K).unwrap();
133+
134+
let slice: &mut [u8] = unsafe {
135+
let mem = mmap_anonymous(
136+
None,
137+
one_k_non_zero,
138+
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
139+
MapFlags::MAP_PRIVATE,
140+
)
141+
.unwrap();
142+
std::slice::from_raw_parts_mut(mem.as_ptr().cast(), ONE_K)
143+
};
144+
145+
// because we do not unmap `slice`, `old_size` and `new_size`
146+
// need to be equal or `EINVAL` is set.
147+
let _new_slice: &mut [u8] = unsafe {
148+
let mem = mremap(
149+
NonNull::from(&mut slice[..]).cast(),
150+
ONE_K,
151+
ONE_K,
152+
MRemapFlags::MREMAP_MAYMOVE | MRemapFlags::MREMAP_DONTUNMAP,
153+
None,
154+
)
155+
.unwrap();
156+
std::slice::from_raw_parts_mut(mem.cast().as_ptr(), 10 * ONE_K)
157+
};
158+
}

0 commit comments

Comments
 (0)