]> git.lizzy.rs Git - rust.git/commitdiff
rollup merge of #19620: retep998/memorymap
authorAlex Crichton <alex@alexcrichton.com>
Tue, 9 Dec 2014 17:25:07 +0000 (09:25 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Tue, 9 Dec 2014 17:25:07 +0000 (09:25 -0800)
1  2 
src/libstd/os.rs
src/libstd/sys/windows/fs.rs

diff --combined src/libstd/os.rs
index f298ec74f6a2b846df02534297e55f4f44d914e6,25842450068b27bbb62246782ba58a56fe64f684..689ee9349e8750fe043a00e7b79c1706a0538b56
@@@ -36,7 -36,6 +36,7 @@@ use error::{FromError, Error}
  use fmt;
  use io::{IoResult, IoError};
  use iter::{Iterator, IteratorExt};
 +use kinds::Copy;
  use libc::{c_void, c_int};
  use libc;
  use boxed::Box;
@@@ -160,7 -159,7 +160,7 @@@ pub fn getcwd() -> IoResult<Path> 
  }
  
  #[cfg(windows)]
- pub mod windows {
+ pub mod windoze {
      use libc::types::os::arch::extra::DWORD;
      use libc;
      use option::Option;
@@@ -317,7 -316,7 +317,7 @@@ pub fn env_as_bytes() -> Vec<(Vec<u8>,V
          fn env_convert(input: Vec<Vec<u8>>) -> Vec<(Vec<u8>, Vec<u8>)> {
              let mut pairs = Vec::new();
              for p in input.iter() {
 -                let mut it = p.as_slice().splitn(1, |b| *b == b'=');
 +                let mut it = p.splitn(1, |b| *b == b'=');
                  let key = it.next().unwrap().to_vec();
                  let default: &[u8] = &[];
                  let val = it.next().unwrap_or(default).to_vec();
@@@ -386,7 -385,7 +386,7 @@@ pub fn getenv_as_bytes(n: &str) -> Opti
  pub fn getenv(n: &str) -> Option<String> {
      unsafe {
          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();
              n.push(0);
              fill_utf16_buf_and_decode(|buf, sz| {
@@@ -620,8 -619,6 +620,8 @@@ pub struct Pipe 
      pub writer: c_int,
  }
  
 +impl Copy for Pipe {}
 +
  /// Creates a new low-level OS in-memory pipe.
  ///
  /// This function can fail to succeed if there are no more resources available
@@@ -715,7 -712,7 +715,7 @@@ pub fn self_exe_name() -> Option<Path> 
      #[cfg(windows)]
      fn load_self() -> Option<Vec<u8>> {
          unsafe {
-             use os::windows::fill_utf16_buf_and_decode;
+             use os::windoze::fill_utf16_buf_and_decode;
              fill_utf16_buf_and_decode(|buf, sz| {
                  libc::GetModuleFileNameW(0u as libc::DWORD, buf, sz)
              }).map(|s| s.into_string().into_bytes())
@@@ -1188,9 -1185,6 +1188,9 @@@ pub struct MemoryMap 
      kind: MemoryMapKind,
  }
  
 +#[cfg(not(stage0))]
 +impl Copy for MemoryMap {}
 +
  /// Type of memory map
  pub enum MemoryMapKind {
      /// Virtual memory map. Usually used to change the permissions of a given
      MapVirtual
  }
  
 +impl Copy for MemoryMapKind {}
 +
  /// Options the memory map is created with
  pub enum MapOption {
      /// The memory should be readable
      /// Create a map for a specific address range. Corresponds to `MAP_FIXED` on
      /// POSIX.
      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.
+     #[cfg(not(windows))]
      MapFd(c_int),
      /// When using `MapFd`, the start of the map is `uint` bytes from the start
      /// of the file.
      MapNonStandardFlags(c_int),
  }
  
 +impl Copy for MapOption {}
 +
  /// Possible errors when creating a map.
  pub enum MapError {
      /// ## The following are POSIX-specific
      ErrMapViewOfFile(uint)
  }
  
 +impl Copy for MapError {}
 +
  impl fmt::Show for MapError {
      fn fmt(&self, out: &mut fmt::Formatter) -> fmt::Result {
          let str = match *self {
@@@ -1413,7 -1405,7 +1417,7 @@@ impl MemoryMap 
          let mut readable = false;
          let mut writable = 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 len = round_up(min_len, page_size());
  
                  MapWritable => { writable = true; },
                  MapExecutable => { executable = true; }
                  MapAddr(addr_) => { lpAddress = addr_ as LPVOID; },
-                 MapFd(fd_) => { fd = fd_; },
+                 MapFd(handle_) => { handle = handle_; },
                  MapOffset(offset_) => { offset = offset_; },
                  MapNonStandardFlags(..) => {}
              }
          }
  
          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, 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, true) => libc::PAGE_EXECUTE_READWRITE,
              _ => return Err(ErrUnsupProt)
          };
  
-         if fd == -1 {
+         if handle == libc::INVALID_HANDLE_VALUE {
              if offset != 0 {
                  return Err(ErrUnsupOffset);
              }
                                                // we should never get here.
              };
              unsafe {
-                 let hFile = libc::get_osfhandle(fd) as HANDLE;
+                 let hFile = handle;
                  let mapping = libc::CreateFileMappingW(hFile,
                                                         ptr::null_mut(),
                                                         flProtect,
@@@ -1991,55 -1983,47 +1995,47 @@@ mod tests 
  
      #[test]
      fn memory_map_file() {
-         use result::Result::{Ok, Err};
          use os::*;
-         use libc::*;
-         use io::fs;
-         #[cfg(unix)]
-         fn lseek_(fd: c_int, size: uint) {
-             unsafe {
-                 assert!(lseek(fd, size as off_t, SEEK_SET) == size as off_t);
-             }
+         use io::fs::{File, unlink};
+         use io::SeekStyle::SeekSet;
+         use io::FileMode::Open;
+         use io::FileAccess::ReadWrite;
+         use libc::HANDLE;
+         #[cfg(not(windows))]
+         fn get_fd(file: &File) -> c_int {
+             use os::unix::AsRawFd;
+             file.as_raw_fd()
          }
          #[cfg(windows)]
-         fn lseek_(fd: c_int, size: uint) {
-            unsafe {
-                assert!(lseek(fd, size as c_long, SEEK_SET) == size as c_long);
-            }
+         fn get_fd(file: &File) -> HANDLE {
+             use os::windows::AsRawHandle;
+             file.as_raw_handle()
          }
  
          let mut path = tmpdir();
          path.push("mmap_file.tmp");
          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 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, &[
+         let chunk = MemoryMap::new(size / 2, &[
              MapReadable,
              MapWritable,
-             MapFd(fd),
+             MapFd(get_fd(&file)),
              MapOffset(size / 2)
-         ]) {
-             Ok(chunk) => chunk,
-             Err(msg) => panic!("{}", msg)
-         };
+         ]).unwrap();
          assert!(chunk.len > 0);
  
          unsafe {
              *chunk.data = 0xbe;
              assert!(*chunk.data == 0xbe);
-             close(fd);
          }
          drop(chunk);
  
-         fs::unlink(&path).unwrap();
+         unlink(&path).unwrap();
      }
  
      #[test]
      #[cfg(unix)]
      fn join_paths_unix() {
          fn test_eq(input: &[&str], output: &str) -> bool {
 -            join_paths(input).unwrap().as_slice() == output.as_bytes()
 +            join_paths(input).unwrap() == output.as_bytes()
          }
  
          assert!(test_eq(&[], ""));
      #[cfg(windows)]
      fn join_paths_windows() {
          fn test_eq(input: &[&str], output: &str) -> bool {
 -            join_paths(input).unwrap().as_slice() == output.as_bytes()
 +            join_paths(input).unwrap() == output.as_bytes()
          }
  
          assert!(test_eq(&[], ""));
index 16779a80185bc8c8aababbfd1ae82368c69ed225,731fdc0871f6d5c390ad1e111d3499b3206ca9df..05be8de0b56e2e81db34f2c2274f1c4eb99b9921
@@@ -15,7 -15,7 +15,7 @@@ use libc::{mod, c_int}
  
  use c_str::CString;
  use mem;
- use os::windows::fill_utf16_buf_and_decode;
+ use os::windoze::fill_utf16_buf_and_decode;
  use path;
  use ptr;
  use str;
@@@ -376,8 -376,8 +376,8 @@@ pub fn readlink(p: &Path) -> IoResult<P
                                    libc::VOLUME_NAME_DOS)
      });
      let ret = match ret {
 -        Some(ref s) if s.as_slice().starts_with(r"\\?\") => { // "
 -            Ok(Path::new(s.as_slice().slice_from(4)))
 +        Some(ref s) if s.starts_with(r"\\?\") => { // "
 +            Ok(Path::new(s.slice_from(4)))
          }
          Some(s) => Ok(Path::new(s)),
          None => Err(super::last_error()),