Make MemoryMap use HANDLE on Windows.

Also fixes some conflicting module names.

Signed-off-by: Peter Atashian <retep998@gmail.com>
This commit is contained in:
Peter Atashian 2014-12-07 13:25:51 -05:00
parent a243e8820a
commit 58f12743c2
2 changed files with 34 additions and 38 deletions

View File

@ -159,7 +159,7 @@ pub fn getcwd() -> IoResult<Path> {
} }
#[cfg(windows)] #[cfg(windows)]
pub mod windows { pub mod windoze {
use libc::types::os::arch::extra::DWORD; use libc::types::os::arch::extra::DWORD;
use libc; use libc;
use option::Option; use option::Option;
@ -385,7 +385,7 @@ pub fn getenv_as_bytes(n: &str) -> Option<Vec<u8>> {
pub fn getenv(n: &str) -> Option<String> { pub fn getenv(n: &str) -> Option<String> {
unsafe { unsafe {
with_env_lock(|| { with_env_lock(|| {
use os::windows::{fill_utf16_buf_and_decode}; use os::windoze::{fill_utf16_buf_and_decode};
let mut n: Vec<u16> = n.utf16_units().collect(); let mut n: Vec<u16> = n.utf16_units().collect();
n.push(0); n.push(0);
fill_utf16_buf_and_decode(|buf, sz| { fill_utf16_buf_and_decode(|buf, sz| {
@ -712,7 +712,7 @@ pub fn self_exe_name() -> Option<Path> {
#[cfg(windows)] #[cfg(windows)]
fn load_self() -> Option<Vec<u8>> { fn load_self() -> Option<Vec<u8>> {
unsafe { unsafe {
use os::windows::fill_utf16_buf_and_decode; use os::windoze::fill_utf16_buf_and_decode;
fill_utf16_buf_and_decode(|buf, sz| { fill_utf16_buf_and_decode(|buf, sz| {
libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz) libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
}).map(|s| s.into_string().into_bytes()) }).map(|s| s.into_string().into_bytes())
@ -1207,7 +1207,11 @@ pub enum MapOption {
/// Create a map for a specific address range. Corresponds to `MAP_FIXED` on /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
/// POSIX. /// POSIX.
MapAddr(*const u8), MapAddr(*const u8),
/// Create a memory mapping for a file with a given HANDLE.
#[cfg(windows)]
MapFd(libc::HANDLE),
/// Create a memory mapping for a file with a given fd. /// Create a memory mapping for a file with a given fd.
#[cfg(not(windows))]
MapFd(c_int), MapFd(c_int),
/// When using `MapFd`, the start of the map is `uint` bytes from the start /// When using `MapFd`, the start of the map is `uint` bytes from the start
/// of the file. /// of the file.
@ -1401,7 +1405,7 @@ impl MemoryMap {
let mut readable = false; let mut readable = false;
let mut writable = false; let mut writable = false;
let mut executable = false; let mut executable = false;
let mut fd: c_int = -1; let mut handle: HANDLE = libc::INVALID_HANDLE_VALUE;
let mut offset: uint = 0; let mut offset: uint = 0;
let len = round_up(min_len, page_size()); let len = round_up(min_len, page_size());
@ -1411,23 +1415,23 @@ impl MemoryMap {
MapWritable => { writable = true; }, MapWritable => { writable = true; },
MapExecutable => { executable = true; } MapExecutable => { executable = true; }
MapAddr(addr_) => { lpAddress = addr_ as LPVOID; }, MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
MapFd(fd_) => { fd = fd_; }, MapFd(handle_) => { handle = handle_; },
MapOffset(offset_) => { offset = offset_; }, MapOffset(offset_) => { offset = offset_; },
MapNonStandardFlags(..) => {} MapNonStandardFlags(..) => {}
} }
} }
let flProtect = match (executable, readable, writable) { let flProtect = match (executable, readable, writable) {
(false, false, false) if fd == -1 => libc::PAGE_NOACCESS, (false, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_NOACCESS,
(false, true, false) => libc::PAGE_READONLY, (false, true, false) => libc::PAGE_READONLY,
(false, true, true) => libc::PAGE_READWRITE, (false, true, true) => libc::PAGE_READWRITE,
(true, false, false) if fd == -1 => libc::PAGE_EXECUTE, (true, false, false) if handle == libc::INVALID_HANDLE_VALUE => libc::PAGE_EXECUTE,
(true, true, false) => libc::PAGE_EXECUTE_READ, (true, true, false) => libc::PAGE_EXECUTE_READ,
(true, true, true) => libc::PAGE_EXECUTE_READWRITE, (true, true, true) => libc::PAGE_EXECUTE_READWRITE,
_ => return Err(ErrUnsupProt) _ => return Err(ErrUnsupProt)
}; };
if fd == -1 { if handle == libc::INVALID_HANDLE_VALUE {
if offset != 0 { if offset != 0 {
return Err(ErrUnsupOffset); return Err(ErrUnsupOffset);
} }
@ -1455,7 +1459,7 @@ impl MemoryMap {
// we should never get here. // we should never get here.
}; };
unsafe { unsafe {
let hFile = libc::get_osfhandle(fd) as HANDLE; let hFile = handle;
let mapping = libc::CreateFileMappingW(hFile, let mapping = libc::CreateFileMappingW(hFile,
ptr::null_mut(), ptr::null_mut(),
flProtect, flProtect,
@ -1979,55 +1983,47 @@ mod tests {
#[test] #[test]
fn memory_map_file() { fn memory_map_file() {
use result::Result::{Ok, Err};
use os::*; use os::*;
use libc::*; use io::fs::{File, unlink};
use io::fs; use io::SeekStyle::SeekSet;
use io::FileMode::Open;
use io::FileAccess::ReadWrite;
use libc::HANDLE;
#[cfg(unix)] #[cfg(not(windows))]
fn lseek_(fd: c_int, size: uint) { fn get_fd(file: &File) -> c_int {
unsafe { use os::unix::AsRawFd;
assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t); file.as_raw_fd()
}
} }
#[cfg(windows)] #[cfg(windows)]
fn lseek_(fd: c_int, size: uint) { fn get_fd(file: &File) -> HANDLE {
unsafe { use os::windows::AsRawHandle;
assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long); file.as_raw_handle()
}
} }
let mut path = tmpdir(); let mut path = tmpdir();
path.push("mmap_file.tmp"); path.push("mmap_file.tmp");
let size = MemoryMap::granularity() * 2; let size = MemoryMap::granularity() * 2;
let mut file = File::open_mode(&path, Open, ReadWrite).unwrap();
file.seek(size as i64, SeekSet);
file.write_u8(0);
let fd = unsafe { let chunk = MemoryMap::new(size / 2, &[
let fd = path.with_c_str(|path| {
open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)
});
lseek_(fd, size);
"x".with_c_str(|x| assert!(write(fd, x as *const c_void, 1) == 1));
fd
};
let chunk = match MemoryMap::new(size / 2, &[
MapReadable, MapReadable,
MapWritable, MapWritable,
MapFd(fd), MapFd(get_fd(&file)),
MapOffset(size / 2) MapOffset(size / 2)
]) { ]).unwrap();
Ok(chunk) => chunk,
Err(msg) => panic!("{}", msg)
};
assert!(chunk.len > 0); assert!(chunk.len > 0);
unsafe { unsafe {
*chunk.data = 0xbe; *chunk.data = 0xbe;
assert!(*chunk.data == 0xbe); assert!(*chunk.data == 0xbe);
close(fd);
} }
drop(chunk); drop(chunk);
fs::unlink(&path).unwrap(); unlink(&path).unwrap();
} }
#[test] #[test]

View File

@ -15,7 +15,7 @@ use libc::{mod, c_int};
use c_str::CString; use c_str::CString;
use mem; use mem;
use os::windows::fill_utf16_buf_and_decode; use os::windoze::fill_utf16_buf_and_decode;
use path; use path;
use ptr; use ptr;
use str; use str;