@ -2,11 +2,10 @@
//! of memory.
//! of memory.
use anyhow ::anyhow ;
use anyhow ::anyhow ;
use anyhow ::{ bail , Context , Result } ;
use anyhow ::{ Context , Result } ;
use more_asserts ::assert_le ;
use more_asserts ::assert_le ;
use std ::convert ::TryFrom ;
use std ::convert ::TryFrom ;
use std ::fs ::File ;
use std ::fs ::File ;
use std ::io ;
use std ::ops ::Range ;
use std ::ops ::Range ;
use std ::path ::Path ;
use std ::path ::Path ;
use std ::ptr ;
use std ::ptr ;
@ -57,8 +56,6 @@ impl Mmap {
pub fn from_file ( path : & Path ) -> Result < Self > {
pub fn from_file ( path : & Path ) -> Result < Self > {
#[ cfg(unix) ]
#[ cfg(unix) ]
{
{
use std ::os ::unix ::prelude ::* ;
let file = File ::open ( path ) . context ( "failed to open file" ) ? ;
let file = File ::open ( path ) . context ( "failed to open file" ) ? ;
let len = file
let len = file
. metadata ( )
. metadata ( )
@ -66,19 +63,16 @@ impl Mmap {
. len ( ) ;
. len ( ) ;
let len = usize ::try_from ( len ) . map_err ( | _ | anyhow ! ( "file too large to map" ) ) ? ;
let len = usize ::try_from ( len ) . map_err ( | _ | anyhow ! ( "file too large to map" ) ) ? ;
let ptr = unsafe {
let ptr = unsafe {
libc ::mmap (
rsix ::io ::mmap (
ptr ::null_mut ( ) ,
ptr ::null_mut ( ) ,
len ,
len ,
libc ::PROT_ READ,
rsix ::io ::ProtFlags ::READ ,
libc ::MAP_ PRIVATE,
rsix ::io ::MapFlags ::PRIVATE ,
file . as_raw_fd ( ) ,
& file ,
0 ,
0 ,
)
)
. context ( format ! ( "mmap failed to allocate {:#x} bytes" , len ) ) ?
} ;
} ;
if ptr as isize = = - 1_ isize {
return Err ( io ::Error ::last_os_error ( ) )
. context ( format ! ( "mmap failed to allocate {:#x} bytes" , len ) ) ;
}
Ok ( Self {
Ok ( Self {
ptr : ptr as usize ,
ptr : ptr as usize ,
@ -90,6 +84,7 @@ impl Mmap {
#[ cfg(windows) ]
#[ cfg(windows) ]
{
{
use std ::fs ::OpenOptions ;
use std ::fs ::OpenOptions ;
use std ::io ;
use std ::os ::windows ::prelude ::* ;
use std ::os ::windows ::prelude ::* ;
use winapi ::um ::handleapi ::* ;
use winapi ::um ::handleapi ::* ;
use winapi ::um ::memoryapi ::* ;
use winapi ::um ::memoryapi ::* ;
@ -175,22 +170,14 @@ impl Mmap {
Ok ( if accessible_size = = mapping_size {
Ok ( if accessible_size = = mapping_size {
// Allocate a single read-write region at once.
// Allocate a single read-write region at once.
let ptr = unsafe {
let ptr = unsafe {
libc ::mmap (
rsix ::io ::mmap_anonymous (
ptr ::null_mut ( ) ,
ptr ::null_mut ( ) ,
mapping_size ,
mapping_size ,
libc ::PROT_READ | libc ::PROT_WRITE ,
rsix ::io ::ProtFlags ::READ | rsix ::io ::ProtFlags ::WRITE ,
libc ::MAP_PRIVATE | libc ::MAP_ANON ,
rsix ::io ::MapFlags ::PRIVATE ,
- 1 ,
0 ,
)
)
. context ( format ! ( "mmap failed to allocate {:#x} bytes" , mapping_size ) ) ?
} ;
} ;
if ptr as isize = = - 1_ isize {
bail ! (
"mmap failed to allocate {:#x} bytes: {}" ,
mapping_size ,
io ::Error ::last_os_error ( )
) ;
}
Self {
Self {
ptr : ptr as usize ,
ptr : ptr as usize ,
@ -200,22 +187,14 @@ impl Mmap {
} else {
} else {
// Reserve the mapping size.
// Reserve the mapping size.
let ptr = unsafe {
let ptr = unsafe {
libc ::mmap (
rsix ::io ::mmap_anonymous (
ptr ::null_mut ( ) ,
ptr ::null_mut ( ) ,
mapping_size ,
mapping_size ,
libc ::PROT_NONE ,
rsix ::io ::ProtFlags ::NONE ,
libc ::MAP_PRIVATE | libc ::MAP_ANON ,
rsix ::io ::MapFlags ::PRIVATE ,
- 1 ,
0 ,
)
)
. context ( format ! ( "mmap failed to allocate {:#x} bytes" , mapping_size ) ) ?
} ;
} ;
if ptr as isize = = - 1_ isize {
bail ! (
"mmap failed to allocate {:#x} bytes: {}" ,
mapping_size ,
io ::Error ::last_os_error ( )
) ;
}
let mut result = Self {
let mut result = Self {
ptr : ptr as usize ,
ptr : ptr as usize ,
@ -237,6 +216,8 @@ impl Mmap {
/// must be native page-size multiples.
/// must be native page-size multiples.
#[ cfg(target_os = " windows " ) ]
#[ cfg(target_os = " windows " ) ]
pub fn accessible_reserved ( accessible_size : usize , mapping_size : usize ) -> Result < Self > {
pub fn accessible_reserved ( accessible_size : usize , mapping_size : usize ) -> Result < Self > {
use anyhow ::bail ;
use std ::io ;
use winapi ::um ::memoryapi ::VirtualAlloc ;
use winapi ::um ::memoryapi ::VirtualAlloc ;
use winapi ::um ::winnt ::{ MEM_COMMIT , MEM_RESERVE , PAGE_NOACCESS , PAGE_READWRITE } ;
use winapi ::um ::winnt ::{ MEM_COMMIT , MEM_RESERVE , PAGE_NOACCESS , PAGE_READWRITE } ;
@ -316,6 +297,8 @@ impl Mmap {
/// `self`'s reserved memory.
/// `self`'s reserved memory.
#[ cfg(target_os = " windows " ) ]
#[ cfg(target_os = " windows " ) ]
pub fn make_accessible ( & mut self , start : usize , len : usize ) -> Result < ( ) > {
pub fn make_accessible ( & mut self , start : usize , len : usize ) -> Result < ( ) > {
use anyhow ::bail ;
use std ::io ;
use winapi ::ctypes ::c_void ;
use winapi ::ctypes ::c_void ;
use winapi ::um ::memoryapi ::VirtualAlloc ;
use winapi ::um ::memoryapi ::VirtualAlloc ;
use winapi ::um ::winnt ::{ MEM_COMMIT , PAGE_READWRITE } ;
use winapi ::um ::winnt ::{ MEM_COMMIT , PAGE_READWRITE } ;
@ -398,6 +381,7 @@ impl Mmap {
// we don't want our modifications to go back to the original file.
// we don't want our modifications to go back to the original file.
#[ cfg(windows) ]
#[ cfg(windows) ]
{
{
use std ::io ;
use winapi ::um ::memoryapi ::* ;
use winapi ::um ::memoryapi ::* ;
use winapi ::um ::winnt ::* ;
use winapi ::um ::winnt ::* ;
@ -440,8 +424,8 @@ impl Drop for Mmap {
#[ cfg(not(target_os = " windows " )) ]
#[ cfg(not(target_os = " windows " )) ]
fn drop ( & mut self ) {
fn drop ( & mut self ) {
if self . len ! = 0 {
if self . len ! = 0 {
let r = unsafe { libc ::munmap ( self . ptr as * mut l ibc ::c_void , self . len ) } ;
unsafe { rsix ::io ::munmap ( self . ptr as * mut std ::ff i ::c_void , self . len ) }
assert_eq ! ( r , 0 , "munmap failed: {}" , io ::Error ::last_os_error ( ) ) ;
. expect ( "munmap failed" ) ;
}
}
}
}