pub unsafe fn mmap(
start: usize,
len: size_t,
prot: i32,
flags: i32,
fd: i32,
offset: off_t
) -> Result<usize, Errno>
Expand description
Map files or devices into memory.
§Example
let path = "/etc/passwd";
let ret = unsafe { nc::openat(nc::AT_FDCWD, path, nc::O_RDONLY, 0o644) };
assert!(ret.is_ok());
let fd = ret.unwrap();
let mut sb = nc::stat_t::default();
let ret = unsafe { nc::fstat(fd, &mut sb) };
assert!(ret.is_ok());
let offset: usize = 0;
let length: usize = sb.st_size as usize - offset;
// Offset for mmap must be page aligned.
let pa_offset: usize = offset & !(nc::PAGE_SIZE - 1);
let map_length = length + offset - pa_offset;
let addr = unsafe {
nc::mmap(
0, // 0 as NULL
map_length,
nc::PROT_READ,
nc::MAP_PRIVATE,
fd,
pa_offset as nc::off_t,
)
};
assert!(addr.is_ok());
let addr = addr.unwrap();
let n_write = unsafe { nc::write(1, addr + offset - pa_offset, length) };
assert!(n_write.is_ok());
assert_eq!(n_write, Ok(length as nc::ssize_t));
let ret = unsafe { nc::munmap(addr, map_length) };
assert!(ret.is_ok());
let ret = unsafe { nc::close(fd) };
assert!(ret.is_ok());
Examples found in repository?
examples/mmap.rs (lines 34-41)
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
fn main() {
let path = "/etc/passwd";
let fd = unsafe { nc::openat(nc::AT_FDCWD, path, nc::O_RDONLY, 0o644) };
assert!(fd.is_ok());
let fd = fd.unwrap();
let mut sb = nc::stat_t::default();
let ret = unsafe { nc::fstat(fd, &mut sb) };
assert!(ret.is_ok());
let offset: usize = 0;
let length: usize = sb.st_size as usize - offset;
// Offset for mmap must be page aligned.
let pa_offset: usize = offset & !(nc::PAGE_SIZE - 1);
let map_length = length + offset - pa_offset;
#[cfg(target_arch = "arm")]
let addr = unsafe {
nc::mmap2(
0, // 0 as NULL
map_length,
nc::PROT_READ,
nc::MAP_PRIVATE,
fd,
pa_offset as nc::off_t,
)
};
#[cfg(not(target_arch = "arm"))]
let addr = unsafe {
nc::mmap(
0, // 0 as NULL
map_length,
nc::PROT_READ,
nc::MAP_PRIVATE,
fd,
pa_offset as nc::off_t,
)
};
assert!(addr.is_ok());
let addr = addr.unwrap();
let n_write = unsafe { nc::write(1, addr + offset - pa_offset, length) };
assert!(n_write.is_ok());
assert_eq!(n_write, Ok(length as nc::ssize_t));
let ret = unsafe { nc::munmap(addr, map_length) };
assert!(ret.is_ok());
let ret = unsafe { nc::close(fd) };
assert!(ret.is_ok());
}
More examples
examples/mprotect.rs (lines 46-53)
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
fn main() {
// Register SIGSEGV handler.
let sa = nc::sigaction_t {
sa_handler: handle_segfault as nc::sighandler_t,
sa_flags: nc::SA_SIGINFO,
..nc::sigaction_t::default()
};
let mut old_sa = nc::sigaction_t::default();
let ret = unsafe {
nc::rt_sigaction(
nc::SIGSEGV,
&sa,
&mut old_sa,
mem::size_of::<nc::sigset_t>(),
)
};
assert!(ret.is_ok());
// Initialize an anonymous mapping with 4 pages.
let map_length = 4 * nc::PAGE_SIZE;
#[cfg(target_arch = "arm")]
let addr = unsafe {
nc::mmap2(
0,
map_length,
nc::PROT_READ | nc::PROT_WRITE,
nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
-1,
0,
)
};
#[cfg(not(target_arch = "arm"))]
let addr = unsafe {
nc::mmap(
0,
map_length,
nc::PROT_READ | nc::PROT_WRITE,
nc::MAP_PRIVATE | nc::MAP_ANONYMOUS,
-1,
0,
)
};
assert!(addr.is_ok());
let addr = addr.unwrap();
// Set the third page readonly. And we will run into SIGSEGV when updating it.
let ret = unsafe { nc::mprotect(addr + 2 * nc::PAGE_SIZE, nc::PAGE_SIZE, nc::PROT_READ) };
assert!(ret.is_ok());
for p in addr..(addr + map_length) {
unsafe {
*(p as *mut u8) = 42;
}
}
let ret = unsafe { nc::munmap(addr, map_length) };
assert!(ret.is_ok());
unsafe { nc::exit(0) };
}