aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys/windows
diff options
context:
space:
mode:
authorVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
committerVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
commit64423f0e34cc4a7d78c15b345b3b8f58243d8286 (patch)
treecc20e2e7f0fc35abf470e20e61d3d48f0d954f3b /ctr-std/src/sys/windows
parentSupport libctru 2.0 (diff)
downloadarchived-ctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.tar.xz
archived-ctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.zip
Delete ctr-std to use my fork of the rust repo instead
Diffstat (limited to 'ctr-std/src/sys/windows')
-rw-r--r--ctr-std/src/sys/windows/args.rs107
-rw-r--r--ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs62
-rw-r--r--ctr-std/src/sys/windows/backtrace/mod.rs326
-rw-r--r--ctr-std/src/sys/windows/backtrace/printing/mod.rs34
-rw-r--r--ctr-std/src/sys/windows/backtrace/printing/msvc.rs217
-rw-r--r--ctr-std/src/sys/windows/c.rs1334
-rw-r--r--ctr-std/src/sys/windows/cmath.rs103
-rw-r--r--ctr-std/src/sys/windows/compat.rs81
-rw-r--r--ctr-std/src/sys/windows/condvar.rs65
-rw-r--r--ctr-std/src/sys/windows/dynamic_lib.rs54
-rw-r--r--ctr-std/src/sys/windows/env.rs19
-rw-r--r--ctr-std/src/sys/windows/ext/ffi.rs152
-rw-r--r--ctr-std/src/sys/windows/ext/fs.rs508
-rw-r--r--ctr-std/src/sys/windows/ext/io.rs209
-rw-r--r--ctr-std/src/sys/windows/ext/mod.rs45
-rw-r--r--ctr-std/src/sys/windows/ext/process.rs123
-rw-r--r--ctr-std/src/sys/windows/ext/raw.rs21
-rw-r--r--ctr-std/src/sys/windows/ext/thread.rs31
-rw-r--r--ctr-std/src/sys/windows/fast_thread_local.rs18
-rw-r--r--ctr-std/src/sys/windows/fs.rs804
-rw-r--r--ctr-std/src/sys/windows/handle.rs218
-rw-r--r--ctr-std/src/sys/windows/memchr.rs15
-rw-r--r--ctr-std/src/sys/windows/mod.rs277
-rw-r--r--ctr-std/src/sys/windows/mutex.rs188
-rw-r--r--ctr-std/src/sys/windows/net.rs356
-rw-r--r--ctr-std/src/sys/windows/os.rs337
-rw-r--r--ctr-std/src/sys/windows/os_str.rs182
-rw-r--r--ctr-std/src/sys/windows/path.rs106
-rw-r--r--ctr-std/src/sys/windows/pipe.rs364
-rw-r--r--ctr-std/src/sys/windows/process.rs581
-rw-r--r--ctr-std/src/sys/windows/rand.rs26
-rw-r--r--ctr-std/src/sys/windows/rwlock.rs52
-rw-r--r--ctr-std/src/sys/windows/stack_overflow.rs52
-rw-r--r--ctr-std/src/sys/windows/stdio.rs233
-rw-r--r--ctr-std/src/sys/windows/thread.rs101
-rw-r--r--ctr-std/src/sys/windows/thread_local.rs251
-rw-r--r--ctr-std/src/sys/windows/time.rs206
37 files changed, 0 insertions, 7858 deletions
diff --git a/ctr-std/src/sys/windows/args.rs b/ctr-std/src/sys/windows/args.rs
deleted file mode 100644
index 4784633..0000000
--- a/ctr-std/src/sys/windows/args.rs
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(dead_code)] // runtime init functions not used during testing
-
-use os::windows::prelude::*;
-use sys::c;
-use slice;
-use ops::Range;
-use ffi::OsString;
-use libc::{c_int, c_void};
-use fmt;
-
-pub unsafe fn init(_argc: isize, _argv: *const *const u8) { }
-
-pub unsafe fn cleanup() { }
-
-pub fn args() -> Args {
- unsafe {
- let mut nArgs: c_int = 0;
- let lpCmdLine = c::GetCommandLineW();
- let szArgList = c::CommandLineToArgvW(lpCmdLine, &mut nArgs);
-
- // szArcList can be NULL if CommandLinToArgvW failed,
- // but in that case nArgs is 0 so we won't actually
- // try to read a null pointer
- Args { cur: szArgList, range: 0..(nArgs as isize) }
- }
-}
-
-pub struct Args {
- range: Range<isize>,
- cur: *mut *mut u16,
-}
-
-pub struct ArgsInnerDebug<'a> {
- args: &'a Args,
-}
-
-impl<'a> fmt::Debug for ArgsInnerDebug<'a> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.write_str("[")?;
- let mut first = true;
- for i in self.args.range.clone() {
- if !first {
- f.write_str(", ")?;
- }
- first = false;
-
- // Here we do allocation which could be avoided.
- fmt::Debug::fmt(&unsafe { os_string_from_ptr(*self.args.cur.offset(i)) }, f)?;
- }
- f.write_str("]")?;
- Ok(())
- }
-}
-
-impl Args {
- pub fn inner_debug(&self) -> ArgsInnerDebug {
- ArgsInnerDebug {
- args: self
- }
- }
-}
-
-unsafe fn os_string_from_ptr(ptr: *mut u16) -> OsString {
- let mut len = 0;
- while *ptr.offset(len) != 0 { len += 1; }
-
- // Push it onto the list.
- let ptr = ptr as *const u16;
- let buf = slice::from_raw_parts(ptr, len as usize);
- OsStringExt::from_wide(buf)
-}
-
-impl Iterator for Args {
- type Item = OsString;
- fn next(&mut self) -> Option<OsString> {
- self.range.next().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
- }
- fn size_hint(&self) -> (usize, Option<usize>) { self.range.size_hint() }
-}
-
-impl DoubleEndedIterator for Args {
- fn next_back(&mut self) -> Option<OsString> {
- self.range.next_back().map(|i| unsafe { os_string_from_ptr(*self.cur.offset(i)) } )
- }
-}
-
-impl ExactSizeIterator for Args {
- fn len(&self) -> usize { self.range.len() }
-}
-
-impl Drop for Args {
- fn drop(&mut self) {
- // self.cur can be null if CommandLineToArgvW previously failed,
- // but LocalFree ignores NULL pointers
- unsafe { c::LocalFree(self.cur as *mut c_void); }
- }
-}
diff --git a/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs b/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs
deleted file mode 100644
index f0d29dd..0000000
--- a/ctr-std/src/sys/windows/backtrace/backtrace_gnu.rs
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use sys::c;
-use libc::c_char;
-use path::PathBuf;
-use fs::{OpenOptions, File};
-use sys::ext::fs::OpenOptionsExt;
-use sys::handle::Handle;
-use super::super::{fill_utf16_buf, os2path, to_u16s, wide_char_to_multi_byte};
-
-fn query_full_process_image_name() -> io::Result<PathBuf> {
- unsafe {
- let process_handle = Handle::new(c::OpenProcess(c::PROCESS_QUERY_INFORMATION,
- c::FALSE,
- c::GetCurrentProcessId()));
- fill_utf16_buf(|buf, mut sz| {
- if c::QueryFullProcessImageNameW(process_handle.raw(), 0, buf, &mut sz) == 0 {
- 0
- } else {
- sz
- }
- }, os2path)
- }
-}
-
-fn lock_and_get_executable_filename() -> io::Result<(PathBuf, File)> {
- // We query the current image name, open the file without FILE_SHARE_DELETE so it
- // can't be moved and then get the current image name again. If the names are the
- // same than we have successfully locked the file
- let image_name1 = query_full_process_image_name()?;
- let file = OpenOptions::new()
- .read(true)
- .share_mode(c::FILE_SHARE_READ | c::FILE_SHARE_WRITE)
- .open(&image_name1)?;
- let image_name2 = query_full_process_image_name()?;
-
- if image_name1 != image_name2 {
- return Err(io::Error::new(io::ErrorKind::Other,
- "executable moved while trying to lock it"));
- }
-
- Ok((image_name1, file))
-}
-
-// Get the executable filename for libbacktrace
-// This returns the path in the ANSI code page and a File which should remain open
-// for as long as the path should remain valid
-pub fn get_executable_filename() -> io::Result<(Vec<c_char>, File)> {
- let (executable, file) = lock_and_get_executable_filename()?;
- let u16_executable = to_u16s(executable.into_os_string())?;
- Ok((wide_char_to_multi_byte(c::CP_ACP, c::WC_NO_BEST_FIT_CHARS,
- &u16_executable, true)?, file))
-}
diff --git a/ctr-std/src/sys/windows/backtrace/mod.rs b/ctr-std/src/sys/windows/backtrace/mod.rs
deleted file mode 100644
index f64cae8..0000000
--- a/ctr-std/src/sys/windows/backtrace/mod.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! As always, windows has something very different than unix, we mainly want
-//! to avoid having to depend too much on libunwind for windows.
-//!
-//! If you google around, you'll find a fair bit of references to built-in
-//! functions to get backtraces on windows. It turns out that most of these are
-//! in an external library called dbghelp. I was unable to find this library
-//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-//! of it.
-//!
-//! You'll also find that there's a function called CaptureStackBackTrace
-//! mentioned frequently (which is also easy to use), but sadly I didn't have a
-//! copy of that function in my mingw install (maybe it was broken?). Instead,
-//! this takes the route of using StackWalk64 in order to walk the stack.
-
-#![allow(deprecated)] // dynamic_lib
-
-use io;
-use libc::c_void;
-use mem;
-use ptr;
-use sys::c;
-use sys::dynamic_lib::DynamicLibrary;
-use sys_common::backtrace::Frame;
-
-macro_rules! sym {
- ($lib:expr, $e:expr, $t:ident) => (
- $lib.symbol($e).map(|f| unsafe {
- $crate::mem::transmute::<usize, $t>(f)
- })
- )
-}
-
-mod printing;
-
-#[cfg(target_env = "gnu")]
-#[path = "backtrace_gnu.rs"]
-pub mod gnu;
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-use self::printing::{load_printing_fns_64, load_printing_fns_ex};
-
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
- let dbghelp = DynamicLibrary::open("dbghelp.dll")?;
-
- // Fetch the symbols necessary from dbghelp.dll
- let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
- let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-
- // StackWalkEx might not be present and we'll fall back to StackWalk64
- let sw_var = match sym!(dbghelp, "StackWalkEx", StackWalkExFn) {
- Ok(StackWalkEx) => {
- StackWalkVariant::StackWalkEx(StackWalkEx, load_printing_fns_ex(&dbghelp)?)
- }
- Err(e) => match sym!(dbghelp, "StackWalk64", StackWalk64Fn) {
- Ok(StackWalk64) => {
- StackWalkVariant::StackWalk64(StackWalk64, load_printing_fns_64(&dbghelp)?)
- }
- Err(..) => return Err(e),
- },
- };
-
- // Allocate necessary structures for doing the stack walk
- let process = unsafe { c::GetCurrentProcess() };
-
- let backtrace_context = BacktraceContext {
- handle: process,
- SymCleanup,
- StackWalkVariant: sw_var,
- dbghelp,
- };
-
- // Initialize this process's symbols
- let ret = unsafe { SymInitialize(process, ptr::null_mut(), c::TRUE) };
- if ret != c::TRUE {
- return Ok((0, backtrace_context));
- }
-
- // And now that we're done with all the setup, do the stack walking!
- match backtrace_context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(StackWalkEx, _) => {
- set_frames(StackWalkEx, frames).map(|i| (i, backtrace_context))
- }
-
- StackWalkVariant::StackWalk64(StackWalk64, _) => {
- set_frames(StackWalk64, frames).map(|i| (i, backtrace_context))
- }
- }
-}
-
-fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> {
- let process = unsafe { c::GetCurrentProcess() };
- let thread = unsafe { c::GetCurrentProcess() };
- let mut context: c::CONTEXT = unsafe { mem::zeroed() };
- unsafe { c::RtlCaptureContext(&mut context) };
- let mut frame = W::Item::new();
- let image = frame.init(&context);
-
- let mut i = 0;
- while i < frames.len()
- && StackWalk.walk(image, process, thread, &mut frame, &mut context) == c::TRUE
- {
- let addr = frame.get_addr();
- frames[i] = Frame {
- symbol_addr: addr,
- exact_position: addr,
- inline_context: 0,
- };
-
- i += 1
- }
- Ok(i)
-}
-
-type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL;
-type SymCleanupFn = unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
-
-type StackWalkExFn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME_EX,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- c::DWORD,
-) -> c::BOOL;
-
-type StackWalk64Fn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME64,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
-) -> c::BOOL;
-
-trait StackWalker {
- type Item: StackFrame;
-
- fn walk(&self, c::DWORD, c::HANDLE, c::HANDLE, &mut Self::Item, &mut c::CONTEXT) -> c::BOOL;
-}
-
-impl StackWalker for StackWalkExFn {
- type Item = c::STACKFRAME_EX;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- 0,
- )
- }
- }
-}
-
-impl StackWalker for StackWalk64Fn {
- type Item = c::STACKFRAME64;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- )
- }
- }
-}
-
-trait StackFrame {
- fn new() -> Self;
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD;
- fn get_addr(&self) -> *const u8;
-}
-
-impl StackFrame for c::STACKFRAME_EX {
- fn new() -> c::STACKFRAME_EX {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-impl StackFrame for c::STACKFRAME64 {
- fn new() -> c::STACKFRAME64 {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-enum StackWalkVariant {
- StackWalkEx(StackWalkExFn, printing::PrintingFnsEx),
- StackWalk64(StackWalk64Fn, printing::PrintingFns64),
-}
-
-pub struct BacktraceContext {
- handle: c::HANDLE,
- SymCleanup: SymCleanupFn,
- // Only used in printing for msvc and not gnu
- // The gnu version is effectively a ZST dummy.
- #[allow(dead_code)]
- StackWalkVariant: StackWalkVariant,
- // keeping DynamycLibrary loaded until its functions no longer needed
- #[allow(dead_code)]
- dbghelp: DynamicLibrary,
-}
-
-impl Drop for BacktraceContext {
- fn drop(&mut self) {
- unsafe {
- (self.SymCleanup)(self.handle);
- }
- }
-}
diff --git a/ctr-std/src/sys/windows/backtrace/printing/mod.rs b/ctr-std/src/sys/windows/backtrace/printing/mod.rs
deleted file mode 100644
index 251d502..0000000
--- a/ctr-std/src/sys/windows/backtrace/printing/mod.rs
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#[cfg(target_env = "msvc")]
-#[path = "msvc.rs"]
-mod printing;
-
-#[cfg(target_env = "gnu")]
-mod printing {
- pub use sys_common::gnu::libbacktrace::{foreach_symbol_fileline, resolve_symname};
-
- // dummy functions to mirror those present in msvc version.
- use sys::dynamic_lib::DynamicLibrary;
- use io;
- pub struct PrintingFnsEx {}
- pub struct PrintingFns64 {}
- pub fn load_printing_fns_ex(_: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
- Ok(PrintingFnsEx{})
- }
- pub fn load_printing_fns_64(_: &DynamicLibrary) -> io::Result<PrintingFns64> {
- Ok(PrintingFns64{})
- }
-}
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-pub use self::printing::{load_printing_fns_ex, load_printing_fns_64,
- PrintingFnsEx, PrintingFns64};
diff --git a/ctr-std/src/sys/windows/backtrace/printing/msvc.rs b/ctr-std/src/sys/windows/backtrace/printing/msvc.rs
deleted file mode 100644
index c8b946b..0000000
--- a/ctr-std/src/sys/windows/backtrace/printing/msvc.rs
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ffi::CStr;
-use io;
-use libc::{c_char, c_ulong};
-use mem;
-use sys::backtrace::BacktraceContext;
-use sys::backtrace::StackWalkVariant;
-use sys::c;
-use sys::dynamic_lib::DynamicLibrary;
-use sys_common::backtrace::Frame;
-
-// Structs holding printing functions and loaders for them
-// Two versions depending on whether dbghelp.dll has StackWalkEx or not
-// (the former being in newer Windows versions, the older being in Win7 and before)
-pub struct PrintingFnsEx {
- resolve_symname: SymFromInlineContextFn,
- sym_get_line: SymGetLineFromInlineContextFn,
-}
-pub struct PrintingFns64 {
- resolve_symname: SymFromAddrFn,
- sym_get_line: SymGetLineFromAddr64Fn,
-}
-
-pub fn load_printing_fns_ex(dbghelp: &DynamicLibrary) -> io::Result<PrintingFnsEx> {
- Ok(PrintingFnsEx {
- resolve_symname: sym!(dbghelp, "SymFromInlineContext", SymFromInlineContextFn)?,
- sym_get_line: sym!(
- dbghelp,
- "SymGetLineFromInlineContext",
- SymGetLineFromInlineContextFn
- )?,
- })
-}
-pub fn load_printing_fns_64(dbghelp: &DynamicLibrary) -> io::Result<PrintingFns64> {
- Ok(PrintingFns64 {
- resolve_symname: sym!(dbghelp, "SymFromAddr", SymFromAddrFn)?,
- sym_get_line: sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn)?,
- })
-}
-
-type SymFromAddrFn =
- unsafe extern "system" fn(c::HANDLE, u64, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-type SymFromInlineContextFn =
- unsafe extern "system" fn(c::HANDLE, u64, c::ULONG, *mut u64, *mut c::SYMBOL_INFO) -> c::BOOL;
-
-type SymGetLineFromAddr64Fn =
- unsafe extern "system" fn(c::HANDLE, u64, *mut u32, *mut c::IMAGEHLP_LINE64) -> c::BOOL;
-type SymGetLineFromInlineContextFn = unsafe extern "system" fn(
- c::HANDLE,
- u64,
- c::ULONG,
- u64,
- *mut c::DWORD,
- *mut c::IMAGEHLP_LINE64,
-) -> c::BOOL;
-
-/// Converts a pointer to symbol to its string value.
-pub fn resolve_symname<F>(frame: Frame, callback: F, context: &BacktraceContext) -> io::Result<()>
-where
- F: FnOnce(Option<&str>) -> io::Result<()>,
-{
- match context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(_, ref fns) => resolve_symname_internal(
- |process: c::HANDLE,
- symbol_address: u64,
- inline_context: c::ULONG,
- info: *mut c::SYMBOL_INFO| unsafe {
- let mut displacement = 0u64;
- (fns.resolve_symname)(
- process,
- symbol_address,
- inline_context,
- &mut displacement,
- info,
- )
- },
- frame,
- callback,
- context,
- ),
- StackWalkVariant::StackWalk64(_, ref fns) => resolve_symname_internal(
- |process: c::HANDLE,
- symbol_address: u64,
- _inline_context: c::ULONG,
- info: *mut c::SYMBOL_INFO| unsafe {
- let mut displacement = 0u64;
- (fns.resolve_symname)(process, symbol_address, &mut displacement, info)
- },
- frame,
- callback,
- context,
- ),
- }
-}
-
-fn resolve_symname_internal<F, R>(
- mut symbol_resolver: R,
- frame: Frame,
- callback: F,
- context: &BacktraceContext,
-) -> io::Result<()>
-where
- F: FnOnce(Option<&str>) -> io::Result<()>,
- R: FnMut(c::HANDLE, u64, c::ULONG, *mut c::SYMBOL_INFO) -> c::BOOL,
-{
- unsafe {
- let mut info: c::SYMBOL_INFO = mem::zeroed();
- info.MaxNameLen = c::MAX_SYM_NAME as c_ulong;
- // the struct size in C. the value is different to
- // `size_of::<SYMBOL_INFO>() - MAX_SYM_NAME + 1` (== 81)
- // due to struct alignment.
- info.SizeOfStruct = 88;
-
- let ret = symbol_resolver(
- context.handle,
- frame.symbol_addr as u64,
- frame.inline_context,
- &mut info,
- );
- let valid_range = if ret == c::TRUE && frame.symbol_addr as usize >= info.Address as usize {
- if info.Size != 0 {
- (frame.symbol_addr as usize) < info.Address as usize + info.Size as usize
- } else {
- true
- }
- } else {
- false
- };
- let symname = if valid_range {
- let ptr = info.Name.as_ptr() as *const c_char;
- CStr::from_ptr(ptr).to_str().ok()
- } else {
- None
- };
- callback(symname)
- }
-}
-
-pub fn foreach_symbol_fileline<F>(
- frame: Frame,
- callback: F,
- context: &BacktraceContext,
-) -> io::Result<bool>
-where
- F: FnMut(&[u8], u32) -> io::Result<()>,
-{
- match context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(_, ref fns) => foreach_symbol_fileline_iternal(
- |process: c::HANDLE,
- frame_address: u64,
- inline_context: c::ULONG,
- line: *mut c::IMAGEHLP_LINE64| unsafe {
- let mut displacement = 0u32;
- (fns.sym_get_line)(
- process,
- frame_address,
- inline_context,
- 0,
- &mut displacement,
- line,
- )
- },
- frame,
- callback,
- context,
- ),
- StackWalkVariant::StackWalk64(_, ref fns) => foreach_symbol_fileline_iternal(
- |process: c::HANDLE,
- frame_address: u64,
- _inline_context: c::ULONG,
- line: *mut c::IMAGEHLP_LINE64| unsafe {
- let mut displacement = 0u32;
- (fns.sym_get_line)(process, frame_address, &mut displacement, line)
- },
- frame,
- callback,
- context,
- ),
- }
-}
-
-fn foreach_symbol_fileline_iternal<F, G>(
- mut line_getter: G,
- frame: Frame,
- mut callback: F,
- context: &BacktraceContext,
-) -> io::Result<bool>
-where
- F: FnMut(&[u8], u32) -> io::Result<()>,
- G: FnMut(c::HANDLE, u64, c::ULONG, *mut c::IMAGEHLP_LINE64) -> c::BOOL,
-{
- unsafe {
- let mut line: c::IMAGEHLP_LINE64 = mem::zeroed();
- line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
-
- let ret = line_getter(
- context.handle,
- frame.exact_position as u64,
- frame.inline_context,
- &mut line,
- );
- if ret == c::TRUE {
- let name = CStr::from_ptr(line.Filename).to_bytes();
- callback(name, line.LineNumber as u32)?;
- }
- Ok(false)
- }
-}
diff --git a/ctr-std/src/sys/windows/c.rs b/ctr-std/src/sys/windows/c.rs
deleted file mode 100644
index e514a56..0000000
--- a/ctr-std/src/sys/windows/c.rs
+++ /dev/null
@@ -1,1334 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! C definitions used by libnative that don't belong in liblibc
-
-#![allow(bad_style)]
-#![cfg_attr(test, allow(dead_code))]
-#![unstable(issue = "0", feature = "windows_c")]
-
-use os::raw::{c_int, c_uint, c_ulong, c_long, c_longlong, c_ushort, c_char};
-#[cfg(target_arch = "x86_64")]
-use os::raw::c_ulonglong;
-use libc::{wchar_t, size_t, c_void};
-use ptr;
-
-pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
-pub use self::EXCEPTION_DISPOSITION::*;
-
-pub type DWORD = c_ulong;
-pub type HANDLE = LPVOID;
-pub type HINSTANCE = HANDLE;
-pub type HMODULE = HINSTANCE;
-pub type HRESULT = LONG;
-pub type BOOL = c_int;
-pub type BYTE = u8;
-pub type BOOLEAN = BYTE;
-pub type GROUP = c_uint;
-pub type LARGE_INTEGER = c_longlong;
-pub type LONG = c_long;
-pub type UINT = c_uint;
-pub type WCHAR = u16;
-pub type USHORT = c_ushort;
-pub type SIZE_T = usize;
-pub type WORD = u16;
-pub type CHAR = c_char;
-pub type ULONG_PTR = usize;
-pub type ULONG = c_ulong;
-#[cfg(target_arch = "x86_64")]
-pub type ULONGLONG = u64;
-#[cfg(target_arch = "x86_64")]
-pub type DWORDLONG = ULONGLONG;
-
-pub type LPBOOL = *mut BOOL;
-pub type LPBYTE = *mut BYTE;
-pub type LPBY_HANDLE_FILE_INFORMATION = *mut BY_HANDLE_FILE_INFORMATION;
-pub type LPCSTR = *const CHAR;
-pub type LPCVOID = *const c_void;
-pub type LPCWSTR = *const WCHAR;
-pub type LPDWORD = *mut DWORD;
-pub type LPHANDLE = *mut HANDLE;
-pub type LPOVERLAPPED = *mut OVERLAPPED;
-pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
-pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
-pub type LPSTARTUPINFO = *mut STARTUPINFO;
-pub type LPVOID = *mut c_void;
-pub type LPWCH = *mut WCHAR;
-pub type LPWIN32_FIND_DATAW = *mut WIN32_FIND_DATAW;
-pub type LPWSADATA = *mut WSADATA;
-pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO;
-pub type LPSTR = *mut CHAR;
-pub type LPWSTR = *mut WCHAR;
-pub type LPFILETIME = *mut FILETIME;
-
-pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
-pub type PLARGE_INTEGER = *mut c_longlong;
-pub type PSRWLOCK = *mut SRWLOCK;
-
-pub type SOCKET = ::os::windows::raw::SOCKET;
-pub type socklen_t = c_int;
-pub type ADDRESS_FAMILY = USHORT;
-
-pub const TRUE: BOOL = 1;
-pub const FALSE: BOOL = 0;
-
-pub const FILE_ATTRIBUTE_READONLY: DWORD = 0x1;
-pub const FILE_ATTRIBUTE_DIRECTORY: DWORD = 0x10;
-pub const FILE_ATTRIBUTE_REPARSE_POINT: DWORD = 0x400;
-
-pub const FILE_SHARE_DELETE: DWORD = 0x4;
-pub const FILE_SHARE_READ: DWORD = 0x1;
-pub const FILE_SHARE_WRITE: DWORD = 0x2;
-
-pub const CREATE_ALWAYS: DWORD = 2;
-pub const CREATE_NEW: DWORD = 1;
-pub const OPEN_ALWAYS: DWORD = 4;
-pub const OPEN_EXISTING: DWORD = 3;
-pub const TRUNCATE_EXISTING: DWORD = 5;
-
-pub const FILE_WRITE_DATA: DWORD = 0x00000002;
-pub const FILE_APPEND_DATA: DWORD = 0x00000004;
-pub const FILE_WRITE_EA: DWORD = 0x00000010;
-pub const FILE_WRITE_ATTRIBUTES: DWORD = 0x00000100;
-pub const READ_CONTROL: DWORD = 0x00020000;
-pub const SYNCHRONIZE: DWORD = 0x00100000;
-pub const GENERIC_READ: DWORD = 0x80000000;
-pub const GENERIC_WRITE: DWORD = 0x40000000;
-pub const STANDARD_RIGHTS_WRITE: DWORD = READ_CONTROL;
-pub const FILE_GENERIC_WRITE: DWORD = STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA |
- FILE_WRITE_ATTRIBUTES |
- FILE_WRITE_EA |
- FILE_APPEND_DATA |
- SYNCHRONIZE;
-
-pub const FILE_FLAG_OPEN_REPARSE_POINT: DWORD = 0x00200000;
-pub const FILE_FLAG_BACKUP_SEMANTICS: DWORD = 0x02000000;
-pub const SECURITY_SQOS_PRESENT: DWORD = 0x00100000;
-
-pub const FIONBIO: c_ulong = 0x8004667e;
-
-#[repr(C)]
-#[derive(Copy)]
-pub struct WIN32_FIND_DATAW {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
- pub dwReserved0: DWORD,
- pub dwReserved1: DWORD,
- pub cFileName: [wchar_t; 260], // #define MAX_PATH 260
- pub cAlternateFileName: [wchar_t; 14],
-}
-impl Clone for WIN32_FIND_DATAW {
- fn clone(&self) -> Self { *self }
-}
-
-pub const WSA_FLAG_OVERLAPPED: DWORD = 0x01;
-
-pub const WSADESCRIPTION_LEN: usize = 256;
-pub const WSASYS_STATUS_LEN: usize = 128;
-pub const WSAPROTOCOL_LEN: DWORD = 255;
-pub const INVALID_SOCKET: SOCKET = !0;
-
-pub const WSAEACCES: c_int = 10013;
-pub const WSAEINVAL: c_int = 10022;
-pub const WSAEWOULDBLOCK: c_int = 10035;
-pub const WSAEADDRINUSE: c_int = 10048;
-pub const WSAEADDRNOTAVAIL: c_int = 10049;
-pub const WSAECONNABORTED: c_int = 10053;
-pub const WSAECONNRESET: c_int = 10054;
-pub const WSAENOTCONN: c_int = 10057;
-pub const WSAESHUTDOWN: c_int = 10058;
-pub const WSAETIMEDOUT: c_int = 10060;
-pub const WSAECONNREFUSED: c_int = 10061;
-
-pub const MAX_PROTOCOL_CHAIN: DWORD = 7;
-
-pub const TOKEN_READ: DWORD = 0x20008;
-pub const MAXIMUM_REPARSE_DATA_BUFFER_SIZE: usize = 16 * 1024;
-pub const FSCTL_GET_REPARSE_POINT: DWORD = 0x900a8;
-pub const IO_REPARSE_TAG_SYMLINK: DWORD = 0xa000000c;
-pub const IO_REPARSE_TAG_MOUNT_POINT: DWORD = 0xa0000003;
-pub const SYMLINK_FLAG_RELATIVE: DWORD = 0x00000001;
-pub const FSCTL_SET_REPARSE_POINT: DWORD = 0x900a4;
-
-pub const SYMBOLIC_LINK_FLAG_DIRECTORY: DWORD = 0x1;
-pub const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE: DWORD = 0x2;
-
-// Note that these are not actually HANDLEs, just values to pass to GetStdHandle
-pub const STD_INPUT_HANDLE: DWORD = -10i32 as DWORD;
-pub const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
-pub const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
-
-pub const HANDLE_FLAG_INHERIT: DWORD = 0x00000001;
-
-pub const PROGRESS_CONTINUE: DWORD = 0;
-
-pub const ERROR_FILE_NOT_FOUND: DWORD = 2;
-pub const ERROR_PATH_NOT_FOUND: DWORD = 3;
-pub const ERROR_ACCESS_DENIED: DWORD = 5;
-pub const ERROR_INVALID_HANDLE: DWORD = 6;
-pub const ERROR_NO_MORE_FILES: DWORD = 18;
-pub const ERROR_HANDLE_EOF: DWORD = 38;
-pub const ERROR_FILE_EXISTS: DWORD = 80;
-pub const ERROR_INVALID_PARAMETER: DWORD = 87;
-pub const ERROR_BROKEN_PIPE: DWORD = 109;
-pub const ERROR_CALL_NOT_IMPLEMENTED: DWORD = 120;
-pub const ERROR_INSUFFICIENT_BUFFER: DWORD = 122;
-pub const ERROR_ALREADY_EXISTS: DWORD = 183;
-pub const ERROR_NO_DATA: DWORD = 232;
-pub const ERROR_ENVVAR_NOT_FOUND: DWORD = 203;
-pub const ERROR_OPERATION_ABORTED: DWORD = 995;
-pub const ERROR_IO_PENDING: DWORD = 997;
-pub const ERROR_TIMEOUT: DWORD = 0x5B4;
-
-pub const E_NOTIMPL: HRESULT = 0x80004001u32 as HRESULT;
-
-pub const INVALID_HANDLE_VALUE: HANDLE = !0 as HANDLE;
-
-pub const FACILITY_NT_BIT: DWORD = 0x1000_0000;
-
-pub const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
-pub const FORMAT_MESSAGE_FROM_HMODULE: DWORD = 0x00000800;
-pub const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
-
-pub const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
-
-pub const DLL_THREAD_DETACH: DWORD = 3;
-pub const DLL_PROCESS_DETACH: DWORD = 0;
-
-pub const INFINITE: DWORD = !0;
-
-pub const DUPLICATE_SAME_ACCESS: DWORD = 0x00000002;
-
-pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
- ptr: ptr::null_mut(),
-};
-pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: ptr::null_mut() };
-
-pub const DETACHED_PROCESS: DWORD = 0x00000008;
-pub const CREATE_NEW_PROCESS_GROUP: DWORD = 0x00000200;
-pub const CREATE_UNICODE_ENVIRONMENT: DWORD = 0x00000400;
-pub const STARTF_USESTDHANDLES: DWORD = 0x00000100;
-
-pub const AF_INET: c_int = 2;
-pub const AF_INET6: c_int = 23;
-pub const SD_BOTH: c_int = 2;
-pub const SD_RECEIVE: c_int = 0;
-pub const SD_SEND: c_int = 1;
-pub const SOCK_DGRAM: c_int = 2;
-pub const SOCK_STREAM: c_int = 1;
-pub const SOL_SOCKET: c_int = 0xffff;
-pub const SO_RCVTIMEO: c_int = 0x1006;
-pub const SO_SNDTIMEO: c_int = 0x1005;
-pub const SO_REUSEADDR: c_int = 0x0004;
-pub const IPPROTO_IP: c_int = 0;
-pub const IPPROTO_TCP: c_int = 6;
-pub const IPPROTO_IPV6: c_int = 41;
-pub const TCP_NODELAY: c_int = 0x0001;
-pub const IP_TTL: c_int = 4;
-pub const IPV6_V6ONLY: c_int = 27;
-pub const SO_ERROR: c_int = 0x1007;
-pub const SO_BROADCAST: c_int = 0x0020;
-pub const IP_MULTICAST_LOOP: c_int = 11;
-pub const IPV6_MULTICAST_LOOP: c_int = 11;
-pub const IP_MULTICAST_TTL: c_int = 10;
-pub const IP_ADD_MEMBERSHIP: c_int = 12;
-pub const IP_DROP_MEMBERSHIP: c_int = 13;
-pub const IPV6_ADD_MEMBERSHIP: c_int = 12;
-pub const IPV6_DROP_MEMBERSHIP: c_int = 13;
-pub const MSG_PEEK: c_int = 0x2;
-
-#[repr(C)]
-pub struct ip_mreq {
- pub imr_multiaddr: in_addr,
- pub imr_interface: in_addr,
-}
-
-#[repr(C)]
-pub struct ipv6_mreq {
- pub ipv6mr_multiaddr: in6_addr,
- pub ipv6mr_interface: c_uint,
-}
-
-pub const VOLUME_NAME_DOS: DWORD = 0x0;
-pub const MOVEFILE_REPLACE_EXISTING: DWORD = 1;
-
-pub const FILE_BEGIN: DWORD = 0;
-pub const FILE_CURRENT: DWORD = 1;
-pub const FILE_END: DWORD = 2;
-
-pub const WAIT_OBJECT_0: DWORD = 0x00000000;
-pub const WAIT_TIMEOUT: DWORD = 258;
-pub const WAIT_FAILED: DWORD = 0xFFFFFFFF;
-
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub const MAX_SYM_NAME: usize = 2000;
-#[cfg(target_arch = "x86")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_I386: DWORD = 0x014c;
-#[cfg(target_arch = "x86_64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_AMD64: DWORD = 0x8664;
-#[cfg(target_arch = "aarch64")]
-#[cfg(feature = "backtrace")]
-pub const IMAGE_FILE_MACHINE_ARM64: DWORD = 0xAA64;
-
-pub const EXCEPTION_CONTINUE_SEARCH: LONG = 0;
-pub const EXCEPTION_STACK_OVERFLOW: DWORD = 0xc00000fd;
-pub const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
-
-pub const PIPE_ACCESS_INBOUND: DWORD = 0x00000001;
-pub const PIPE_ACCESS_OUTBOUND: DWORD = 0x00000002;
-pub const FILE_FLAG_FIRST_PIPE_INSTANCE: DWORD = 0x00080000;
-pub const FILE_FLAG_OVERLAPPED: DWORD = 0x40000000;
-pub const PIPE_WAIT: DWORD = 0x00000000;
-pub const PIPE_TYPE_BYTE: DWORD = 0x00000000;
-pub const PIPE_REJECT_REMOTE_CLIENTS: DWORD = 0x00000008;
-pub const PIPE_READMODE_BYTE: DWORD = 0x00000000;
-
-pub const FD_SETSIZE: usize = 64;
-
-pub const STACK_SIZE_PARAM_IS_A_RESERVATION: DWORD = 0x00010000;
-
-#[repr(C)]
-#[cfg(not(target_pointer_width = "64"))]
-pub struct WSADATA {
- pub wVersion: WORD,
- pub wHighVersion: WORD,
- pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
- pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
- pub iMaxSockets: u16,
- pub iMaxUdpDg: u16,
- pub lpVendorInfo: *mut u8,
-}
-#[repr(C)]
-#[cfg(target_pointer_width = "64")]
-pub struct WSADATA {
- pub wVersion: WORD,
- pub wHighVersion: WORD,
- pub iMaxSockets: u16,
- pub iMaxUdpDg: u16,
- pub lpVendorInfo: *mut u8,
- pub szDescription: [u8; WSADESCRIPTION_LEN + 1],
- pub szSystemStatus: [u8; WSASYS_STATUS_LEN + 1],
-}
-
-#[repr(C)]
-pub struct WSAPROTOCOL_INFO {
- pub dwServiceFlags1: DWORD,
- pub dwServiceFlags2: DWORD,
- pub dwServiceFlags3: DWORD,
- pub dwServiceFlags4: DWORD,
- pub dwProviderFlags: DWORD,
- pub ProviderId: GUID,
- pub dwCatalogEntryId: DWORD,
- pub ProtocolChain: WSAPROTOCOLCHAIN,
- pub iVersion: c_int,
- pub iAddressFamily: c_int,
- pub iMaxSockAddr: c_int,
- pub iMinSockAddr: c_int,
- pub iSocketType: c_int,
- pub iProtocol: c_int,
- pub iProtocolMaxOffset: c_int,
- pub iNetworkByteOrder: c_int,
- pub iSecurityScheme: c_int,
- pub dwMessageSize: DWORD,
- pub dwProviderReserved: DWORD,
- pub szProtocol: [u16; (WSAPROTOCOL_LEN as usize) + 1],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct WIN32_FILE_ATTRIBUTE_DATA {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
-}
-
-#[repr(C)]
-pub struct BY_HANDLE_FILE_INFORMATION {
- pub dwFileAttributes: DWORD,
- pub ftCreationTime: FILETIME,
- pub ftLastAccessTime: FILETIME,
- pub ftLastWriteTime: FILETIME,
- pub dwVolumeSerialNumber: DWORD,
- pub nFileSizeHigh: DWORD,
- pub nFileSizeLow: DWORD,
- pub nNumberOfLinks: DWORD,
- pub nFileIndexHigh: DWORD,
- pub nFileIndexLow: DWORD,
-}
-
-#[repr(C)]
-#[allow(dead_code)] // we only use some variants
-pub enum FILE_INFO_BY_HANDLE_CLASS {
- FileBasicInfo = 0,
- FileStandardInfo = 1,
- FileNameInfo = 2,
- FileRenameInfo = 3,
- FileDispositionInfo = 4,
- FileAllocationInfo = 5,
- FileEndOfFileInfo = 6,
- FileStreamInfo = 7,
- FileCompressionInfo = 8,
- FileAttributeTagInfo = 9,
- FileIdBothDirectoryInfo = 10, // 0xA
- FileIdBothDirectoryRestartInfo = 11, // 0xB
- FileIoPriorityHintInfo = 12, // 0xC
- FileRemoteProtocolInfo = 13, // 0xD
- FileFullDirectoryInfo = 14, // 0xE
- FileFullDirectoryRestartInfo = 15, // 0xF
- FileStorageInfo = 16, // 0x10
- FileAlignmentInfo = 17, // 0x11
- FileIdInfo = 18, // 0x12
- FileIdExtdDirectoryInfo = 19, // 0x13
- FileIdExtdDirectoryRestartInfo = 20, // 0x14
- MaximumFileInfoByHandlesClass
-}
-
-#[repr(C)]
-pub struct FILE_BASIC_INFO {
- pub CreationTime: LARGE_INTEGER,
- pub LastAccessTime: LARGE_INTEGER,
- pub LastWriteTime: LARGE_INTEGER,
- pub ChangeTime: LARGE_INTEGER,
- pub FileAttributes: DWORD,
-}
-
-#[repr(C)]
-pub struct FILE_END_OF_FILE_INFO {
- pub EndOfFile: LARGE_INTEGER,
-}
-
-#[repr(C)]
-pub struct REPARSE_DATA_BUFFER {
- pub ReparseTag: c_uint,
- pub ReparseDataLength: c_ushort,
- pub Reserved: c_ushort,
- pub rest: (),
-}
-
-#[repr(C)]
-pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
- pub SubstituteNameOffset: c_ushort,
- pub SubstituteNameLength: c_ushort,
- pub PrintNameOffset: c_ushort,
- pub PrintNameLength: c_ushort,
- pub Flags: c_ulong,
- pub PathBuffer: WCHAR,
-}
-
-#[repr(C)]
-pub struct MOUNT_POINT_REPARSE_BUFFER {
- pub SubstituteNameOffset: c_ushort,
- pub SubstituteNameLength: c_ushort,
- pub PrintNameOffset: c_ushort,
- pub PrintNameLength: c_ushort,
- pub PathBuffer: WCHAR,
-}
-
-pub type LPPROGRESS_ROUTINE = ::option::Option<unsafe extern "system" fn(
- TotalFileSize: LARGE_INTEGER,
- TotalBytesTransferred: LARGE_INTEGER,
- StreamSize: LARGE_INTEGER,
- StreamBytesTransferred: LARGE_INTEGER,
- dwStreamNumber: DWORD,
- dwCallbackReason: DWORD,
- hSourceFile: HANDLE,
- hDestinationFile: HANDLE,
- lpData: LPVOID,
-) -> DWORD>;
-
-#[repr(C)]
-pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
-#[repr(C)]
-pub struct SRWLOCK { pub ptr: LPVOID }
-#[repr(C)]
-pub struct CRITICAL_SECTION {
- CriticalSectionDebug: LPVOID,
- LockCount: LONG,
- RecursionCount: LONG,
- OwningThread: HANDLE,
- LockSemaphore: HANDLE,
- SpinCount: ULONG_PTR
-}
-
-#[repr(C)]
-pub struct REPARSE_MOUNTPOINT_DATA_BUFFER {
- pub ReparseTag: DWORD,
- pub ReparseDataLength: DWORD,
- pub Reserved: WORD,
- pub ReparseTargetLength: WORD,
- pub ReparseTargetMaximumLength: WORD,
- pub Reserved1: WORD,
- pub ReparseTarget: WCHAR,
-}
-
-#[repr(C)]
-pub struct EXCEPTION_RECORD {
- pub ExceptionCode: DWORD,
- pub ExceptionFlags: DWORD,
- pub ExceptionRecord: *mut EXCEPTION_RECORD,
- pub ExceptionAddress: LPVOID,
- pub NumberParameters: DWORD,
- pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
-}
-
-#[repr(C)]
-pub struct EXCEPTION_POINTERS {
- pub ExceptionRecord: *mut EXCEPTION_RECORD,
- pub ContextRecord: *mut CONTEXT,
-}
-
-pub type PVECTORED_EXCEPTION_HANDLER = extern "system"
- fn(ExceptionInfo: *mut EXCEPTION_POINTERS) -> LONG;
-
-#[repr(C)]
-pub struct GUID {
- pub Data1: DWORD,
- pub Data2: WORD,
- pub Data3: WORD,
- pub Data4: [BYTE; 8],
-}
-
-#[repr(C)]
-pub struct WSAPROTOCOLCHAIN {
- pub ChainLen: c_int,
- pub ChainEntries: [DWORD; MAX_PROTOCOL_CHAIN as usize],
-}
-
-#[repr(C)]
-pub struct SECURITY_ATTRIBUTES {
- pub nLength: DWORD,
- pub lpSecurityDescriptor: LPVOID,
- pub bInheritHandle: BOOL,
-}
-
-#[repr(C)]
-pub struct PROCESS_INFORMATION {
- pub hProcess: HANDLE,
- pub hThread: HANDLE,
- pub dwProcessId: DWORD,
- pub dwThreadId: DWORD,
-}
-
-#[repr(C)]
-pub struct STARTUPINFO {
- pub cb: DWORD,
- pub lpReserved: LPWSTR,
- pub lpDesktop: LPWSTR,
- pub lpTitle: LPWSTR,
- pub dwX: DWORD,
- pub dwY: DWORD,
- pub dwXSize: DWORD,
- pub dwYSize: DWORD,
- pub dwXCountChars: DWORD,
- pub dwYCountCharts: DWORD,
- pub dwFillAttribute: DWORD,
- pub dwFlags: DWORD,
- pub wShowWindow: WORD,
- pub cbReserved2: WORD,
- pub lpReserved2: LPBYTE,
- pub hStdInput: HANDLE,
- pub hStdOutput: HANDLE,
- pub hStdError: HANDLE,
-}
-
-#[repr(C)]
-pub struct SOCKADDR {
- pub sa_family: ADDRESS_FAMILY,
- pub sa_data: [CHAR; 14],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct FILETIME {
- pub dwLowDateTime: DWORD,
- pub dwHighDateTime: DWORD,
-}
-
-#[repr(C)]
-pub struct OVERLAPPED {
- pub Internal: *mut c_ulong,
- pub InternalHigh: *mut c_ulong,
- pub Offset: DWORD,
- pub OffsetHigh: DWORD,
- pub hEvent: HANDLE,
-}
-
-#[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct SYMBOL_INFO {
- pub SizeOfStruct: c_ulong,
- pub TypeIndex: c_ulong,
- pub Reserved: [u64; 2],
- pub Index: c_ulong,
- pub Size: c_ulong,
- pub ModBase: u64,
- pub Flags: c_ulong,
- pub Value: u64,
- pub Address: u64,
- pub Register: c_ulong,
- pub Scope: c_ulong,
- pub Tag: c_ulong,
- pub NameLen: c_ulong,
- pub MaxNameLen: c_ulong,
- // note that windows has this as 1, but it basically just means that
- // the name is inline at the end of the struct. For us, we just bump
- // the struct size up to MAX_SYM_NAME.
- pub Name: [c_char; MAX_SYM_NAME],
-}
-
-#[repr(C)]
-#[cfg(target_env = "msvc")]
-#[cfg(feature = "backtrace")]
-pub struct IMAGEHLP_LINE64 {
- pub SizeOfStruct: u32,
- pub Key: *const c_void,
- pub LineNumber: u32,
- pub Filename: *const c_char,
- pub Address: u64,
-}
-
-#[repr(C)]
-#[allow(dead_code)] // we only use some variants
-pub enum ADDRESS_MODE {
- AddrMode1616,
- AddrMode1632,
- AddrModeReal,
- AddrModeFlat,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct ADDRESS64 {
- pub Offset: u64,
- pub Segment: u16,
- pub Mode: ADDRESS_MODE,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME_EX {
- pub AddrPC: ADDRESS64,
- pub AddrReturn: ADDRESS64,
- pub AddrFrame: ADDRESS64,
- pub AddrStack: ADDRESS64,
- pub AddrBStore: ADDRESS64,
- pub FuncTableEntry: *mut c_void,
- pub Params: [u64; 4],
- pub Far: BOOL,
- pub Virtual: BOOL,
- pub Reserved: [u64; 3],
- pub KdHelp: KDHELP64,
- pub StackFrameSize: DWORD,
- pub InlineFrameContext: DWORD,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct STACKFRAME64 {
- pub AddrPC: ADDRESS64,
- pub AddrReturn: ADDRESS64,
- pub AddrFrame: ADDRESS64,
- pub AddrStack: ADDRESS64,
- pub AddrBStore: ADDRESS64,
- pub FuncTableEntry: *mut c_void,
- pub Params: [u64; 4],
- pub Far: BOOL,
- pub Virtual: BOOL,
- pub Reserved: [u64; 3],
- pub KdHelp: KDHELP64,
-}
-
-#[repr(C)]
-#[cfg(feature = "backtrace")]
-pub struct KDHELP64 {
- pub Thread: u64,
- pub ThCallbackStack: DWORD,
- pub ThCallbackBStore: DWORD,
- pub NextCallback: DWORD,
- pub FramePointer: DWORD,
- pub KiCallUserMode: u64,
- pub KeUserCallbackDispatcher: u64,
- pub SystemRangeStart: u64,
- pub KiUserExceptionDispatcher: u64,
- pub StackBase: u64,
- pub StackLimit: u64,
- pub Reserved: [u64; 5],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct CONTEXT {
- pub ContextFlags: DWORD,
- pub Dr0: DWORD,
- pub Dr1: DWORD,
- pub Dr2: DWORD,
- pub Dr3: DWORD,
- pub Dr6: DWORD,
- pub Dr7: DWORD,
- pub FloatSave: FLOATING_SAVE_AREA,
- pub SegGs: DWORD,
- pub SegFs: DWORD,
- pub SegEs: DWORD,
- pub SegDs: DWORD,
- pub Edi: DWORD,
- pub Esi: DWORD,
- pub Ebx: DWORD,
- pub Edx: DWORD,
- pub Ecx: DWORD,
- pub Eax: DWORD,
- pub Ebp: DWORD,
- pub Eip: DWORD,
- pub SegCs: DWORD,
- pub EFlags: DWORD,
- pub Esp: DWORD,
- pub SegSs: DWORD,
- pub ExtendedRegisters: [u8; 512],
-}
-
-#[cfg(target_arch = "x86")]
-#[repr(C)]
-pub struct FLOATING_SAVE_AREA {
- pub ControlWord: DWORD,
- pub StatusWord: DWORD,
- pub TagWord: DWORD,
- pub ErrorOffset: DWORD,
- pub ErrorSelector: DWORD,
- pub DataOffset: DWORD,
- pub DataSelector: DWORD,
- pub RegisterArea: [u8; 80],
- pub Cr0NpxState: DWORD,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
- pub P1Home: DWORDLONG,
- pub P2Home: DWORDLONG,
- pub P3Home: DWORDLONG,
- pub P4Home: DWORDLONG,
- pub P5Home: DWORDLONG,
- pub P6Home: DWORDLONG,
-
- pub ContextFlags: DWORD,
- pub MxCsr: DWORD,
-
- pub SegCs: WORD,
- pub SegDs: WORD,
- pub SegEs: WORD,
- pub SegFs: WORD,
- pub SegGs: WORD,
- pub SegSs: WORD,
- pub EFlags: DWORD,
-
- pub Dr0: DWORDLONG,
- pub Dr1: DWORDLONG,
- pub Dr2: DWORDLONG,
- pub Dr3: DWORDLONG,
- pub Dr6: DWORDLONG,
- pub Dr7: DWORDLONG,
-
- pub Rax: DWORDLONG,
- pub Rcx: DWORDLONG,
- pub Rdx: DWORDLONG,
- pub Rbx: DWORDLONG,
- pub Rsp: DWORDLONG,
- pub Rbp: DWORDLONG,
- pub Rsi: DWORDLONG,
- pub Rdi: DWORDLONG,
- pub R8: DWORDLONG,
- pub R9: DWORDLONG,
- pub R10: DWORDLONG,
- pub R11: DWORDLONG,
- pub R12: DWORDLONG,
- pub R13: DWORDLONG,
- pub R14: DWORDLONG,
- pub R15: DWORDLONG,
-
- pub Rip: DWORDLONG,
-
- pub FltSave: FLOATING_SAVE_AREA,
-
- pub VectorRegister: [M128A; 26],
- pub VectorControl: DWORDLONG,
-
- pub DebugControl: DWORDLONG,
- pub LastBranchToRip: DWORDLONG,
- pub LastBranchFromRip: DWORDLONG,
- pub LastExceptionToRip: DWORDLONG,
- pub LastExceptionFromRip: DWORDLONG,
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct M128A {
- pub Low: c_ulonglong,
- pub High: c_longlong
-}
-
-#[cfg(target_arch = "x86_64")]
-#[repr(C, align(16))]
-pub struct FLOATING_SAVE_AREA {
- _Dummy: [u8; 512] // FIXME: Fill this out
-}
-
-// FIXME(#43348): This structure is used for backtrace only, and a fake
-// definition is provided here only to allow rustdoc to pass type-check. This
-// will not appear in the final documentation. This should be also defined for
-// other architectures supported by Windows such as ARM, and for historical
-// interest, maybe MIPS and PowerPC as well.
-#[cfg(all(dox, not(any(target_arch = "x86_64", target_arch = "x86", target_arch = "aarch64"))))]
-pub enum CONTEXT {}
-
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_BREAKPOINTS: usize = 8;
-
-#[cfg(target_arch = "aarch64")]
-pub const ARM64_MAX_WATCHPOINTS: usize = 2;
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C)]
-pub struct ARM64_NT_NEON128 {
- pub D: [f64; 2],
-}
-
-#[cfg(target_arch = "aarch64")]
-#[repr(C, align(16))]
-pub struct CONTEXT {
- pub ContextFlags: DWORD,
- pub Cpsr: DWORD,
- pub X0: u64,
- pub X1: u64,
- pub X2: u64,
- pub X3: u64,
- pub X4: u64,
- pub X5: u64,
- pub X6: u64,
- pub X7: u64,
- pub X8: u64,
- pub X9: u64,
- pub X10: u64,
- pub X11: u64,
- pub X12: u64,
- pub X13: u64,
- pub X14: u64,
- pub X15: u64,
- pub X16: u64,
- pub X17: u64,
- pub X18: u64,
- pub X19: u64,
- pub X20: u64,
- pub X21: u64,
- pub X22: u64,
- pub X23: u64,
- pub X24: u64,
- pub X25: u64,
- pub X26: u64,
- pub X27: u64,
- pub X28: u64,
- pub Fp: u64,
- pub Lr: u64,
- pub Sp: u64,
- pub Pc: u64,
- pub V: [ARM64_NT_NEON128; 32],
- pub Fpcr: DWORD,
- pub Fpsr: DWORD,
- pub Bcr: [DWORD; ARM64_MAX_BREAKPOINTS],
- pub Bvr: [DWORD; ARM64_MAX_BREAKPOINTS],
- pub Wcr: [DWORD; ARM64_MAX_WATCHPOINTS],
- pub Wvr: [DWORD; ARM64_MAX_WATCHPOINTS],
-}
-
-#[repr(C)]
-pub struct SOCKADDR_STORAGE_LH {
- pub ss_family: ADDRESS_FAMILY,
- pub __ss_pad1: [CHAR; 6],
- pub __ss_align: i64,
- pub __ss_pad2: [CHAR; 112],
-}
-
-#[repr(C)]
-pub struct ADDRINFOA {
- pub ai_flags: c_int,
- pub ai_family: c_int,
- pub ai_socktype: c_int,
- pub ai_protocol: c_int,
- pub ai_addrlen: size_t,
- pub ai_canonname: *mut c_char,
- pub ai_addr: *mut SOCKADDR,
- pub ai_next: *mut ADDRINFOA,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct sockaddr_in {
- pub sin_family: ADDRESS_FAMILY,
- pub sin_port: USHORT,
- pub sin_addr: in_addr,
- pub sin_zero: [CHAR; 8],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct sockaddr_in6 {
- pub sin6_family: ADDRESS_FAMILY,
- pub sin6_port: USHORT,
- pub sin6_flowinfo: c_ulong,
- pub sin6_addr: in6_addr,
- pub sin6_scope_id: c_ulong,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct in_addr {
- pub s_addr: u32,
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct in6_addr {
- pub s6_addr: [u8; 16],
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-#[allow(dead_code)] // we only use some variants
-pub enum EXCEPTION_DISPOSITION {
- ExceptionContinueExecution,
- ExceptionContinueSearch,
- ExceptionNestedException,
- ExceptionCollidedUnwind
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct CONSOLE_READCONSOLE_CONTROL {
- pub nLength: ULONG,
- pub nInitialChars: ULONG,
- pub dwCtrlWakeupMask: ULONG,
- pub dwControlKeyState: ULONG,
-}
-pub type PCONSOLE_READCONSOLE_CONTROL = *mut CONSOLE_READCONSOLE_CONTROL;
-
-#[repr(C)]
-#[derive(Copy)]
-pub struct fd_set {
- pub fd_count: c_uint,
- pub fd_array: [SOCKET; FD_SETSIZE],
-}
-
-impl Clone for fd_set {
- fn clone(&self) -> fd_set {
- *self
- }
-}
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-pub struct timeval {
- pub tv_sec: c_long,
- pub tv_usec: c_long,
-}
-
-extern "system" {
- pub fn WSAStartup(wVersionRequested: WORD,
- lpWSAData: LPWSADATA) -> c_int;
- pub fn WSACleanup() -> c_int;
- pub fn WSAGetLastError() -> c_int;
- pub fn WSADuplicateSocketW(s: SOCKET,
- dwProcessId: DWORD,
- lpProtocolInfo: LPWSAPROTOCOL_INFO)
- -> c_int;
- pub fn GetCurrentProcessId() -> DWORD;
- pub fn WSASocketW(af: c_int,
- kind: c_int,
- protocol: c_int,
- lpProtocolInfo: LPWSAPROTOCOL_INFO,
- g: GROUP,
- dwFlags: DWORD) -> SOCKET;
- pub fn ioctlsocket(s: SOCKET, cmd: c_long, argp: *mut c_ulong) -> c_int;
- pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
- pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
- pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-
- pub fn ReadConsoleW(hConsoleInput: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfCharsToRead: DWORD,
- lpNumberOfCharsRead: LPDWORD,
- pInputControl: PCONSOLE_READCONSOLE_CONTROL) -> BOOL;
-
- pub fn WriteConsoleW(hConsoleOutput: HANDLE,
- lpBuffer: LPCVOID,
- nNumberOfCharsToWrite: DWORD,
- lpNumberOfCharsWritten: LPDWORD,
- lpReserved: LPVOID) -> BOOL;
-
- pub fn GetConsoleMode(hConsoleHandle: HANDLE,
- lpMode: LPDWORD) -> BOOL;
- pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn SetFileAttributesW(lpFileName: LPCWSTR,
- dwFileAttributes: DWORD) -> BOOL;
- pub fn GetFileInformationByHandle(hFile: HANDLE,
- lpFileInformation: LPBY_HANDLE_FILE_INFORMATION)
- -> BOOL;
-
- pub fn SetLastError(dwErrCode: DWORD);
- pub fn GetCommandLineW() -> *mut LPCWSTR;
- pub fn LocalFree(ptr: *mut c_void);
- pub fn CommandLineToArgvW(lpCmdLine: *mut LPCWSTR,
- pNumArgs: *mut c_int) -> *mut *mut u16;
- pub fn GetTempPathW(nBufferLength: DWORD,
- lpBuffer: LPCWSTR) -> DWORD;
- pub fn OpenProcessToken(ProcessHandle: HANDLE,
- DesiredAccess: DWORD,
- TokenHandle: *mut HANDLE) -> BOOL;
- pub fn GetCurrentProcess() -> HANDLE;
- pub fn GetCurrentThread() -> HANDLE;
- pub fn GetStdHandle(which: DWORD) -> HANDLE;
- pub fn ExitProcess(uExitCode: c_uint) -> !;
- pub fn DeviceIoControl(hDevice: HANDLE,
- dwIoControlCode: DWORD,
- lpInBuffer: LPVOID,
- nInBufferSize: DWORD,
- lpOutBuffer: LPVOID,
- nOutBufferSize: DWORD,
- lpBytesReturned: LPDWORD,
- lpOverlapped: LPOVERLAPPED) -> BOOL;
- pub fn CreateThread(lpThreadAttributes: LPSECURITY_ATTRIBUTES,
- dwStackSize: SIZE_T,
- lpStartAddress: extern "system" fn(*mut c_void)
- -> DWORD,
- lpParameter: LPVOID,
- dwCreationFlags: DWORD,
- lpThreadId: LPDWORD) -> HANDLE;
- pub fn WaitForSingleObject(hHandle: HANDLE,
- dwMilliseconds: DWORD) -> DWORD;
- pub fn SwitchToThread() -> BOOL;
- pub fn Sleep(dwMilliseconds: DWORD);
- pub fn GetProcessId(handle: HANDLE) -> DWORD;
- pub fn GetUserProfileDirectoryW(hToken: HANDLE,
- lpProfileDir: LPWSTR,
- lpcchSize: *mut DWORD) -> BOOL;
- pub fn SetHandleInformation(hObject: HANDLE,
- dwMask: DWORD,
- dwFlags: DWORD) -> BOOL;
- pub fn CopyFileExW(lpExistingFileName: LPCWSTR,
- lpNewFileName: LPCWSTR,
- lpProgressRoutine: LPPROGRESS_ROUTINE,
- lpData: LPVOID,
- pbCancel: LPBOOL,
- dwCopyFlags: DWORD) -> BOOL;
- pub fn AddVectoredExceptionHandler(FirstHandler: ULONG,
- VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
- -> LPVOID;
- pub fn FormatMessageW(flags: DWORD,
- lpSrc: LPVOID,
- msgId: DWORD,
- langId: DWORD,
- buf: LPWSTR,
- nsize: DWORD,
- args: *const c_void)
- -> DWORD;
- pub fn TlsAlloc() -> DWORD;
- pub fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
- pub fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
- pub fn GetLastError() -> DWORD;
- pub fn QueryPerformanceFrequency(lpFrequency: *mut LARGE_INTEGER) -> BOOL;
- pub fn QueryPerformanceCounter(lpPerformanceCount: *mut LARGE_INTEGER)
- -> BOOL;
- pub fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: LPDWORD) -> BOOL;
- pub fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) -> BOOL;
- pub fn CreateProcessW(lpApplicationName: LPCWSTR,
- lpCommandLine: LPWSTR,
- lpProcessAttributes: LPSECURITY_ATTRIBUTES,
- lpThreadAttributes: LPSECURITY_ATTRIBUTES,
- bInheritHandles: BOOL,
- dwCreationFlags: DWORD,
- lpEnvironment: LPVOID,
- lpCurrentDirectory: LPCWSTR,
- lpStartupInfo: LPSTARTUPINFO,
- lpProcessInformation: LPPROCESS_INFORMATION)
- -> BOOL;
- pub fn GetEnvironmentVariableW(n: LPCWSTR, v: LPWSTR, nsize: DWORD) -> DWORD;
- pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR) -> BOOL;
- pub fn GetEnvironmentStringsW() -> LPWCH;
- pub fn FreeEnvironmentStringsW(env_ptr: LPWCH) -> BOOL;
- pub fn GetModuleFileNameW(hModule: HMODULE,
- lpFilename: LPWSTR,
- nSize: DWORD)
- -> DWORD;
- pub fn CreateDirectoryW(lpPathName: LPCWSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
- -> BOOL;
- pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
- pub fn GetCurrentDirectoryW(nBufferLength: DWORD, lpBuffer: LPWSTR) -> DWORD;
- pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
- pub fn WideCharToMultiByte(CodePage: UINT,
- dwFlags: DWORD,
- lpWideCharStr: LPCWSTR,
- cchWideChar: c_int,
- lpMultiByteStr: LPSTR,
- cbMultiByte: c_int,
- lpDefaultChar: LPCSTR,
- lpUsedDefaultChar: LPBOOL) -> c_int;
-
- pub fn closesocket(socket: SOCKET) -> c_int;
- pub fn recv(socket: SOCKET, buf: *mut c_void, len: c_int,
- flags: c_int) -> c_int;
- pub fn send(socket: SOCKET, buf: *const c_void, len: c_int,
- flags: c_int) -> c_int;
- pub fn recvfrom(socket: SOCKET,
- buf: *mut c_void,
- len: c_int,
- flags: c_int,
- addr: *mut SOCKADDR,
- addrlen: *mut c_int)
- -> c_int;
- pub fn sendto(socket: SOCKET,
- buf: *const c_void,
- len: c_int,
- flags: c_int,
- addr: *const SOCKADDR,
- addrlen: c_int)
- -> c_int;
- pub fn shutdown(socket: SOCKET, how: c_int) -> c_int;
- pub fn accept(socket: SOCKET,
- address: *mut SOCKADDR,
- address_len: *mut c_int)
- -> SOCKET;
- pub fn DuplicateHandle(hSourceProcessHandle: HANDLE,
- hSourceHandle: HANDLE,
- hTargetProcessHandle: HANDLE,
- lpTargetHandle: LPHANDLE,
- dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwOptions: DWORD)
- -> BOOL;
- pub fn ReadFile(hFile: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfBytesToRead: DWORD,
- lpNumberOfBytesRead: LPDWORD,
- lpOverlapped: LPOVERLAPPED)
- -> BOOL;
- pub fn WriteFile(hFile: HANDLE,
- lpBuffer: LPVOID,
- nNumberOfBytesToWrite: DWORD,
- lpNumberOfBytesWritten: LPDWORD,
- lpOverlapped: LPOVERLAPPED)
- -> BOOL;
- pub fn CloseHandle(hObject: HANDLE) -> BOOL;
- pub fn CreateHardLinkW(lpSymlinkFileName: LPCWSTR,
- lpTargetFileName: LPCWSTR,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
- -> BOOL;
- pub fn MoveFileExW(lpExistingFileName: LPCWSTR,
- lpNewFileName: LPCWSTR,
- dwFlags: DWORD)
- -> BOOL;
- pub fn SetFilePointerEx(hFile: HANDLE,
- liDistanceToMove: LARGE_INTEGER,
- lpNewFilePointer: PLARGE_INTEGER,
- dwMoveMethod: DWORD)
- -> BOOL;
- pub fn FlushFileBuffers(hFile: HANDLE) -> BOOL;
- pub fn CreateFileW(lpFileName: LPCWSTR,
- dwDesiredAccess: DWORD,
- dwShareMode: DWORD,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES,
- dwCreationDisposition: DWORD,
- dwFlagsAndAttributes: DWORD,
- hTemplateFile: HANDLE)
- -> HANDLE;
-
- pub fn FindFirstFileW(fileName: LPCWSTR,
- findFileData: LPWIN32_FIND_DATAW)
- -> HANDLE;
- pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW)
- -> BOOL;
- pub fn FindClose(findFile: HANDLE) -> BOOL;
- #[cfg(feature = "backtrace")]
- pub fn RtlCaptureContext(ctx: *mut CONTEXT);
- pub fn getsockopt(s: SOCKET,
- level: c_int,
- optname: c_int,
- optval: *mut c_char,
- optlen: *mut c_int)
- -> c_int;
- pub fn setsockopt(s: SOCKET,
- level: c_int,
- optname: c_int,
- optval: *const c_void,
- optlen: c_int)
- -> c_int;
- pub fn getsockname(socket: SOCKET,
- address: *mut SOCKADDR,
- address_len: *mut c_int)
- -> c_int;
- pub fn getpeername(socket: SOCKET,
- address: *mut SOCKADDR,
- address_len: *mut c_int)
- -> c_int;
- pub fn bind(socket: SOCKET, address: *const SOCKADDR,
- address_len: socklen_t) -> c_int;
- pub fn listen(socket: SOCKET, backlog: c_int) -> c_int;
- pub fn connect(socket: SOCKET, address: *const SOCKADDR, len: c_int)
- -> c_int;
- pub fn getaddrinfo(node: *const c_char, service: *const c_char,
- hints: *const ADDRINFOA,
- res: *mut *mut ADDRINFOA) -> c_int;
- pub fn freeaddrinfo(res: *mut ADDRINFOA);
-
- #[cfg(feature = "backtrace")]
- pub fn LoadLibraryW(name: LPCWSTR) -> HMODULE;
- #[cfg(feature = "backtrace")]
- pub fn FreeLibrary(handle: HMODULE) -> BOOL;
- pub fn GetProcAddress(handle: HMODULE,
- name: LPCSTR) -> *mut c_void;
- pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
-
- pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME);
-
- pub fn CreateEventW(lpEventAttributes: LPSECURITY_ATTRIBUTES,
- bManualReset: BOOL,
- bInitialState: BOOL,
- lpName: LPCWSTR) -> HANDLE;
- pub fn WaitForMultipleObjects(nCount: DWORD,
- lpHandles: *const HANDLE,
- bWaitAll: BOOL,
- dwMilliseconds: DWORD) -> DWORD;
- pub fn CreateNamedPipeW(lpName: LPCWSTR,
- dwOpenMode: DWORD,
- dwPipeMode: DWORD,
- nMaxInstances: DWORD,
- nOutBufferSize: DWORD,
- nInBufferSize: DWORD,
- nDefaultTimeOut: DWORD,
- lpSecurityAttributes: LPSECURITY_ATTRIBUTES)
- -> HANDLE;
- pub fn CancelIo(handle: HANDLE) -> BOOL;
- pub fn GetOverlappedResult(hFile: HANDLE,
- lpOverlapped: LPOVERLAPPED,
- lpNumberOfBytesTransferred: LPDWORD,
- bWait: BOOL) -> BOOL;
- pub fn select(nfds: c_int,
- readfds: *mut fd_set,
- writefds: *mut fd_set,
- exceptfds: *mut fd_set,
- timeout: *const timeval) -> c_int;
-
- #[link_name = "SystemFunction036"]
- pub fn RtlGenRandom(RandomBuffer: *mut u8, RandomBufferLength: ULONG) -> BOOLEAN;
-}
-
-// Functions that aren't available on every version of Windows that we support,
-// but we still use them and just provide some form of a fallback implementation.
-compat_fn! {
- kernel32:
-
- pub fn CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
- _lpTargetFileName: LPCWSTR,
- _dwFlags: DWORD) -> BOOLEAN {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
- pub fn GetFinalPathNameByHandleW(_hFile: HANDLE,
- _lpszFilePath: LPCWSTR,
- _cchFilePath: DWORD,
- _dwFlags: DWORD) -> DWORD {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
- pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
- pub fn SetThreadDescription(hThread: HANDLE,
- lpThreadDescription: LPCWSTR) -> HRESULT {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); E_NOTIMPL
- }
- pub fn SetFileInformationByHandle(_hFile: HANDLE,
- _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
- _lpFileInformation: LPVOID,
- _dwBufferSize: DWORD) -> BOOL {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
- pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
- SRWLock: PSRWLOCK,
- dwMilliseconds: DWORD,
- Flags: ULONG) -> BOOL {
- panic!("condition variables not available")
- }
- pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
- -> () {
- panic!("condition variables not available")
- }
- pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
- -> () {
- panic!("condition variables not available")
- }
- pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
- panic!("rwlocks not available")
- }
- pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK) -> () {
- panic!("rwlocks not available")
- }
- pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
- panic!("rwlocks not available")
- }
- pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK) -> () {
- panic!("rwlocks not available")
- }
- pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN {
- panic!("rwlocks not available")
- }
- pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN {
- panic!("rwlocks not available")
- }
-}
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-mod gnu {
- use super::*;
-
- pub const PROCESS_QUERY_INFORMATION: DWORD = 0x0400;
-
- pub const CP_ACP: UINT = 0;
-
- pub const WC_NO_BEST_FIT_CHARS: DWORD = 0x00000400;
-
- extern "system" {
- pub fn OpenProcess(dwDesiredAccess: DWORD,
- bInheritHandle: BOOL,
- dwProcessId: DWORD) -> HANDLE;
- }
-
- compat_fn! {
- kernel32:
-
- pub fn QueryFullProcessImageNameW(_hProcess: HANDLE,
- _dwFlags: DWORD,
- _lpExeName: LPWSTR,
- _lpdwSize: LPDWORD) -> BOOL {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
- }
- }
-}
-
-#[cfg(all(target_env = "gnu", feature = "backtrace"))]
-pub use self::gnu::*;
diff --git a/ctr-std/src/sys/windows/cmath.rs b/ctr-std/src/sys/windows/cmath.rs
deleted file mode 100644
index b665a2c..0000000
--- a/ctr-std/src/sys/windows/cmath.rs
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg(not(test))]
-
-use libc::{c_float, c_double};
-
-#[link_name = "m"]
-extern {
- pub fn acos(n: c_double) -> c_double;
- pub fn asin(n: c_double) -> c_double;
- pub fn atan(n: c_double) -> c_double;
- pub fn atan2(a: c_double, b: c_double) -> c_double;
- pub fn cbrt(n: c_double) -> c_double;
- pub fn cbrtf(n: c_float) -> c_float;
- pub fn cosh(n: c_double) -> c_double;
- pub fn expm1(n: c_double) -> c_double;
- pub fn expm1f(n: c_float) -> c_float;
- pub fn fdim(a: c_double, b: c_double) -> c_double;
- pub fn fdimf(a: c_float, b: c_float) -> c_float;
- #[cfg_attr(target_env = "msvc", link_name = "_hypot")]
- pub fn hypot(x: c_double, y: c_double) -> c_double;
- #[cfg_attr(target_env = "msvc", link_name = "_hypotf")]
- pub fn hypotf(x: c_float, y: c_float) -> c_float;
- pub fn log1p(n: c_double) -> c_double;
- pub fn log1pf(n: c_float) -> c_float;
- pub fn sinh(n: c_double) -> c_double;
- pub fn tan(n: c_double) -> c_double;
- pub fn tanh(n: c_double) -> c_double;
-}
-
-pub use self::shims::*;
-
-#[cfg(not(target_env = "msvc"))]
-mod shims {
- use libc::c_float;
-
- extern {
- pub fn acosf(n: c_float) -> c_float;
- pub fn asinf(n: c_float) -> c_float;
- pub fn atan2f(a: c_float, b: c_float) -> c_float;
- pub fn atanf(n: c_float) -> c_float;
- pub fn coshf(n: c_float) -> c_float;
- pub fn sinhf(n: c_float) -> c_float;
- pub fn tanf(n: c_float) -> c_float;
- pub fn tanhf(n: c_float) -> c_float;
- }
-}
-
-// On MSVC these functions aren't defined, so we just define shims which promote
-// everything fo f64, perform the calculation, and then demote back to f32.
-// While not precisely correct should be "correct enough" for now.
-#[cfg(target_env = "msvc")]
-mod shims {
- use libc::c_float;
-
- #[inline]
- pub unsafe fn acosf(n: c_float) -> c_float {
- f64::acos(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn asinf(n: c_float) -> c_float {
- f64::asin(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn atan2f(n: c_float, b: c_float) -> c_float {
- f64::atan2(n as f64, b as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn atanf(n: c_float) -> c_float {
- f64::atan(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn coshf(n: c_float) -> c_float {
- f64::cosh(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn sinhf(n: c_float) -> c_float {
- f64::sinh(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn tanf(n: c_float) -> c_float {
- f64::tan(n as f64) as c_float
- }
-
- #[inline]
- pub unsafe fn tanhf(n: c_float) -> c_float {
- f64::tanh(n as f64) as c_float
- }
-}
diff --git a/ctr-std/src/sys/windows/compat.rs b/ctr-std/src/sys/windows/compat.rs
deleted file mode 100644
index cd42b7d..0000000
--- a/ctr-std/src/sys/windows/compat.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! A "compatibility layer" for spanning XP and Windows 7
-//!
-//! The standard library currently binds many functions that are not available
-//! on Windows XP, but we would also like to support building executables that
-//! run on XP. To do this we specify all non-XP APIs as having a fallback
-//! implementation to do something reasonable.
-//!
-//! This dynamic runtime detection of whether a function is available is
-//! implemented with `GetModuleHandle` and `GetProcAddress` paired with a
-//! static-per-function which caches the result of the first check. In this
-//! manner we pay a semi-large one-time cost up front for detecting whether a
-//! function is available but afterwards it's just a load and a jump.
-
-use ffi::CString;
-use sync::atomic::{AtomicUsize, Ordering};
-use sys::c;
-
-pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
- let mut module: Vec<u16> = module.encode_utf16().collect();
- module.push(0);
- let symbol = CString::new(symbol).unwrap();
- unsafe {
- let handle = c::GetModuleHandleW(module.as_ptr());
- match c::GetProcAddress(handle, symbol.as_ptr()) as usize {
- 0 => None,
- n => Some(n),
- }
- }
-}
-
-pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
- fallback: usize) -> usize {
- let value = lookup(module, symbol).unwrap_or(fallback);
- ptr.store(value, Ordering::SeqCst);
- value
-}
-
-macro_rules! compat_fn {
- ($module:ident: $(
- pub fn $symbol:ident($($argname:ident: $argtype:ty),*)
- -> $rettype:ty {
- $($body:expr);*
- }
- )*) => ($(
- #[allow(unused_variables)]
- pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
- use sync::atomic::{AtomicUsize, Ordering};
- use mem;
- type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
-
- static PTR: AtomicUsize = AtomicUsize::new(0);
-
- fn load() -> usize {
- ::sys::compat::store_func(&PTR,
- stringify!($module),
- stringify!($symbol),
- fallback as usize)
- }
- unsafe extern "system" fn fallback($($argname: $argtype),*)
- -> $rettype {
- $($body);*
- }
-
- let addr = match PTR.load(Ordering::SeqCst) {
- 0 => load(),
- n => n,
- };
- mem::transmute::<usize, F>(addr)($($argname),*)
- }
- )*)
-}
diff --git a/ctr-std/src/sys/windows/condvar.rs b/ctr-std/src/sys/windows/condvar.rs
deleted file mode 100644
index d708b32..0000000
--- a/ctr-std/src/sys/windows/condvar.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cell::UnsafeCell;
-use sys::c;
-use sys::mutex::{self, Mutex};
-use sys::os;
-use time::Duration;
-
-pub struct Condvar { inner: UnsafeCell<c::CONDITION_VARIABLE> }
-
-unsafe impl Send for Condvar {}
-unsafe impl Sync for Condvar {}
-
-impl Condvar {
- pub const fn new() -> Condvar {
- Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
- }
-
- #[inline]
- pub unsafe fn init(&mut self) {}
-
- #[inline]
- pub unsafe fn wait(&self, mutex: &Mutex) {
- let r = c::SleepConditionVariableSRW(self.inner.get(),
- mutex::raw(mutex),
- c::INFINITE,
- 0);
- debug_assert!(r != 0);
- }
-
- pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
- let r = c::SleepConditionVariableSRW(self.inner.get(),
- mutex::raw(mutex),
- super::dur2timeout(dur),
- 0);
- if r == 0 {
- debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
- false
- } else {
- true
- }
- }
-
- #[inline]
- pub unsafe fn notify_one(&self) {
- c::WakeConditionVariable(self.inner.get())
- }
-
- #[inline]
- pub unsafe fn notify_all(&self) {
- c::WakeAllConditionVariable(self.inner.get())
- }
-
- pub unsafe fn destroy(&self) {
- // ...
- }
-}
diff --git a/ctr-std/src/sys/windows/dynamic_lib.rs b/ctr-std/src/sys/windows/dynamic_lib.rs
deleted file mode 100644
index 5227280..0000000
--- a/ctr-std/src/sys/windows/dynamic_lib.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use os::windows::prelude::*;
-
-use ffi::{CString, OsStr};
-use io;
-use sys::c;
-
-pub struct DynamicLibrary {
- handle: c::HMODULE,
-}
-
-impl DynamicLibrary {
- pub fn open(filename: &str) -> io::Result<DynamicLibrary> {
- let filename = OsStr::new(filename)
- .encode_wide()
- .chain(Some(0))
- .collect::<Vec<_>>();
- let result = unsafe {
- c::LoadLibraryW(filename.as_ptr())
- };
- if result.is_null() {
- Err(io::Error::last_os_error())
- } else {
- Ok(DynamicLibrary { handle: result })
- }
- }
-
- pub fn symbol(&self, symbol: &str) -> io::Result<usize> {
- let symbol = CString::new(symbol)?;
- unsafe {
- match c::GetProcAddress(self.handle, symbol.as_ptr()) as usize {
- 0 => Err(io::Error::last_os_error()),
- n => Ok(n),
- }
- }
- }
-}
-
-impl Drop for DynamicLibrary {
- fn drop(&mut self) {
- unsafe {
- c::FreeLibrary(self.handle);
- }
- }
-}
diff --git a/ctr-std/src/sys/windows/env.rs b/ctr-std/src/sys/windows/env.rs
deleted file mode 100644
index e6d7489..0000000
--- a/ctr-std/src/sys/windows/env.rs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-pub mod os {
- pub const FAMILY: &'static str = "windows";
- pub const OS: &'static str = "windows";
- pub const DLL_PREFIX: &'static str = "";
- pub const DLL_SUFFIX: &'static str = ".dll";
- pub const DLL_EXTENSION: &'static str = "dll";
- pub const EXE_SUFFIX: &'static str = ".exe";
- pub const EXE_EXTENSION: &'static str = "exe";
-}
diff --git a/ctr-std/src/sys/windows/ext/ffi.rs b/ctr-std/src/sys/windows/ext/ffi.rs
deleted file mode 100644
index bae0d02..0000000
--- a/ctr-std/src/sys/windows/ext/ffi.rs
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Windows-specific extensions to the primitives in the `std::ffi` module.
-//!
-//! # Overview
-//!
-//! For historical reasons, the Windows API uses a form of potentially
-//! ill-formed UTF-16 encoding for strings. Specifically, the 16-bit
-//! code units in Windows strings may contain [isolated surrogate code
-//! points which are not paired together][ill-formed-utf-16]. The
-//! Unicode standard requires that surrogate code points (those in the
-//! range U+D800 to U+DFFF) always be *paired*, because in the UTF-16
-//! encoding a *surrogate code unit pair* is used to encode a single
-//! character. For compatibility with code that does not enforce
-//! these pairings, Windows does not enforce them, either.
-//!
-//! While it is not always possible to convert such a string losslessly into
-//! a valid UTF-16 string (or even UTF-8), it is often desirable to be
-//! able to round-trip such a string from and to Windows APIs
-//! losslessly. For example, some Rust code may be "bridging" some
-//! Windows APIs together, just passing `WCHAR` strings among those
-//! APIs without ever really looking into the strings.
-//!
-//! If Rust code *does* need to look into those strings, it can
-//! convert them to valid UTF-8, possibly lossily, by substituting
-//! invalid sequences with [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD], as is
-//! conventionally done in other Rust APIs that deal with string
-//! encodings.
-//!
-//! # `OsStringExt` and `OsStrExt`
-//!
-//! [`OsString`] is the Rust wrapper for owned strings in the
-//! preferred representation of the operating system. On Windows,
-//! this struct gets augmented with an implementation of the
-//! [`OsStringExt`] trait, which has a [`from_wide`] method. This
-//! lets you create an [`OsString`] from a `&[u16]` slice; presumably
-//! you get such a slice out of a `WCHAR` Windows API.
-//!
-//! Similarly, [`OsStr`] is the Rust wrapper for borrowed strings from
-//! preferred representation of the operating system. On Windows, the
-//! [`OsStrExt`] trait provides the [`encode_wide`] method, which
-//! outputs an [`EncodeWide`] iterator. You can [`collect`] this
-//! iterator, for example, to obtain a `Vec<u16>`; you can later get a
-//! pointer to this vector's contents and feed it to Windows APIs.
-//!
-//! These traits, along with [`OsString`] and [`OsStr`], work in
-//! conjunction so that it is possible to **round-trip** strings from
-//! Windows and back, with no loss of data, even if the strings are
-//! ill-formed UTF-16.
-//!
-//! [ill-formed-utf-16]: https://simonsapin.github.io/wtf-8/#ill-formed-utf-16
-//! [`OsString`]: ../../../ffi/struct.OsString.html
-//! [`OsStr`]: ../../../ffi/struct.OsStr.html
-//! [`OsStringExt`]: trait.OsStringExt.html
-//! [`OsStrExt`]: trait.OsStrExt.html
-//! [`EncodeWide`]: struct.EncodeWide.html
-//! [`from_wide`]: trait.OsStringExt.html#tymethod.from_wide
-//! [`encode_wide`]: trait.OsStrExt.html#tymethod.encode_wide
-//! [`collect`]: ../../../iter/trait.Iterator.html#method.collect
-//! [U+FFFD]: ../../../char/constant.REPLACEMENT_CHARACTER.html
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use ffi::{OsString, OsStr};
-use sys::os_str::Buf;
-use sys_common::wtf8::Wtf8Buf;
-use sys_common::{FromInner, AsInner};
-
-#[stable(feature = "rust1", since = "1.0.0")]
-pub use sys_common::wtf8::EncodeWide;
-
-/// Windows-specific extensions to [`OsString`].
-///
-/// [`OsString`]: ../../../../std/ffi/struct.OsString.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStringExt {
- /// Creates an `OsString` from a potentially ill-formed UTF-16 slice of
- /// 16-bit code units.
- ///
- /// This is lossless: calling [`encode_wide`] on the resulting string
- /// will always return the original code units.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::windows::prelude::*;
- ///
- /// // UTF-16 encoding for "Unicode".
- /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
- ///
- /// let string = OsString::from_wide(&source[..]);
- /// ```
- ///
- /// [`encode_wide`]: ./trait.OsStrExt.html#tymethod.encode_wide
- #[stable(feature = "rust1", since = "1.0.0")]
- fn from_wide(wide: &[u16]) -> Self;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStringExt for OsString {
- fn from_wide(wide: &[u16]) -> OsString {
- FromInner::from_inner(Buf { inner: Wtf8Buf::from_wide(wide) })
- }
-}
-
-/// Windows-specific extensions to [`OsStr`].
-///
-/// [`OsStr`]: ../../../../std/ffi/struct.OsStr.html
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait OsStrExt {
- /// Re-encodes an `OsStr` as a wide character sequence, i.e. potentially
- /// ill-formed UTF-16.
- ///
- /// This is lossless: calling [`OsString::from_wide`] and then
- /// `encode_wide` on the result will yield the original code units.
- /// Note that the encoding does not add a final null terminator.
- ///
- /// # Examples
- ///
- /// ```
- /// use std::ffi::OsString;
- /// use std::os::windows::prelude::*;
- ///
- /// // UTF-16 encoding for "Unicode".
- /// let source = [0x0055, 0x006E, 0x0069, 0x0063, 0x006F, 0x0064, 0x0065];
- ///
- /// let string = OsString::from_wide(&source[..]);
- ///
- /// let result: Vec<u16> = string.encode_wide().collect();
- /// assert_eq!(&source[..], &result[..]);
- /// ```
- ///
- /// [`OsString::from_wide`]: ./trait.OsStringExt.html#tymethod.from_wide
- #[stable(feature = "rust1", since = "1.0.0")]
- fn encode_wide(&self) -> EncodeWide;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl OsStrExt for OsStr {
- fn encode_wide(&self) -> EncodeWide {
- self.as_inner().inner.encode_wide()
- }
-}
diff --git a/ctr-std/src/sys/windows/ext/fs.rs b/ctr-std/src/sys/windows/ext/fs.rs
deleted file mode 100644
index 78c9e95..0000000
--- a/ctr-std/src/sys/windows/ext/fs.rs
+++ /dev/null
@@ -1,508 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Windows-specific extensions for the primitives in the `std::fs` module.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use fs::{self, OpenOptions, Metadata};
-use io;
-use path::Path;
-use sys;
-use sys_common::{AsInnerMut, AsInner};
-
-/// Windows-specific extensions to [`File`].
-///
-/// [`File`]: ../../../fs/struct.File.html
-#[stable(feature = "file_offset", since = "1.15.0")]
-pub trait FileExt {
- /// Seeks to a given position and reads a number of bytes.
- ///
- /// Returns the number of bytes read.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor. The current cursor **is** affected by this
- /// function, it is set to the end of the read.
- ///
- /// Reading beyond the end of the file will always return with a length of
- /// 0\.
- ///
- /// Note that similar to `File::read`, it is not an error to return with a
- /// short read. When returning from such a short read, the file pointer is
- /// still updated.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs::File;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let mut file = File::open("foo.txt")?;
- /// let mut buffer = [0; 10];
- ///
- /// // Read 10 bytes, starting 72 bytes from the
- /// // start of the file.
- /// file.seek_read(&mut buffer[..], 72)?;
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_offset", since = "1.15.0")]
- fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
-
- /// Seeks to a given position and writes a number of bytes.
- ///
- /// Returns the number of bytes written.
- ///
- /// The offset is relative to the start of the file and thus independent
- /// from the current cursor. The current cursor **is** affected by this
- /// function, it is set to the end of the write.
- ///
- /// When writing beyond the end of the file, the file is appropriately
- /// extended and the intermediate bytes are left uninitialized.
- ///
- /// Note that similar to `File::write`, it is not an error to return a
- /// short write. When returning from such a short write, the file pointer
- /// is still updated.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::File;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> std::io::Result<()> {
- /// let mut buffer = File::create("foo.txt")?;
- ///
- /// // Write a byte string starting 72 bytes from
- /// // the start of the file.
- /// buffer.seek_write(b"some bytes", 72)?;
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "file_offset", since = "1.15.0")]
- fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
-}
-
-#[stable(feature = "file_offset", since = "1.15.0")]
-impl FileExt for fs::File {
- fn seek_read(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- self.as_inner().read_at(buf, offset)
- }
-
- fn seek_write(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- self.as_inner().write_at(buf, offset)
- }
-}
-
-/// Windows-specific extensions to [`fs::OpenOptions`].
-///
-/// [`fs::OpenOptions`]: ../../../../std/fs/struct.OpenOptions.html
-#[stable(feature = "open_options_ext", since = "1.10.0")]
-pub trait OpenOptionsExt {
- /// Overrides the `dwDesiredAccess` argument to the call to [`CreateFile`]
- /// with the specified value.
- ///
- /// This will override the `read`, `write`, and `append` flags on the
- /// `OpenOptions` structure. This method provides fine-grained control over
- /// the permissions to read, write and append data, attributes (like hidden
- /// and system), and extended attributes.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::OpenOptions;
- /// use std::os::windows::prelude::*;
- ///
- /// // Open without read and write permission, for example if you only need
- /// // to call `stat` on the file
- /// let file = OpenOptions::new().access_mode(0).open("foo.txt");
- /// ```
- ///
- /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn access_mode(&mut self, access: u32) -> &mut Self;
-
- /// Overrides the `dwShareMode` argument to the call to [`CreateFile`] with
- /// the specified value.
- ///
- /// By default `share_mode` is set to
- /// `FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE`. This allows
- /// other processes to to read, write, and delete/rename the same file
- /// while it is open. Removing any of the flags will prevent other
- /// processes from performing the corresponding operation until the file
- /// handle is closed.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::OpenOptions;
- /// use std::os::windows::prelude::*;
- ///
- /// // Do not allow others to read or modify this file while we have it open
- /// // for writing.
- /// let file = OpenOptions::new()
- /// .write(true)
- /// .share_mode(0)
- /// .open("foo.txt");
- /// ```
- ///
- /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn share_mode(&mut self, val: u32) -> &mut Self;
-
- /// Sets extra flags for the `dwFileFlags` argument to the call to
- /// [`CreateFile2`] to the specified value (or combines it with
- /// `attributes` and `security_qos_flags` to set the `dwFlagsAndAttributes`
- /// for [`CreateFile`]).
- ///
- /// Custom flags can only set flags, not remove flags set by Rust's options.
- /// This option overwrites any previously set custom flags.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// # #[cfg(for_demonstration_only)]
- /// extern crate winapi;
- /// # mod winapi { pub const FILE_FLAG_DELETE_ON_CLOSE: u32 = 0x04000000; }
- ///
- /// use std::fs::OpenOptions;
- /// use std::os::windows::prelude::*;
- ///
- /// let file = OpenOptions::new()
- /// .create(true)
- /// .write(true)
- /// .custom_flags(winapi::FILE_FLAG_DELETE_ON_CLOSE)
- /// .open("foo.txt");
- /// ```
- ///
- /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
- /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn custom_flags(&mut self, flags: u32) -> &mut Self;
-
- /// Sets the `dwFileAttributes` argument to the call to [`CreateFile2`] to
- /// the specified value (or combines it with `custom_flags` and
- /// `security_qos_flags` to set the `dwFlagsAndAttributes` for
- /// [`CreateFile`]).
- ///
- /// If a _new_ file is created because it does not yet exist and
- /// `.create(true)` or `.create_new(true)` are specified, the new file is
- /// given the attributes declared with `.attributes()`.
- ///
- /// If an _existing_ file is opened with `.create(true).truncate(true)`, its
- /// existing attributes are preserved and combined with the ones declared
- /// with `.attributes()`.
- ///
- /// In all other cases the attributes get ignored.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// # #[cfg(for_demonstration_only)]
- /// extern crate winapi;
- /// # mod winapi { pub const FILE_ATTRIBUTE_HIDDEN: u32 = 2; }
- ///
- /// use std::fs::OpenOptions;
- /// use std::os::windows::prelude::*;
- ///
- /// let file = OpenOptions::new()
- /// .write(true)
- /// .create(true)
- /// .attributes(winapi::FILE_ATTRIBUTE_HIDDEN)
- /// .open("foo.txt");
- /// ```
- ///
- /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
- /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn attributes(&mut self, val: u32) -> &mut Self;
-
- /// Sets the `dwSecurityQosFlags` argument to the call to [`CreateFile2`] to
- /// the specified value (or combines it with `custom_flags` and `attributes`
- /// to set the `dwFlagsAndAttributes` for [`CreateFile`]).
- ///
- /// By default, `security_qos_flags` is set to `SECURITY_ANONYMOUS`. For
- /// information about possible values, see [Impersonation Levels] on the
- /// Windows Dev Center site.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::fs::OpenOptions;
- /// use std::os::windows::prelude::*;
- ///
- /// let file = OpenOptions::new()
- /// .write(true)
- /// .create(true)
- ///
- /// // Sets the flag value to `SecurityIdentification`.
- /// .security_qos_flags(1)
- ///
- /// .open("foo.txt");
- /// ```
- ///
- /// [`CreateFile`]: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363858.aspx
- /// [`CreateFile2`]: https://msdn.microsoft.com/en-us/library/windows/desktop/hh449422.aspx
- /// [Impersonation Levels]:
- /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa379572.aspx
- #[stable(feature = "open_options_ext", since = "1.10.0")]
- fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions;
-}
-
-#[stable(feature = "open_options_ext", since = "1.10.0")]
-impl OpenOptionsExt for OpenOptions {
- fn access_mode(&mut self, access: u32) -> &mut OpenOptions {
- self.as_inner_mut().access_mode(access); self
- }
-
- fn share_mode(&mut self, share: u32) -> &mut OpenOptions {
- self.as_inner_mut().share_mode(share); self
- }
-
- fn custom_flags(&mut self, flags: u32) -> &mut OpenOptions {
- self.as_inner_mut().custom_flags(flags); self
- }
-
- fn attributes(&mut self, attributes: u32) -> &mut OpenOptions {
- self.as_inner_mut().attributes(attributes); self
- }
-
- fn security_qos_flags(&mut self, flags: u32) -> &mut OpenOptions {
- self.as_inner_mut().security_qos_flags(flags); self
- }
-}
-
-/// Windows-specific extensions to [`fs::Metadata`].
-///
-/// The data members that this trait exposes correspond to the members
-/// of the [`BY_HANDLE_FILE_INFORMATION`] structure.
-///
-/// [`fs::Metadata`]: ../../../../std/fs/struct.Metadata.html
-/// [`BY_HANDLE_FILE_INFORMATION`]:
-/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363788.aspx
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-pub trait MetadataExt {
- /// Returns the value of the `dwFileAttributes` field of this metadata.
- ///
- /// This field contains the file system attribute information for a file
- /// or directory. For possible values and their descriptions, see
- /// [File Attribute Constants] in the Windows Dev Center.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let metadata = fs::metadata("foo.txt")?;
- /// let attributes = metadata.file_attributes();
- /// Ok(())
- /// }
- /// ```
- ///
- /// [File Attribute Constants]:
- /// https://msdn.microsoft.com/en-us/library/windows/desktop/gg258117.aspx
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn file_attributes(&self) -> u32;
-
- /// Returns the value of the `ftCreationTime` field of this metadata.
- ///
- /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
- /// which represents the number of 100-nanosecond intervals since
- /// January 1, 1601 (UTC). The struct is automatically
- /// converted to a `u64` value, as that is the recommended way
- /// to use it.
- ///
- /// If the underlying filesystem does not support creation time, the
- /// returned value is 0.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let metadata = fs::metadata("foo.txt")?;
- /// let creation_time = metadata.creation_time();
- /// Ok(())
- /// }
- /// ```
- ///
- /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn creation_time(&self) -> u64;
-
- /// Returns the value of the `ftLastAccessTime` field of this metadata.
- ///
- /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
- /// which represents the number of 100-nanosecond intervals since
- /// January 1, 1601 (UTC). The struct is automatically
- /// converted to a `u64` value, as that is the recommended way
- /// to use it.
- ///
- /// For a file, the value specifies the last time that a file was read
- /// from or written to. For a directory, the value specifies when
- /// the directory was created. For both files and directories, the
- /// specified date is correct, but the time of day is always set to
- /// midnight.
- ///
- /// If the underlying filesystem does not support last access time, the
- /// returned value is 0.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let metadata = fs::metadata("foo.txt")?;
- /// let last_access_time = metadata.last_access_time();
- /// Ok(())
- /// }
- /// ```
- ///
- /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn last_access_time(&self) -> u64;
-
- /// Returns the value of the `ftLastWriteTime` field of this metadata.
- ///
- /// The returned 64-bit value is equivalent to a [`FILETIME`] struct,
- /// which represents the number of 100-nanosecond intervals since
- /// January 1, 1601 (UTC). The struct is automatically
- /// converted to a `u64` value, as that is the recommended way
- /// to use it.
- ///
- /// For a file, the value specifies the last time that a file was written
- /// to. For a directory, the structure specifies when the directory was
- /// created.
- ///
- /// If the underlying filesystem does not support the last write time,
- /// the returned value is 0.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let metadata = fs::metadata("foo.txt")?;
- /// let last_write_time = metadata.last_write_time();
- /// Ok(())
- /// }
- /// ```
- ///
- /// [`FILETIME`]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn last_write_time(&self) -> u64;
-
- /// Returns the value of the `nFileSize{High,Low}` fields of this
- /// metadata.
- ///
- /// The returned value does not have meaning for directories.
- ///
- /// # Examples
- ///
- /// ```no_run
- /// use std::io;
- /// use std::fs;
- /// use std::os::windows::prelude::*;
- ///
- /// fn main() -> io::Result<()> {
- /// let metadata = fs::metadata("foo.txt")?;
- /// let file_size = metadata.file_size();
- /// Ok(())
- /// }
- /// ```
- #[stable(feature = "metadata_ext", since = "1.1.0")]
- fn file_size(&self) -> u64;
-}
-
-#[stable(feature = "metadata_ext", since = "1.1.0")]
-impl MetadataExt for Metadata {
- fn file_attributes(&self) -> u32 { self.as_inner().attrs() }
- fn creation_time(&self) -> u64 { self.as_inner().created_u64() }
- fn last_access_time(&self) -> u64 { self.as_inner().accessed_u64() }
- fn last_write_time(&self) -> u64 { self.as_inner().modified_u64() }
- fn file_size(&self) -> u64 { self.as_inner().size() }
-}
-
-/// Windows-specific extensions to [`FileType`].
-///
-/// On Windows, a symbolic link knows whether it is a file or directory.
-///
-/// [`FileType`]: ../../../../std/fs/struct.FileType.html
-#[unstable(feature = "windows_file_type_ext", issue = "0")]
-pub trait FileTypeExt {
- /// Returns whether this file type is a symbolic link that is also a directory.
- #[unstable(feature = "windows_file_type_ext", issue = "0")]
- fn is_symlink_dir(&self) -> bool;
- /// Returns whether this file type is a symbolic link that is also a file.
- #[unstable(feature = "windows_file_type_ext", issue = "0")]
- fn is_symlink_file(&self) -> bool;
-}
-
-#[unstable(feature = "windows_file_type_ext", issue = "0")]
-impl FileTypeExt for fs::FileType {
- fn is_symlink_dir(&self) -> bool { self.as_inner().is_symlink_dir() }
- fn is_symlink_file(&self) -> bool { self.as_inner().is_symlink_file() }
-}
-
-/// Creates a new file symbolic link on the filesystem.
-///
-/// The `dst` path will be a file symbolic link pointing to the `src`
-/// path.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::windows::fs;
-///
-/// fn main() -> std::io::Result<()> {
-/// fs::symlink_file("a.txt", "b.txt")?;
-/// Ok(())
-/// }
-/// ```
-#[stable(feature = "symlink", since = "1.1.0")]
-pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
- -> io::Result<()> {
- sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), false)
-}
-
-/// Creates a new directory symlink on the filesystem.
-///
-/// The `dst` path will be a directory symbolic link pointing to the `src`
-/// path.
-///
-/// # Examples
-///
-/// ```no_run
-/// use std::os::windows::fs;
-///
-/// fn main() -> std::io::Result<()> {
-/// fs::symlink_dir("a", "b")?;
-/// Ok(())
-/// }
-/// ```
-#[stable(feature = "symlink", since = "1.1.0")]
-pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q)
- -> io::Result<()> {
- sys::fs::symlink_inner(src.as_ref(), dst.as_ref(), true)
-}
diff --git a/ctr-std/src/sys/windows/ext/io.rs b/ctr-std/src/sys/windows/ext/io.rs
deleted file mode 100644
index 90128dd..0000000
--- a/ctr-std/src/sys/windows/ext/io.rs
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-
-use fs;
-use os::windows::raw;
-use net;
-use sys_common::{self, AsInner, FromInner, IntoInner};
-use sys;
-use io;
-use sys::c;
-
-/// Raw HANDLEs.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type RawHandle = raw::HANDLE;
-
-/// Raw SOCKETs.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type RawSocket = raw::SOCKET;
-
-/// Extract raw handles.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait AsRawHandle {
- /// Extracts the raw handle, without taking any ownership.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_handle(&self) -> RawHandle;
-}
-
-/// Construct I/O objects from raw handles.
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-pub trait FromRawHandle {
- /// Constructs a new I/O object from the specified raw handle.
- ///
- /// This function will **consume ownership** of the handle given,
- /// passing responsibility for closing the handle to the returned
- /// object.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- #[stable(feature = "from_raw_os", since = "1.1.0")]
- unsafe fn from_raw_handle(handle: RawHandle) -> Self;
-}
-
-/// A trait to express the ability to consume an object and acquire ownership of
-/// its raw `HANDLE`.
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-pub trait IntoRawHandle {
- /// Consumes this object, returning the raw underlying handle.
- ///
- /// This function **transfers ownership** of the underlying handle to the
- /// caller. Callers are then the unique owners of the handle and must close
- /// it once it's no longer needed.
- #[stable(feature = "into_raw_os", since = "1.4.0")]
- fn into_raw_handle(self) -> RawHandle;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawHandle for fs::File {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as RawHandle
- }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawHandle for io::Stdin {
- fn as_raw_handle(&self) -> RawHandle {
- unsafe { c::GetStdHandle(c::STD_INPUT_HANDLE) as RawHandle }
- }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawHandle for io::Stdout {
- fn as_raw_handle(&self) -> RawHandle {
- unsafe { c::GetStdHandle(c::STD_OUTPUT_HANDLE) as RawHandle }
- }
-}
-
-#[stable(feature = "asraw_stdio", since = "1.21.0")]
-impl AsRawHandle for io::Stderr {
- fn as_raw_handle(&self) -> RawHandle {
- unsafe { c::GetStdHandle(c::STD_ERROR_HANDLE) as RawHandle }
- }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawHandle for fs::File {
- unsafe fn from_raw_handle(handle: RawHandle) -> fs::File {
- let handle = handle as c::HANDLE;
- fs::File::from_inner(sys::fs::File::from_inner(handle))
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawHandle for fs::File {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
-
-/// Extract raw sockets.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub trait AsRawSocket {
- /// Extracts the underlying raw socket from this object.
- #[stable(feature = "rust1", since = "1.0.0")]
- fn as_raw_socket(&self) -> RawSocket;
-}
-
-/// Create I/O objects from raw sockets.
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-pub trait FromRawSocket {
- /// Creates a new I/O object from the given raw socket.
- ///
- /// This function will **consume ownership** of the socket provided and
- /// it will be closed when the returned object goes out of scope.
- ///
- /// This function is also unsafe as the primitives currently returned
- /// have the contract that they are the sole owner of the file
- /// descriptor they are wrapping. Usage of this function could
- /// accidentally allow violating this contract which can cause memory
- /// unsafety in code that relies on it being true.
- #[stable(feature = "from_raw_os", since = "1.1.0")]
- unsafe fn from_raw_socket(sock: RawSocket) -> Self;
-}
-
-/// A trait to express the ability to consume an object and acquire ownership of
-/// its raw `SOCKET`.
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-pub trait IntoRawSocket {
- /// Consumes this object, returning the raw underlying socket.
- ///
- /// This function **transfers ownership** of the underlying socket to the
- /// caller. Callers are then the unique owners of the socket and must close
- /// it once it's no longer needed.
- #[stable(feature = "into_raw_os", since = "1.4.0")]
- fn into_raw_socket(self) -> RawSocket;
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawSocket for net::TcpStream {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawSocket for net::TcpListener {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
-}
-#[stable(feature = "rust1", since = "1.0.0")]
-impl AsRawSocket for net::UdpSocket {
- fn as_raw_socket(&self) -> RawSocket {
- *self.as_inner().socket().as_inner()
- }
-}
-
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawSocket for net::TcpStream {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream {
- let sock = sys::net::Socket::from_inner(sock);
- net::TcpStream::from_inner(sys_common::net::TcpStream::from_inner(sock))
- }
-}
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawSocket for net::TcpListener {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener {
- let sock = sys::net::Socket::from_inner(sock);
- net::TcpListener::from_inner(sys_common::net::TcpListener::from_inner(sock))
- }
-}
-#[stable(feature = "from_raw_os", since = "1.1.0")]
-impl FromRawSocket for net::UdpSocket {
- unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket {
- let sock = sys::net::Socket::from_inner(sock);
- net::UdpSocket::from_inner(sys_common::net::UdpSocket::from_inner(sock))
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawSocket for net::TcpStream {
- fn into_raw_socket(self) -> RawSocket {
- self.into_inner().into_socket().into_inner()
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawSocket for net::TcpListener {
- fn into_raw_socket(self) -> RawSocket {
- self.into_inner().into_socket().into_inner()
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawSocket for net::UdpSocket {
- fn into_raw_socket(self) -> RawSocket {
- self.into_inner().into_socket().into_inner()
- }
-}
diff --git a/ctr-std/src/sys/windows/ext/mod.rs b/ctr-std/src/sys/windows/ext/mod.rs
deleted file mode 100644
index 1f10609..0000000
--- a/ctr-std/src/sys/windows/ext/mod.rs
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Platform-specific extensions to `std` for Windows.
-//!
-//! Provides access to platform-level information for Windows, and exposes
-//! Windows-specific idioms that would otherwise be inappropriate as part
-//! the core `std` library. These extensions allow developers to use
-//! `std` types and idioms with Windows in a way that the normal
-//! platform-agnostic idioms would not normally support.
-
-#![stable(feature = "rust1", since = "1.0.0")]
-#![doc(cfg(windows))]
-#![allow(missing_docs)]
-
-pub mod ffi;
-pub mod fs;
-pub mod io;
-pub mod raw;
-pub mod process;
-pub mod thread;
-
-/// A prelude for conveniently writing platform-specific code.
-///
-/// Includes all extension traits, and some important type definitions.
-#[stable(feature = "rust1", since = "1.0.0")]
-pub mod prelude {
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::io::{RawSocket, RawHandle, AsRawSocket, AsRawHandle};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::io::{FromRawSocket, FromRawHandle, IntoRawSocket, IntoRawHandle};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::ffi::{OsStrExt, OsStringExt};
- #[doc(no_inline)] #[stable(feature = "rust1", since = "1.0.0")]
- pub use super::fs::{OpenOptionsExt, MetadataExt};
- #[doc(no_inline)] #[stable(feature = "file_offset", since = "1.15.0")]
- pub use super::fs::FileExt;
-}
diff --git a/ctr-std/src/sys/windows/ext/process.rs b/ctr-std/src/sys/windows/ext/process.rs
deleted file mode 100644
index a02bcbe..0000000
--- a/ctr-std/src/sys/windows/ext/process.rs
+++ /dev/null
@@ -1,123 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Extensions to `std::process` for Windows.
-
-#![stable(feature = "process_extensions", since = "1.2.0")]
-
-use os::windows::io::{FromRawHandle, RawHandle, AsRawHandle, IntoRawHandle};
-use process;
-use sys;
-use sys_common::{AsInnerMut, AsInner, FromInner, IntoInner};
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl FromRawHandle for process::Stdio {
- unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio {
- let handle = sys::handle::Handle::new(handle as *mut _);
- let io = sys::process::Stdio::Handle(handle);
- process::Stdio::from_inner(io)
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawHandle for process::Child {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as *mut _
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawHandle for process::Child {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawHandle for process::ChildStdin {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as *mut _
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawHandle for process::ChildStdout {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as *mut _
- }
-}
-
-#[stable(feature = "process_extensions", since = "1.2.0")]
-impl AsRawHandle for process::ChildStderr {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as *mut _
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawHandle for process::ChildStdin {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawHandle for process::ChildStdout {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
-
-#[stable(feature = "into_raw_os", since = "1.4.0")]
-impl IntoRawHandle for process::ChildStderr {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
-
-/// Windows-specific extensions to [`process::ExitStatus`].
-///
-/// [`process::ExitStatus`]: ../../../../std/process/struct.ExitStatus.html
-#[stable(feature = "exit_status_from", since = "1.12.0")]
-pub trait ExitStatusExt {
- /// Creates a new `ExitStatus` from the raw underlying `u32` return value of
- /// a process.
- #[stable(feature = "exit_status_from", since = "1.12.0")]
- fn from_raw(raw: u32) -> Self;
-}
-
-#[stable(feature = "exit_status_from", since = "1.12.0")]
-impl ExitStatusExt for process::ExitStatus {
- fn from_raw(raw: u32) -> Self {
- process::ExitStatus::from_inner(From::from(raw))
- }
-}
-
-/// Windows-specific extensions to the [`process::Command`] builder.
-///
-/// [`process::Command`]: ../../../../std/process/struct.Command.html
-#[stable(feature = "windows_process_extensions", since = "1.16.0")]
-pub trait CommandExt {
- /// Sets the [process creation flags][1] to be passed to `CreateProcess`.
- ///
- /// These will always be ORed with `CREATE_UNICODE_ENVIRONMENT`.
- ///
- /// [1]: https://msdn.microsoft.com/en-us/library/windows/desktop/ms684863(v=vs.85).aspx
- #[stable(feature = "windows_process_extensions", since = "1.16.0")]
- fn creation_flags(&mut self, flags: u32) -> &mut process::Command;
-}
-
-#[stable(feature = "windows_process_extensions", since = "1.16.0")]
-impl CommandExt for process::Command {
- fn creation_flags(&mut self, flags: u32) -> &mut process::Command {
- self.as_inner_mut().creation_flags(flags);
- self
- }
-}
diff --git a/ctr-std/src/sys/windows/ext/raw.rs b/ctr-std/src/sys/windows/ext/raw.rs
deleted file mode 100644
index 92d53e2..0000000
--- a/ctr-std/src/sys/windows/ext/raw.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Windows-specific primitives
-
-#![stable(feature = "raw_ext", since = "1.1.0")]
-
-use os::raw::c_void;
-
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type HANDLE = *mut c_void;
-#[cfg(target_pointer_width = "32")]
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type SOCKET = u32;
-#[cfg(target_pointer_width = "64")]
-#[stable(feature = "raw_ext", since = "1.1.0")] pub type SOCKET = u64;
diff --git a/ctr-std/src/sys/windows/ext/thread.rs b/ctr-std/src/sys/windows/ext/thread.rs
deleted file mode 100644
index 36b3a3d..0000000
--- a/ctr-std/src/sys/windows/ext/thread.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Extensions to `std::thread` for Windows.
-
-#![stable(feature = "thread_extensions", since = "1.9.0")]
-
-use os::windows::io::{RawHandle, AsRawHandle, IntoRawHandle};
-use thread;
-use sys_common::{AsInner, IntoInner};
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-impl<T> AsRawHandle for thread::JoinHandle<T> {
- fn as_raw_handle(&self) -> RawHandle {
- self.as_inner().handle().raw() as *mut _
- }
-}
-
-#[stable(feature = "thread_extensions", since = "1.9.0")]
-impl<T> IntoRawHandle for thread::JoinHandle<T> {
- fn into_raw_handle(self) -> RawHandle {
- self.into_inner().into_handle().into_raw() as *mut _
- }
-}
diff --git a/ctr-std/src/sys/windows/fast_thread_local.rs b/ctr-std/src/sys/windows/fast_thread_local.rs
deleted file mode 100644
index 9fee9bd..0000000
--- a/ctr-std/src/sys/windows/fast_thread_local.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "thread_local_internals", issue = "0")]
-#![cfg(target_thread_local)]
-
-pub use sys_common::thread_local::register_dtor_fallback as register_dtor;
-
-pub fn requires_move_before_drop() -> bool {
- false
-}
diff --git a/ctr-std/src/sys/windows/fs.rs b/ctr-std/src/sys/windows/fs.rs
deleted file mode 100644
index 082d468..0000000
--- a/ctr-std/src/sys/windows/fs.rs
+++ /dev/null
@@ -1,804 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use os::windows::prelude::*;
-
-use ffi::OsString;
-use fmt;
-use io::{self, Error, SeekFrom};
-use mem;
-use path::{Path, PathBuf};
-use ptr;
-use slice;
-use sync::Arc;
-use sys::handle::Handle;
-use sys::time::SystemTime;
-use sys::{c, cvt};
-use sys_common::FromInner;
-
-use super::to_u16s;
-
-pub struct File { handle: Handle }
-
-#[derive(Clone)]
-pub struct FileAttr {
- attributes: c::DWORD,
- creation_time: c::FILETIME,
- last_access_time: c::FILETIME,
- last_write_time: c::FILETIME,
- file_size: u64,
- reparse_tag: c::DWORD,
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
-pub struct FileType {
- attributes: c::DWORD,
- reparse_tag: c::DWORD,
-}
-
-pub struct ReadDir {
- handle: FindNextFileHandle,
- root: Arc<PathBuf>,
- first: Option<c::WIN32_FIND_DATAW>,
-}
-
-struct FindNextFileHandle(c::HANDLE);
-
-unsafe impl Send for FindNextFileHandle {}
-unsafe impl Sync for FindNextFileHandle {}
-
-pub struct DirEntry {
- root: Arc<PathBuf>,
- data: c::WIN32_FIND_DATAW,
-}
-
-#[derive(Clone, Debug)]
-pub struct OpenOptions {
- // generic
- read: bool,
- write: bool,
- append: bool,
- truncate: bool,
- create: bool,
- create_new: bool,
- // system-specific
- custom_flags: u32,
- access_mode: Option<c::DWORD>,
- attributes: c::DWORD,
- share_mode: c::DWORD,
- security_qos_flags: c::DWORD,
- security_attributes: usize, // FIXME: should be a reference
-}
-
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct FilePermissions { attrs: c::DWORD }
-
-#[derive(Debug)]
-pub struct DirBuilder;
-
-impl fmt::Debug for ReadDir {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // This will only be called from std::fs::ReadDir, which will add a "ReadDir()" frame.
- // Thus the result will be e g 'ReadDir("C:\")'
- fmt::Debug::fmt(&*self.root, f)
- }
-}
-
-impl Iterator for ReadDir {
- type Item = io::Result<DirEntry>;
- fn next(&mut self) -> Option<io::Result<DirEntry>> {
- if let Some(first) = self.first.take() {
- if let Some(e) = DirEntry::new(&self.root, &first) {
- return Some(Ok(e));
- }
- }
- unsafe {
- let mut wfd = mem::zeroed();
- loop {
- if c::FindNextFileW(self.handle.0, &mut wfd) == 0 {
- if c::GetLastError() == c::ERROR_NO_MORE_FILES {
- return None
- } else {
- return Some(Err(Error::last_os_error()))
- }
- }
- if let Some(e) = DirEntry::new(&self.root, &wfd) {
- return Some(Ok(e))
- }
- }
- }
- }
-}
-
-impl Drop for FindNextFileHandle {
- fn drop(&mut self) {
- let r = unsafe { c::FindClose(self.0) };
- debug_assert!(r != 0);
- }
-}
-
-impl DirEntry {
- fn new(root: &Arc<PathBuf>, wfd: &c::WIN32_FIND_DATAW) -> Option<DirEntry> {
- match &wfd.cFileName[0..3] {
- // check for '.' and '..'
- &[46, 0, ..] |
- &[46, 46, 0, ..] => return None,
- _ => {}
- }
-
- Some(DirEntry {
- root: root.clone(),
- data: *wfd,
- })
- }
-
- pub fn path(&self) -> PathBuf {
- self.root.join(&self.file_name())
- }
-
- pub fn file_name(&self) -> OsString {
- let filename = super::truncate_utf16_at_nul(&self.data.cFileName);
- OsString::from_wide(filename)
- }
-
- pub fn file_type(&self) -> io::Result<FileType> {
- Ok(FileType::new(self.data.dwFileAttributes,
- /* reparse_tag = */ self.data.dwReserved0))
- }
-
- pub fn metadata(&self) -> io::Result<FileAttr> {
- Ok(FileAttr {
- attributes: self.data.dwFileAttributes,
- creation_time: self.data.ftCreationTime,
- last_access_time: self.data.ftLastAccessTime,
- last_write_time: self.data.ftLastWriteTime,
- file_size: ((self.data.nFileSizeHigh as u64) << 32) | (self.data.nFileSizeLow as u64),
- reparse_tag: if self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
- // reserved unless this is a reparse point
- self.data.dwReserved0
- } else {
- 0
- },
- })
- }
-}
-
-impl OpenOptions {
- pub fn new() -> OpenOptions {
- OpenOptions {
- // generic
- read: false,
- write: false,
- append: false,
- truncate: false,
- create: false,
- create_new: false,
- // system-specific
- custom_flags: 0,
- access_mode: None,
- share_mode: c::FILE_SHARE_READ | c::FILE_SHARE_WRITE | c::FILE_SHARE_DELETE,
- attributes: 0,
- security_qos_flags: 0,
- security_attributes: 0,
- }
- }
-
- pub fn read(&mut self, read: bool) { self.read = read; }
- pub fn write(&mut self, write: bool) { self.write = write; }
- pub fn append(&mut self, append: bool) { self.append = append; }
- pub fn truncate(&mut self, truncate: bool) { self.truncate = truncate; }
- pub fn create(&mut self, create: bool) { self.create = create; }
- pub fn create_new(&mut self, create_new: bool) { self.create_new = create_new; }
-
- pub fn custom_flags(&mut self, flags: u32) { self.custom_flags = flags; }
- pub fn access_mode(&mut self, access_mode: u32) { self.access_mode = Some(access_mode); }
- pub fn share_mode(&mut self, share_mode: u32) { self.share_mode = share_mode; }
- pub fn attributes(&mut self, attrs: u32) { self.attributes = attrs; }
- pub fn security_qos_flags(&mut self, flags: u32) { self.security_qos_flags = flags; }
- pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
- self.security_attributes = attrs as usize;
- }
-
- fn get_access_mode(&self) -> io::Result<c::DWORD> {
- const ERROR_INVALID_PARAMETER: i32 = 87;
-
- match (self.read, self.write, self.append, self.access_mode) {
- (.., Some(mode)) => Ok(mode),
- (true, false, false, None) => Ok(c::GENERIC_READ),
- (false, true, false, None) => Ok(c::GENERIC_WRITE),
- (true, true, false, None) => Ok(c::GENERIC_READ | c::GENERIC_WRITE),
- (false, _, true, None) => Ok(c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA),
- (true, _, true, None) => Ok(c::GENERIC_READ |
- (c::FILE_GENERIC_WRITE & !c::FILE_WRITE_DATA)),
- (false, false, false, None) => Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER)),
- }
- }
-
- fn get_creation_mode(&self) -> io::Result<c::DWORD> {
- const ERROR_INVALID_PARAMETER: i32 = 87;
-
- match (self.write, self.append) {
- (true, false) => {}
- (false, false) =>
- if self.truncate || self.create || self.create_new {
- return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER));
- },
- (_, true) =>
- if self.truncate && !self.create_new {
- return Err(Error::from_raw_os_error(ERROR_INVALID_PARAMETER));
- },
- }
-
- Ok(match (self.create, self.truncate, self.create_new) {
- (false, false, false) => c::OPEN_EXISTING,
- (true, false, false) => c::OPEN_ALWAYS,
- (false, true, false) => c::TRUNCATE_EXISTING,
- (true, true, false) => c::CREATE_ALWAYS,
- (_, _, true) => c::CREATE_NEW,
- })
- }
-
- fn get_flags_and_attributes(&self) -> c::DWORD {
- self.custom_flags |
- self.attributes |
- self.security_qos_flags |
- if self.security_qos_flags != 0 { c::SECURITY_SQOS_PRESENT } else { 0 } |
- if self.create_new { c::FILE_FLAG_OPEN_REPARSE_POINT } else { 0 }
- }
-}
-
-impl File {
- pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
- let path = to_u16s(path)?;
- let handle = unsafe {
- c::CreateFileW(path.as_ptr(),
- opts.get_access_mode()?,
- opts.share_mode,
- opts.security_attributes as *mut _,
- opts.get_creation_mode()?,
- opts.get_flags_and_attributes(),
- ptr::null_mut())
- };
- if handle == c::INVALID_HANDLE_VALUE {
- Err(Error::last_os_error())
- } else {
- Ok(File { handle: Handle::new(handle) })
- }
- }
-
- pub fn fsync(&self) -> io::Result<()> {
- cvt(unsafe { c::FlushFileBuffers(self.handle.raw()) })?;
- Ok(())
- }
-
- pub fn datasync(&self) -> io::Result<()> { self.fsync() }
-
- pub fn truncate(&self, size: u64) -> io::Result<()> {
- let mut info = c::FILE_END_OF_FILE_INFO {
- EndOfFile: size as c::LARGE_INTEGER,
- };
- let size = mem::size_of_val(&info);
- cvt(unsafe {
- c::SetFileInformationByHandle(self.handle.raw(),
- c::FileEndOfFileInfo,
- &mut info as *mut _ as *mut _,
- size as c::DWORD)
- })?;
- Ok(())
- }
-
- pub fn file_attr(&self) -> io::Result<FileAttr> {
- unsafe {
- let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed();
- cvt(c::GetFileInformationByHandle(self.handle.raw(),
- &mut info))?;
- let mut attr = FileAttr {
- attributes: info.dwFileAttributes,
- creation_time: info.ftCreationTime,
- last_access_time: info.ftLastAccessTime,
- last_write_time: info.ftLastWriteTime,
- file_size: ((info.nFileSizeHigh as u64) << 32) | (info.nFileSizeLow as u64),
- reparse_tag: 0,
- };
- if attr.is_reparse_point() {
- let mut b = [0; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- if let Ok((_, buf)) = self.reparse_point(&mut b) {
- attr.reparse_tag = buf.ReparseTag;
- }
- }
- Ok(attr)
- }
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.handle.read(buf)
- }
-
- pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- self.handle.read_at(buf, offset)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- self.handle.write(buf)
- }
-
- pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- self.handle.write_at(buf, offset)
- }
-
- pub fn flush(&self) -> io::Result<()> { Ok(()) }
-
- pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
- let (whence, pos) = match pos {
- // Casting to `i64` is fine, `SetFilePointerEx` reinterprets this
- // integer as `u64`.
- SeekFrom::Start(n) => (c::FILE_BEGIN, n as i64),
- SeekFrom::End(n) => (c::FILE_END, n),
- SeekFrom::Current(n) => (c::FILE_CURRENT, n),
- };
- let pos = pos as c::LARGE_INTEGER;
- let mut newpos = 0;
- cvt(unsafe {
- c::SetFilePointerEx(self.handle.raw(), pos,
- &mut newpos, whence)
- })?;
- Ok(newpos as u64)
- }
-
- pub fn duplicate(&self) -> io::Result<File> {
- Ok(File {
- handle: self.handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)?,
- })
- }
-
- pub fn handle(&self) -> &Handle { &self.handle }
-
- pub fn into_handle(self) -> Handle { self.handle }
-
- fn reparse_point<'a>(&self,
- space: &'a mut [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE])
- -> io::Result<(c::DWORD, &'a c::REPARSE_DATA_BUFFER)> {
- unsafe {
- let mut bytes = 0;
- cvt({
- c::DeviceIoControl(self.handle.raw(),
- c::FSCTL_GET_REPARSE_POINT,
- ptr::null_mut(),
- 0,
- space.as_mut_ptr() as *mut _,
- space.len() as c::DWORD,
- &mut bytes,
- ptr::null_mut())
- })?;
- Ok((bytes, &*(space.as_ptr() as *const c::REPARSE_DATA_BUFFER)))
- }
- }
-
- fn readlink(&self) -> io::Result<PathBuf> {
- let mut space = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- let (_bytes, buf) = self.reparse_point(&mut space)?;
- unsafe {
- let (path_buffer, subst_off, subst_len, relative) = match buf.ReparseTag {
- c::IO_REPARSE_TAG_SYMLINK => {
- let info: *const c::SYMBOLIC_LINK_REPARSE_BUFFER =
- &buf.rest as *const _ as *const _;
- (&(*info).PathBuffer as *const _ as *const u16,
- (*info).SubstituteNameOffset / 2,
- (*info).SubstituteNameLength / 2,
- (*info).Flags & c::SYMLINK_FLAG_RELATIVE != 0)
- },
- c::IO_REPARSE_TAG_MOUNT_POINT => {
- let info: *const c::MOUNT_POINT_REPARSE_BUFFER =
- &buf.rest as *const _ as *const _;
- (&(*info).PathBuffer as *const _ as *const u16,
- (*info).SubstituteNameOffset / 2,
- (*info).SubstituteNameLength / 2,
- false)
- },
- _ => return Err(io::Error::new(io::ErrorKind::Other,
- "Unsupported reparse point type"))
- };
- let subst_ptr = path_buffer.offset(subst_off as isize);
- let mut subst = slice::from_raw_parts(subst_ptr, subst_len as usize);
- // Absolute paths start with an NT internal namespace prefix `\??\`
- // We should not let it leak through.
- if !relative && subst.starts_with(&[92u16, 63u16, 63u16, 92u16]) {
- subst = &subst[4..];
- }
- Ok(PathBuf::from(OsString::from_wide(subst)))
- }
- }
-
- pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> {
- let mut info = c::FILE_BASIC_INFO {
- CreationTime: 0,
- LastAccessTime: 0,
- LastWriteTime: 0,
- ChangeTime: 0,
- FileAttributes: perm.attrs,
- };
- let size = mem::size_of_val(&info);
- cvt(unsafe {
- c::SetFileInformationByHandle(self.handle.raw(),
- c::FileBasicInfo,
- &mut info as *mut _ as *mut _,
- size as c::DWORD)
- })?;
- Ok(())
- }
-}
-
-impl FromInner<c::HANDLE> for File {
- fn from_inner(handle: c::HANDLE) -> File {
- File { handle: Handle::new(handle) }
- }
-}
-
-impl fmt::Debug for File {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- // FIXME(#24570): add more info here (e.g. mode)
- let mut b = f.debug_struct("File");
- b.field("handle", &self.handle.raw());
- if let Ok(path) = get_path(&self) {
- b.field("path", &path);
- }
- b.finish()
- }
-}
-
-impl FileAttr {
- pub fn size(&self) -> u64 {
- self.file_size
- }
-
- pub fn perm(&self) -> FilePermissions {
- FilePermissions { attrs: self.attributes }
- }
-
- pub fn attrs(&self) -> u32 { self.attributes as u32 }
-
- pub fn file_type(&self) -> FileType {
- FileType::new(self.attributes, self.reparse_tag)
- }
-
- pub fn modified(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(self.last_write_time))
- }
-
- pub fn accessed(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(self.last_access_time))
- }
-
- pub fn created(&self) -> io::Result<SystemTime> {
- Ok(SystemTime::from(self.creation_time))
- }
-
- pub fn modified_u64(&self) -> u64 {
- to_u64(&self.last_write_time)
- }
-
- pub fn accessed_u64(&self) -> u64 {
- to_u64(&self.last_access_time)
- }
-
- pub fn created_u64(&self) -> u64 {
- to_u64(&self.creation_time)
- }
-
- fn is_reparse_point(&self) -> bool {
- self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
- }
-}
-
-fn to_u64(ft: &c::FILETIME) -> u64 {
- (ft.dwLowDateTime as u64) | ((ft.dwHighDateTime as u64) << 32)
-}
-
-impl FilePermissions {
- pub fn readonly(&self) -> bool {
- self.attrs & c::FILE_ATTRIBUTE_READONLY != 0
- }
-
- pub fn set_readonly(&mut self, readonly: bool) {
- if readonly {
- self.attrs |= c::FILE_ATTRIBUTE_READONLY;
- } else {
- self.attrs &= !c::FILE_ATTRIBUTE_READONLY;
- }
- }
-}
-
-impl FileType {
- fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType {
- FileType {
- attributes: attrs,
- reparse_tag: reparse_tag,
- }
- }
- pub fn is_dir(&self) -> bool {
- !self.is_symlink() && self.is_directory()
- }
- pub fn is_file(&self) -> bool {
- !self.is_symlink() && !self.is_directory()
- }
- pub fn is_symlink(&self) -> bool {
- self.is_reparse_point() && self.is_reparse_tag_name_surrogate()
- }
- pub fn is_symlink_dir(&self) -> bool {
- self.is_symlink() && self.is_directory()
- }
- pub fn is_symlink_file(&self) -> bool {
- self.is_symlink() && !self.is_directory()
- }
- fn is_directory(&self) -> bool {
- self.attributes & c::FILE_ATTRIBUTE_DIRECTORY != 0
- }
- fn is_reparse_point(&self) -> bool {
- self.attributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
- }
- fn is_reparse_tag_name_surrogate(&self) -> bool {
- self.reparse_tag & 0x20000000 != 0
- }
-}
-
-impl DirBuilder {
- pub fn new() -> DirBuilder { DirBuilder }
-
- pub fn mkdir(&self, p: &Path) -> io::Result<()> {
- let p = to_u16s(p)?;
- cvt(unsafe {
- c::CreateDirectoryW(p.as_ptr(), ptr::null_mut())
- })?;
- Ok(())
- }
-}
-
-pub fn readdir(p: &Path) -> io::Result<ReadDir> {
- let root = p.to_path_buf();
- let star = p.join("*");
- let path = to_u16s(&star)?;
-
- unsafe {
- let mut wfd = mem::zeroed();
- let find_handle = c::FindFirstFileW(path.as_ptr(), &mut wfd);
- if find_handle != c::INVALID_HANDLE_VALUE {
- Ok(ReadDir {
- handle: FindNextFileHandle(find_handle),
- root: Arc::new(root),
- first: Some(wfd),
- })
- } else {
- Err(Error::last_os_error())
- }
- }
-}
-
-pub fn unlink(p: &Path) -> io::Result<()> {
- let p_u16s = to_u16s(p)?;
- cvt(unsafe { c::DeleteFileW(p_u16s.as_ptr()) })?;
- Ok(())
-}
-
-pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
- let old = to_u16s(old)?;
- let new = to_u16s(new)?;
- cvt(unsafe {
- c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING)
- })?;
- Ok(())
-}
-
-pub fn rmdir(p: &Path) -> io::Result<()> {
- let p = to_u16s(p)?;
- cvt(unsafe { c::RemoveDirectoryW(p.as_ptr()) })?;
- Ok(())
-}
-
-pub fn remove_dir_all(path: &Path) -> io::Result<()> {
- let filetype = lstat(path)?.file_type();
- if filetype.is_symlink() {
- // On Windows symlinks to files and directories are removed differently.
- // rmdir only deletes dir symlinks and junctions, not file symlinks.
- rmdir(path)
- } else {
- remove_dir_all_recursive(path)
- }
-}
-
-fn remove_dir_all_recursive(path: &Path) -> io::Result<()> {
- for child in readdir(path)? {
- let child = child?;
- let child_type = child.file_type()?;
- if child_type.is_dir() {
- remove_dir_all_recursive(&child.path())?;
- } else if child_type.is_symlink_dir() {
- rmdir(&child.path())?;
- } else {
- unlink(&child.path())?;
- }
- }
- rmdir(path)
-}
-
-pub fn readlink(path: &Path) -> io::Result<PathBuf> {
- // Open the link with no access mode, instead of generic read.
- // By default FILE_LIST_DIRECTORY is denied for the junction "C:\Documents and Settings", so
- // this is needed for a common case.
- let mut opts = OpenOptions::new();
- opts.access_mode(0);
- opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
- c::FILE_FLAG_BACKUP_SEMANTICS);
- let file = File::open(&path, &opts)?;
- file.readlink()
-}
-
-pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
- symlink_inner(src, dst, false)
-}
-
-pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
- let src = to_u16s(src)?;
- let dst = to_u16s(dst)?;
- let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 };
- // Formerly, symlink creation required the SeCreateSymbolicLink privilege. For the Windows 10
- // Creators Update, Microsoft loosened this to allow unprivileged symlink creation if the
- // computer is in Developer Mode, but SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE must be
- // added to dwFlags to opt into this behaviour.
- let result = cvt(unsafe {
- c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(),
- flags | c::SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE) as c::BOOL
- });
- if let Err(err) = result {
- if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as i32) {
- // Older Windows objects to SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE,
- // so if we encounter ERROR_INVALID_PARAMETER, retry without that flag.
- cvt(unsafe {
- c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as c::BOOL
- })?;
- } else {
- return Err(err);
- }
- }
- Ok(())
-}
-
-pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
- let src = to_u16s(src)?;
- let dst = to_u16s(dst)?;
- cvt(unsafe {
- c::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::null_mut())
- })?;
- Ok(())
-}
-
-pub fn stat(path: &Path) -> io::Result<FileAttr> {
- let mut opts = OpenOptions::new();
- // No read or write permissions are necessary
- opts.access_mode(0);
- // This flag is so we can open directories too
- opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
- let file = File::open(path, &opts)?;
- file.file_attr()
-}
-
-pub fn lstat(path: &Path) -> io::Result<FileAttr> {
- let mut opts = OpenOptions::new();
- // No read or write permissions are necessary
- opts.access_mode(0);
- opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS | c::FILE_FLAG_OPEN_REPARSE_POINT);
- let file = File::open(path, &opts)?;
- file.file_attr()
-}
-
-pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
- let p = to_u16s(p)?;
- unsafe {
- cvt(c::SetFileAttributesW(p.as_ptr(), perm.attrs))?;
- Ok(())
- }
-}
-
-fn get_path(f: &File) -> io::Result<PathBuf> {
- super::fill_utf16_buf(|buf, sz| unsafe {
- c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
- c::VOLUME_NAME_DOS)
- }, |buf| {
- PathBuf::from(OsString::from_wide(buf))
- })
-}
-
-pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
- let mut opts = OpenOptions::new();
- // No read or write permissions are necessary
- opts.access_mode(0);
- // This flag is so we can open directories too
- opts.custom_flags(c::FILE_FLAG_BACKUP_SEMANTICS);
- let f = File::open(p, &opts)?;
- get_path(&f)
-}
-
-pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
- unsafe extern "system" fn callback(
- _TotalFileSize: c::LARGE_INTEGER,
- _TotalBytesTransferred: c::LARGE_INTEGER,
- _StreamSize: c::LARGE_INTEGER,
- StreamBytesTransferred: c::LARGE_INTEGER,
- dwStreamNumber: c::DWORD,
- _dwCallbackReason: c::DWORD,
- _hSourceFile: c::HANDLE,
- _hDestinationFile: c::HANDLE,
- lpData: c::LPVOID,
- ) -> c::DWORD {
- if dwStreamNumber == 1 {*(lpData as *mut i64) = StreamBytesTransferred;}
- c::PROGRESS_CONTINUE
- }
- let pfrom = to_u16s(from)?;
- let pto = to_u16s(to)?;
- let mut size = 0i64;
- cvt(unsafe {
- c::CopyFileExW(pfrom.as_ptr(), pto.as_ptr(), Some(callback),
- &mut size as *mut _ as *mut _, ptr::null_mut(), 0)
- })?;
- Ok(size as u64)
-}
-
-#[allow(dead_code)]
-pub fn symlink_junction<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
- symlink_junction_inner(src.as_ref(), dst.as_ref())
-}
-
-// Creating a directory junction on windows involves dealing with reparse
-// points and the DeviceIoControl function, and this code is a skeleton of
-// what can be found here:
-//
-// http://www.flexhex.com/docs/articles/hard-links.phtml
-#[allow(dead_code)]
-fn symlink_junction_inner(target: &Path, junction: &Path) -> io::Result<()> {
- let d = DirBuilder::new();
- d.mkdir(&junction)?;
-
- let mut opts = OpenOptions::new();
- opts.write(true);
- opts.custom_flags(c::FILE_FLAG_OPEN_REPARSE_POINT |
- c::FILE_FLAG_BACKUP_SEMANTICS);
- let f = File::open(junction, &opts)?;
- let h = f.handle().raw();
-
- unsafe {
- let mut data = [0u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
- let db = data.as_mut_ptr()
- as *mut c::REPARSE_MOUNTPOINT_DATA_BUFFER;
- let buf = &mut (*db).ReparseTarget as *mut c::WCHAR;
- let mut i = 0;
- // FIXME: this conversion is very hacky
- let v = br"\??\";
- let v = v.iter().map(|x| *x as u16);
- for c in v.chain(target.as_os_str().encode_wide()) {
- *buf.offset(i) = c;
- i += 1;
- }
- *buf.offset(i) = 0;
- i += 1;
- (*db).ReparseTag = c::IO_REPARSE_TAG_MOUNT_POINT;
- (*db).ReparseTargetMaximumLength = (i * 2) as c::WORD;
- (*db).ReparseTargetLength = ((i - 1) * 2) as c::WORD;
- (*db).ReparseDataLength =
- (*db).ReparseTargetLength as c::DWORD + 12;
-
- let mut ret = 0;
- cvt(c::DeviceIoControl(h as *mut _,
- c::FSCTL_SET_REPARSE_POINT,
- data.as_ptr() as *mut _,
- (*db).ReparseDataLength + 8,
- ptr::null_mut(), 0,
- &mut ret,
- ptr::null_mut())).map(|_| ())
- }
-}
diff --git a/ctr-std/src/sys/windows/handle.rs b/ctr-std/src/sys/windows/handle.rs
deleted file mode 100644
index 3729d6d..0000000
--- a/ctr-std/src/sys/windows/handle.rs
+++ /dev/null
@@ -1,218 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(issue = "0", feature = "windows_handle")]
-
-use cmp;
-use io::{ErrorKind, Read};
-use io;
-use mem;
-use ops::Deref;
-use ptr;
-use sys::c;
-use sys::cvt;
-
-/// An owned container for `HANDLE` object, closing them on Drop.
-///
-/// All methods are inherited through a `Deref` impl to `RawHandle`
-pub struct Handle(RawHandle);
-
-/// A wrapper type for `HANDLE` objects to give them proper Send/Sync inference
-/// as well as Rust-y methods.
-///
-/// This does **not** drop the handle when it goes out of scope, use `Handle`
-/// instead for that.
-#[derive(Copy, Clone)]
-pub struct RawHandle(c::HANDLE);
-
-unsafe impl Send for RawHandle {}
-unsafe impl Sync for RawHandle {}
-
-impl Handle {
- pub fn new(handle: c::HANDLE) -> Handle {
- Handle(RawHandle::new(handle))
- }
-
- pub fn new_event(manual: bool, init: bool) -> io::Result<Handle> {
- unsafe {
- let event = c::CreateEventW(ptr::null_mut(),
- manual as c::BOOL,
- init as c::BOOL,
- ptr::null());
- if event.is_null() {
- Err(io::Error::last_os_error())
- } else {
- Ok(Handle::new(event))
- }
- }
- }
-
- pub fn into_raw(self) -> c::HANDLE {
- let ret = self.raw();
- mem::forget(self);
- return ret;
- }
-}
-
-impl Deref for Handle {
- type Target = RawHandle;
- fn deref(&self) -> &RawHandle { &self.0 }
-}
-
-impl Drop for Handle {
- fn drop(&mut self) {
- unsafe { let _ = c::CloseHandle(self.raw()); }
- }
-}
-
-impl RawHandle {
- pub fn new(handle: c::HANDLE) -> RawHandle {
- RawHandle(handle)
- }
-
- pub fn raw(&self) -> c::HANDLE { self.0 }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- let mut read = 0;
- let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
- let res = cvt(unsafe {
- c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID,
- len, &mut read, ptr::null_mut())
- });
-
- match res {
- Ok(_) => Ok(read as usize),
-
- // The special treatment of BrokenPipe is to deal with Windows
- // pipe semantics, which yields this error when *reading* from
- // a pipe after the other end has closed; we interpret that as
- // EOF on the pipe.
- Err(ref e) if e.kind() == ErrorKind::BrokenPipe => Ok(0),
-
- Err(e) => Err(e)
- }
- }
-
- pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize> {
- let mut read = 0;
- let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
- let res = unsafe {
- let mut overlapped: c::OVERLAPPED = mem::zeroed();
- overlapped.Offset = offset as u32;
- overlapped.OffsetHigh = (offset >> 32) as u32;
- cvt(c::ReadFile(self.0, buf.as_mut_ptr() as c::LPVOID,
- len, &mut read, &mut overlapped))
- };
- match res {
- Ok(_) => Ok(read as usize),
- Err(ref e) if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32) => Ok(0),
- Err(e) => Err(e),
- }
- }
-
- pub unsafe fn read_overlapped(&self,
- buf: &mut [u8],
- overlapped: *mut c::OVERLAPPED)
- -> io::Result<Option<usize>> {
- let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
- let mut amt = 0;
- let res = cvt({
- c::ReadFile(self.0, buf.as_ptr() as c::LPVOID,
- len, &mut amt, overlapped)
- });
- match res {
- Ok(_) => Ok(Some(amt as usize)),
- Err(e) => {
- if e.raw_os_error() == Some(c::ERROR_IO_PENDING as i32) {
- Ok(None)
- } else if e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
- Ok(Some(0))
- } else {
- Err(e)
- }
- }
- }
- }
-
- pub fn overlapped_result(&self,
- overlapped: *mut c::OVERLAPPED,
- wait: bool) -> io::Result<usize> {
- unsafe {
- let mut bytes = 0;
- let wait = if wait {c::TRUE} else {c::FALSE};
- let res = cvt({
- c::GetOverlappedResult(self.raw(), overlapped, &mut bytes, wait)
- });
- match res {
- Ok(_) => Ok(bytes as usize),
- Err(e) => {
- if e.raw_os_error() == Some(c::ERROR_HANDLE_EOF as i32) ||
- e.raw_os_error() == Some(c::ERROR_BROKEN_PIPE as i32) {
- Ok(0)
- } else {
- Err(e)
- }
- }
- }
- }
- }
-
- pub fn cancel_io(&self) -> io::Result<()> {
- unsafe {
- cvt(c::CancelIo(self.raw())).map(|_| ())
- }
- }
-
- pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
- let mut me = self;
- (&mut me).read_to_end(buf)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- let mut amt = 0;
- let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
- cvt(unsafe {
- c::WriteFile(self.0, buf.as_ptr() as c::LPVOID,
- len, &mut amt, ptr::null_mut())
- })?;
- Ok(amt as usize)
- }
-
- pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize> {
- let mut written = 0;
- let len = cmp::min(buf.len(), <c::DWORD>::max_value() as usize) as c::DWORD;
- unsafe {
- let mut overlapped: c::OVERLAPPED = mem::zeroed();
- overlapped.Offset = offset as u32;
- overlapped.OffsetHigh = (offset >> 32) as u32;
- cvt(c::WriteFile(self.0, buf.as_ptr() as c::LPVOID,
- len, &mut written, &mut overlapped))?;
- }
- Ok(written as usize)
- }
-
- pub fn duplicate(&self, access: c::DWORD, inherit: bool,
- options: c::DWORD) -> io::Result<Handle> {
- let mut ret = 0 as c::HANDLE;
- cvt(unsafe {
- let cur_proc = c::GetCurrentProcess();
- c::DuplicateHandle(cur_proc, self.0, cur_proc, &mut ret,
- access, inherit as c::BOOL,
- options)
- })?;
- Ok(Handle::new(ret))
- }
-}
-
-impl<'a> Read for &'a RawHandle {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- (**self).read(buf)
- }
-}
diff --git a/ctr-std/src/sys/windows/memchr.rs b/ctr-std/src/sys/windows/memchr.rs
deleted file mode 100644
index fa7c816..0000000
--- a/ctr-std/src/sys/windows/memchr.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-//
-// Original implementation taken from rust-memchr
-// Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
-
-// Fallback memchr is fastest on windows
-pub use core::slice::memchr::{memchr, memrchr};
diff --git a/ctr-std/src/sys/windows/mod.rs b/ctr-std/src/sys/windows/mod.rs
deleted file mode 100644
index ccf79de..0000000
--- a/ctr-std/src/sys/windows/mod.rs
+++ /dev/null
@@ -1,277 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![allow(missing_docs, bad_style)]
-
-use ptr;
-use ffi::{OsStr, OsString};
-use io::{self, ErrorKind};
-use os::windows::ffi::{OsStrExt, OsStringExt};
-use path::PathBuf;
-use time::Duration;
-
-pub use libc::strlen;
-pub use self::rand::hashmap_random_keys;
-
-#[macro_use] pub mod compat;
-
-pub mod args;
-#[cfg(feature = "backtrace")]
-pub mod backtrace;
-pub mod c;
-pub mod cmath;
-pub mod condvar;
-#[cfg(feature = "backtrace")]
-pub mod dynamic_lib;
-pub mod env;
-pub mod ext;
-pub mod fast_thread_local;
-pub mod fs;
-pub mod handle;
-pub mod memchr;
-pub mod mutex;
-pub mod net;
-pub mod os;
-pub mod os_str;
-pub mod path;
-pub mod pipe;
-pub mod process;
-pub mod rand;
-pub mod rwlock;
-pub mod stack_overflow;
-pub mod thread;
-pub mod thread_local;
-pub mod time;
-pub mod stdio;
-
-#[cfg(not(test))]
-pub fn init() {
-}
-
-pub fn decode_error_kind(errno: i32) -> ErrorKind {
- match errno as c::DWORD {
- c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
- c::ERROR_ALREADY_EXISTS => return ErrorKind::AlreadyExists,
- c::ERROR_FILE_EXISTS => return ErrorKind::AlreadyExists,
- c::ERROR_BROKEN_PIPE => return ErrorKind::BrokenPipe,
- c::ERROR_FILE_NOT_FOUND => return ErrorKind::NotFound,
- c::ERROR_PATH_NOT_FOUND => return ErrorKind::NotFound,
- c::ERROR_NO_DATA => return ErrorKind::BrokenPipe,
- c::ERROR_OPERATION_ABORTED => return ErrorKind::TimedOut,
- _ => {}
- }
-
- match errno {
- c::WSAEACCES => ErrorKind::PermissionDenied,
- c::WSAEADDRINUSE => ErrorKind::AddrInUse,
- c::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
- c::WSAECONNABORTED => ErrorKind::ConnectionAborted,
- c::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
- c::WSAECONNRESET => ErrorKind::ConnectionReset,
- c::WSAEINVAL => ErrorKind::InvalidInput,
- c::WSAENOTCONN => ErrorKind::NotConnected,
- c::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
- c::WSAETIMEDOUT => ErrorKind::TimedOut,
-
- _ => ErrorKind::Other,
- }
-}
-
-pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> io::Result<Vec<u16>> {
- fn inner(s: &OsStr) -> io::Result<Vec<u16>> {
- let mut maybe_result: Vec<u16> = s.encode_wide().collect();
- if maybe_result.iter().any(|&u| u == 0) {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "strings passed to WinAPI cannot contain NULs"));
- }
- maybe_result.push(0);
- Ok(maybe_result)
- }
- inner(s.as_ref())
-}
-
-// Many Windows APIs follow a pattern of where we hand a buffer and then they
-// will report back to us how large the buffer should be or how many bytes
-// currently reside in the buffer. This function is an abstraction over these
-// functions by making them easier to call.
-//
-// The first callback, `f1`, is yielded a (pointer, len) pair which can be
-// passed to a syscall. The `ptr` is valid for `len` items (u16 in this case).
-// The closure is expected to return what the syscall returns which will be
-// interpreted by this function to determine if the syscall needs to be invoked
-// again (with more buffer space).
-//
-// Once the syscall has completed (errors bail out early) the second closure is
-// yielded the data which has been read from the syscall. The return value
-// from this closure is then the return value of the function.
-fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> io::Result<T>
- where F1: FnMut(*mut u16, c::DWORD) -> c::DWORD,
- F2: FnOnce(&[u16]) -> T
-{
- // Start off with a stack buf but then spill over to the heap if we end up
- // needing more space.
- let mut stack_buf = [0u16; 512];
- let mut heap_buf = Vec::new();
- unsafe {
- let mut n = stack_buf.len();
- loop {
- let buf = if n <= stack_buf.len() {
- &mut stack_buf[..]
- } else {
- let extra = n - heap_buf.len();
- heap_buf.reserve(extra);
- heap_buf.set_len(n);
- &mut heap_buf[..]
- };
-
- // This function is typically called on windows API functions which
- // will return the correct length of the string, but these functions
- // also return the `0` on error. In some cases, however, the
- // returned "correct length" may actually be 0!
- //
- // To handle this case we call `SetLastError` to reset it to 0 and
- // then check it again if we get the "0 error value". If the "last
- // error" is still 0 then we interpret it as a 0 length buffer and
- // not an actual error.
- c::SetLastError(0);
- let k = match f1(buf.as_mut_ptr(), n as c::DWORD) {
- 0 if c::GetLastError() == 0 => 0,
- 0 => return Err(io::Error::last_os_error()),
- n => n,
- } as usize;
- if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
- n *= 2;
- } else if k >= n {
- n = k;
- } else {
- return Ok(f2(&buf[..k]))
- }
- }
- }
-}
-
-fn os2path(s: &[u16]) -> PathBuf {
- PathBuf::from(OsString::from_wide(s))
-}
-
-#[allow(dead_code)] // Only used in backtrace::gnu::get_executable_filename()
-fn wide_char_to_multi_byte(code_page: u32,
- flags: u32,
- s: &[u16],
- no_default_char: bool)
- -> io::Result<Vec<i8>> {
- unsafe {
- let mut size = c::WideCharToMultiByte(code_page,
- flags,
- s.as_ptr(),
- s.len() as i32,
- ptr::null_mut(),
- 0,
- ptr::null(),
- ptr::null_mut());
- if size == 0 {
- return Err(io::Error::last_os_error());
- }
-
- let mut buf = Vec::with_capacity(size as usize);
- buf.set_len(size as usize);
-
- let mut used_default_char = c::FALSE;
- size = c::WideCharToMultiByte(code_page,
- flags,
- s.as_ptr(),
- s.len() as i32,
- buf.as_mut_ptr(),
- buf.len() as i32,
- ptr::null(),
- if no_default_char { &mut used_default_char }
- else { ptr::null_mut() });
- if size == 0 {
- return Err(io::Error::last_os_error());
- }
- if no_default_char && used_default_char == c::TRUE {
- return Err(io::Error::new(io::ErrorKind::InvalidData,
- "string cannot be converted to requested code page"));
- }
-
- buf.set_len(size as usize);
-
- Ok(buf)
- }
-}
-
-pub fn truncate_utf16_at_nul<'a>(v: &'a [u16]) -> &'a [u16] {
- match v.iter().position(|c| *c == 0) {
- // don't include the 0
- Some(i) => &v[..i],
- None => v
- }
-}
-
-pub trait IsZero {
- fn is_zero(&self) -> bool;
-}
-
-macro_rules! impl_is_zero {
- ($($t:ident)*) => ($(impl IsZero for $t {
- fn is_zero(&self) -> bool {
- *self == 0
- }
- })*)
-}
-
-impl_is_zero! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }
-
-pub fn cvt<I: IsZero>(i: I) -> io::Result<I> {
- if i.is_zero() {
- Err(io::Error::last_os_error())
- } else {
- Ok(i)
- }
-}
-
-pub fn dur2timeout(dur: Duration) -> c::DWORD {
- // Note that a duration is a (u64, u32) (seconds, nanoseconds) pair, and the
- // timeouts in windows APIs are typically u32 milliseconds. To translate, we
- // have two pieces to take care of:
- //
- // * Nanosecond precision is rounded up
- // * Greater than u32::MAX milliseconds (50 days) is rounded up to INFINITE
- // (never time out).
- dur.as_secs().checked_mul(1000).and_then(|ms| {
- ms.checked_add((dur.subsec_nanos() as u64) / 1_000_000)
- }).and_then(|ms| {
- ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 {1} else {0})
- }).map(|ms| {
- if ms > <c::DWORD>::max_value() as u64 {
- c::INFINITE
- } else {
- ms as c::DWORD
- }
- }).unwrap_or(c::INFINITE)
-}
-
-// On Windows, use the processor-specific __fastfail mechanism. In Windows 8
-// and later, this will terminate the process immediately without running any
-// in-process exception handlers. In earlier versions of Windows, this
-// sequence of instructions will be treated as an access violation,
-// terminating the process but without necessarily bypassing all exception
-// handlers.
-//
-// https://msdn.microsoft.com/en-us/library/dn774154.aspx
-#[allow(unreachable_code)]
-pub unsafe fn abort_internal() -> ! {
- #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
- {
- asm!("int $$0x29" :: "{ecx}"(7) ::: volatile); // 7 is FAST_FAIL_FATAL_APP_EXIT
- ::intrinsics::unreachable();
- }
- ::intrinsics::abort();
-}
diff --git a/ctr-std/src/sys/windows/mutex.rs b/ctr-std/src/sys/windows/mutex.rs
deleted file mode 100644
index 9bf9f74..0000000
--- a/ctr-std/src/sys/windows/mutex.rs
+++ /dev/null
@@ -1,188 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! System Mutexes
-//!
-//! The Windows implementation of mutexes is a little odd and it may not be
-//! immediately obvious what's going on. The primary oddness is that SRWLock is
-//! used instead of CriticalSection, and this is done because:
-//!
-//! 1. SRWLock is several times faster than CriticalSection according to
-//! benchmarks performed on both Windows 8 and Windows 7.
-//!
-//! 2. CriticalSection allows recursive locking while SRWLock deadlocks. The
-//! Unix implementation deadlocks so consistency is preferred. See #19962 for
-//! more details.
-//!
-//! 3. While CriticalSection is fair and SRWLock is not, the current Rust policy
-//! is that there are no guarantees of fairness.
-//!
-//! The downside of this approach, however, is that SRWLock is not available on
-//! Windows XP, so we continue to have a fallback implementation where
-//! CriticalSection is used and we keep track of who's holding the mutex to
-//! detect recursive locks.
-
-use cell::UnsafeCell;
-use mem;
-use sync::atomic::{AtomicUsize, Ordering};
-use sys::c;
-use sys::compat;
-
-pub struct Mutex {
- lock: AtomicUsize,
- held: UnsafeCell<bool>,
-}
-
-unsafe impl Send for Mutex {}
-unsafe impl Sync for Mutex {}
-
-#[derive(Clone, Copy)]
-enum Kind {
- SRWLock = 1,
- CriticalSection = 2,
-}
-
-#[inline]
-pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK {
- debug_assert!(mem::size_of::<c::SRWLOCK>() <= mem::size_of_val(&m.lock));
- &m.lock as *const _ as *mut _
-}
-
-impl Mutex {
- pub const fn new() -> Mutex {
- Mutex {
- lock: AtomicUsize::new(0),
- held: UnsafeCell::new(false),
- }
- }
- #[inline]
- pub unsafe fn init(&mut self) {}
- pub unsafe fn lock(&self) {
- match kind() {
- Kind::SRWLock => c::AcquireSRWLockExclusive(raw(self)),
- Kind::CriticalSection => {
- let re = self.remutex();
- (*re).lock();
- if !self.flag_locked() {
- (*re).unlock();
- panic!("cannot recursively lock a mutex");
- }
- }
- }
- }
- pub unsafe fn try_lock(&self) -> bool {
- match kind() {
- Kind::SRWLock => c::TryAcquireSRWLockExclusive(raw(self)) != 0,
- Kind::CriticalSection => {
- let re = self.remutex();
- if !(*re).try_lock() {
- false
- } else if self.flag_locked() {
- true
- } else {
- (*re).unlock();
- false
- }
- }
- }
- }
- pub unsafe fn unlock(&self) {
- *self.held.get() = false;
- match kind() {
- Kind::SRWLock => c::ReleaseSRWLockExclusive(raw(self)),
- Kind::CriticalSection => (*self.remutex()).unlock(),
- }
- }
- pub unsafe fn destroy(&self) {
- match kind() {
- Kind::SRWLock => {}
- Kind::CriticalSection => {
- match self.lock.load(Ordering::SeqCst) {
- 0 => {}
- n => { Box::from_raw(n as *mut ReentrantMutex).destroy(); }
- }
- }
- }
- }
-
- unsafe fn remutex(&self) -> *mut ReentrantMutex {
- match self.lock.load(Ordering::SeqCst) {
- 0 => {}
- n => return n as *mut _,
- }
- let mut re = box ReentrantMutex::uninitialized();
- re.init();
- let re = Box::into_raw(re);
- match self.lock.compare_and_swap(0, re as usize, Ordering::SeqCst) {
- 0 => re,
- n => { Box::from_raw(re).destroy(); n as *mut _ }
- }
- }
-
- unsafe fn flag_locked(&self) -> bool {
- if *self.held.get() {
- false
- } else {
- *self.held.get() = true;
- true
- }
-
- }
-}
-
-fn kind() -> Kind {
- static KIND: AtomicUsize = AtomicUsize::new(0);
-
- let val = KIND.load(Ordering::SeqCst);
- if val == Kind::SRWLock as usize {
- return Kind::SRWLock
- } else if val == Kind::CriticalSection as usize {
- return Kind::CriticalSection
- }
-
- let ret = match compat::lookup("kernel32", "AcquireSRWLockExclusive") {
- None => Kind::CriticalSection,
- Some(..) => Kind::SRWLock,
- };
- KIND.store(ret as usize, Ordering::SeqCst);
- return ret;
-}
-
-pub struct ReentrantMutex { inner: UnsafeCell<c::CRITICAL_SECTION> }
-
-unsafe impl Send for ReentrantMutex {}
-unsafe impl Sync for ReentrantMutex {}
-
-impl ReentrantMutex {
- pub unsafe fn uninitialized() -> ReentrantMutex {
- mem::uninitialized()
- }
-
- pub unsafe fn init(&mut self) {
- c::InitializeCriticalSection(self.inner.get());
- }
-
- pub unsafe fn lock(&self) {
- c::EnterCriticalSection(self.inner.get());
- }
-
- #[inline]
- pub unsafe fn try_lock(&self) -> bool {
- c::TryEnterCriticalSection(self.inner.get()) != 0
- }
-
- pub unsafe fn unlock(&self) {
- c::LeaveCriticalSection(self.inner.get());
- }
-
- pub unsafe fn destroy(&self) {
- c::DeleteCriticalSection(self.inner.get());
- }
-}
diff --git a/ctr-std/src/sys/windows/net.rs b/ctr-std/src/sys/windows/net.rs
deleted file mode 100644
index cd8acff..0000000
--- a/ctr-std/src/sys/windows/net.rs
+++ /dev/null
@@ -1,356 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(issue = "0", feature = "windows_net")]
-
-use cmp;
-use io::{self, Read};
-use libc::{c_int, c_void, c_ulong, c_long};
-use mem;
-use net::{SocketAddr, Shutdown};
-use ptr;
-use sync::Once;
-use sys::c;
-use sys;
-use sys_common::{self, AsInner, FromInner, IntoInner};
-use sys_common::net;
-use time::Duration;
-
-pub type wrlen_t = i32;
-
-pub mod netc {
- pub use sys::c::*;
- pub use sys::c::SOCKADDR as sockaddr;
- pub use sys::c::SOCKADDR_STORAGE_LH as sockaddr_storage;
- pub use sys::c::ADDRINFOA as addrinfo;
- pub use sys::c::ADDRESS_FAMILY as sa_family_t;
-}
-
-pub struct Socket(c::SOCKET);
-
-/// Checks whether the Windows socket interface has been started already, and
-/// if not, starts it.
-pub fn init() {
- static START: Once = Once::new();
-
- START.call_once(|| unsafe {
- let mut data: c::WSADATA = mem::zeroed();
- let ret = c::WSAStartup(0x202, // version 2.2
- &mut data);
- assert_eq!(ret, 0);
-
- let _ = sys_common::at_exit(|| { c::WSACleanup(); });
- });
-}
-
-/// Returns the last error from the Windows socket interface.
-fn last_error() -> io::Error {
- io::Error::from_raw_os_error(unsafe { c::WSAGetLastError() })
-}
-
-#[doc(hidden)]
-pub trait IsMinusOne {
- fn is_minus_one(&self) -> bool;
-}
-
-macro_rules! impl_is_minus_one {
- ($($t:ident)*) => ($(impl IsMinusOne for $t {
- fn is_minus_one(&self) -> bool {
- *self == -1
- }
- })*)
-}
-
-impl_is_minus_one! { i8 i16 i32 i64 isize }
-
-/// Checks if the signed integer is the Windows constant `SOCKET_ERROR` (-1)
-/// and if so, returns the last error from the Windows socket interface. This
-/// function must be called before another call to the socket API is made.
-pub fn cvt<T: IsMinusOne>(t: T) -> io::Result<T> {
- if t.is_minus_one() {
- Err(last_error())
- } else {
- Ok(t)
- }
-}
-
-/// A variant of `cvt` for `getaddrinfo` which return 0 for a success.
-pub fn cvt_gai(err: c_int) -> io::Result<()> {
- if err == 0 {
- Ok(())
- } else {
- Err(last_error())
- }
-}
-
-/// Just to provide the same interface as sys/unix/net.rs
-pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
- where T: IsMinusOne,
- F: FnMut() -> T
-{
- cvt(f())
-}
-
-impl Socket {
- pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
- let fam = match *addr {
- SocketAddr::V4(..) => c::AF_INET,
- SocketAddr::V6(..) => c::AF_INET6,
- };
- let socket = unsafe {
- match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
- c::WSA_FLAG_OVERLAPPED) {
- c::INVALID_SOCKET => Err(last_error()),
- n => Ok(Socket(n)),
- }
- }?;
- socket.set_no_inherit()?;
- Ok(socket)
- }
-
- pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
- self.set_nonblocking(true)?;
- let r = unsafe {
- let (addrp, len) = addr.into_inner();
- cvt(c::connect(self.0, addrp, len))
- };
- self.set_nonblocking(false)?;
-
- match r {
- Ok(_) => return Ok(()),
- Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
- Err(e) => return Err(e),
- }
-
- if timeout.as_secs() == 0 && timeout.subsec_nanos() == 0 {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot set a 0 duration timeout"));
- }
-
- let mut timeout = c::timeval {
- tv_sec: timeout.as_secs() as c_long,
- tv_usec: (timeout.subsec_nanos() / 1000) as c_long,
- };
- if timeout.tv_sec == 0 && timeout.tv_usec == 0 {
- timeout.tv_usec = 1;
- }
-
- let fds = unsafe {
- let mut fds = mem::zeroed::<c::fd_set>();
- fds.fd_count = 1;
- fds.fd_array[0] = self.0;
- fds
- };
-
- let mut writefds = fds;
- let mut errorfds = fds;
-
- let n = unsafe {
- cvt(c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout))?
- };
-
- match n {
- 0 => Err(io::Error::new(io::ErrorKind::TimedOut, "connection timed out")),
- _ => {
- if writefds.fd_count != 1 {
- if let Some(e) = self.take_error()? {
- return Err(e);
- }
- }
- Ok(())
- }
- }
- }
-
- pub fn accept(&self, storage: *mut c::SOCKADDR,
- len: *mut c_int) -> io::Result<Socket> {
- let socket = unsafe {
- match c::accept(self.0, storage, len) {
- c::INVALID_SOCKET => Err(last_error()),
- n => Ok(Socket(n)),
- }
- }?;
- socket.set_no_inherit()?;
- Ok(socket)
- }
-
- pub fn duplicate(&self) -> io::Result<Socket> {
- let socket = unsafe {
- let mut info: c::WSAPROTOCOL_INFO = mem::zeroed();
- cvt(c::WSADuplicateSocketW(self.0,
- c::GetCurrentProcessId(),
- &mut info))?;
- match c::WSASocketW(info.iAddressFamily,
- info.iSocketType,
- info.iProtocol,
- &mut info, 0,
- c::WSA_FLAG_OVERLAPPED) {
- c::INVALID_SOCKET => Err(last_error()),
- n => Ok(Socket(n)),
- }
- }?;
- socket.set_no_inherit()?;
- Ok(socket)
- }
-
- fn recv_with_flags(&self, buf: &mut [u8], flags: c_int) -> io::Result<usize> {
- // On unix when a socket is shut down all further reads return 0, so we
- // do the same on windows to map a shut down socket to returning EOF.
- let len = cmp::min(buf.len(), i32::max_value() as usize) as i32;
- unsafe {
- match c::recv(self.0, buf.as_mut_ptr() as *mut c_void, len, flags) {
- -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
- -1 => Err(last_error()),
- n => Ok(n as usize)
- }
- }
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.recv_with_flags(buf, 0)
- }
-
- pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.recv_with_flags(buf, c::MSG_PEEK)
- }
-
- fn recv_from_with_flags(&self, buf: &mut [u8], flags: c_int)
- -> io::Result<(usize, SocketAddr)> {
- let mut storage: c::SOCKADDR_STORAGE_LH = unsafe { mem::zeroed() };
- let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
- let len = cmp::min(buf.len(), <wrlen_t>::max_value() as usize) as wrlen_t;
-
- // On unix when a socket is shut down all further reads return 0, so we
- // do the same on windows to map a shut down socket to returning EOF.
- unsafe {
- match c::recvfrom(self.0,
- buf.as_mut_ptr() as *mut c_void,
- len,
- flags,
- &mut storage as *mut _ as *mut _,
- &mut addrlen) {
- -1 if c::WSAGetLastError() == c::WSAESHUTDOWN => {
- Ok((0, net::sockaddr_to_addr(&storage, addrlen as usize)?))
- },
- -1 => Err(last_error()),
- n => Ok((n as usize, net::sockaddr_to_addr(&storage, addrlen as usize)?)),
- }
- }
- }
-
- pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.recv_from_with_flags(buf, 0)
- }
-
- pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
- self.recv_from_with_flags(buf, c::MSG_PEEK)
- }
-
- pub fn set_timeout(&self, dur: Option<Duration>,
- kind: c_int) -> io::Result<()> {
- let timeout = match dur {
- Some(dur) => {
- let timeout = sys::dur2timeout(dur);
- if timeout == 0 {
- return Err(io::Error::new(io::ErrorKind::InvalidInput,
- "cannot set a 0 duration timeout"));
- }
- timeout
- }
- None => 0
- };
- net::setsockopt(self, c::SOL_SOCKET, kind, timeout)
- }
-
- pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
- let raw: c::DWORD = net::getsockopt(self, c::SOL_SOCKET, kind)?;
- if raw == 0 {
- Ok(None)
- } else {
- let secs = raw / 1000;
- let nsec = (raw % 1000) * 1000000;
- Ok(Some(Duration::new(secs as u64, nsec as u32)))
- }
- }
-
- fn set_no_inherit(&self) -> io::Result<()> {
- sys::cvt(unsafe {
- c::SetHandleInformation(self.0 as c::HANDLE,
- c::HANDLE_FLAG_INHERIT, 0)
- }).map(|_| ())
- }
-
- pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
- let how = match how {
- Shutdown::Write => c::SD_SEND,
- Shutdown::Read => c::SD_RECEIVE,
- Shutdown::Both => c::SD_BOTH,
- };
- cvt(unsafe { c::shutdown(self.0, how) })?;
- Ok(())
- }
-
- pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
- let mut nonblocking = nonblocking as c_ulong;
- let r = unsafe { c::ioctlsocket(self.0, c::FIONBIO as c_int, &mut nonblocking) };
- if r == 0 {
- Ok(())
- } else {
- Err(io::Error::last_os_error())
- }
- }
-
- pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
- net::setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BYTE)
- }
-
- pub fn nodelay(&self) -> io::Result<bool> {
- let raw: c::BYTE = net::getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)?;
- Ok(raw != 0)
- }
-
- pub fn take_error(&self) -> io::Result<Option<io::Error>> {
- let raw: c_int = net::getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)?;
- if raw == 0 {
- Ok(None)
- } else {
- Ok(Some(io::Error::from_raw_os_error(raw as i32)))
- }
- }
-}
-
-#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
-impl<'a> Read for &'a Socket {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- (**self).read(buf)
- }
-}
-
-impl Drop for Socket {
- fn drop(&mut self) {
- let _ = unsafe { c::closesocket(self.0) };
- }
-}
-
-impl AsInner<c::SOCKET> for Socket {
- fn as_inner(&self) -> &c::SOCKET { &self.0 }
-}
-
-impl FromInner<c::SOCKET> for Socket {
- fn from_inner(sock: c::SOCKET) -> Socket { Socket(sock) }
-}
-
-impl IntoInner<c::SOCKET> for Socket {
- fn into_inner(self) -> c::SOCKET {
- let ret = self.0;
- mem::forget(self);
- ret
- }
-}
diff --git a/ctr-std/src/sys/windows/os.rs b/ctr-std/src/sys/windows/os.rs
deleted file mode 100644
index b944824..0000000
--- a/ctr-std/src/sys/windows/os.rs
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Implementation of `std::os` functionality for Windows
-
-#![allow(bad_style)]
-
-use os::windows::prelude::*;
-
-use error::Error as StdError;
-use ffi::{OsString, OsStr};
-use fmt;
-use io;
-use os::windows::ffi::EncodeWide;
-use path::{self, PathBuf};
-use ptr;
-use slice;
-use sys::{c, cvt};
-use sys::handle::Handle;
-
-use super::to_u16s;
-
-pub fn errno() -> i32 {
- unsafe { c::GetLastError() as i32 }
-}
-
-/// Gets a detailed string description for the given error number.
-pub fn error_string(mut errnum: i32) -> String {
- // This value is calculated from the macro
- // MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
- let langId = 0x0800 as c::DWORD;
-
- let mut buf = [0 as c::WCHAR; 2048];
-
- unsafe {
- let mut module = ptr::null_mut();
- let mut flags = 0;
-
- // NTSTATUS errors may be encoded as HRESULT, which may returned from
- // GetLastError. For more information about Windows error codes, see
- // `[MS-ERREF]`: https://msdn.microsoft.com/en-us/library/cc231198.aspx
- if (errnum & c::FACILITY_NT_BIT as i32) != 0 {
- // format according to https://support.microsoft.com/en-us/help/259693
- const NTDLL_DLL: &'static [u16] = &['N' as _, 'T' as _, 'D' as _, 'L' as _, 'L' as _,
- '.' as _, 'D' as _, 'L' as _, 'L' as _, 0];
- module = c::GetModuleHandleW(NTDLL_DLL.as_ptr());
-
- if module != ptr::null_mut() {
- errnum ^= c::FACILITY_NT_BIT as i32;
- flags = c::FORMAT_MESSAGE_FROM_HMODULE;
- }
- }
-
- let res = c::FormatMessageW(flags | c::FORMAT_MESSAGE_FROM_SYSTEM |
- c::FORMAT_MESSAGE_IGNORE_INSERTS,
- module,
- errnum as c::DWORD,
- langId,
- buf.as_mut_ptr(),
- buf.len() as c::DWORD,
- ptr::null()) as usize;
- if res == 0 {
- // Sometimes FormatMessageW can fail e.g. system doesn't like langId,
- let fm_err = errno();
- return format!("OS Error {} (FormatMessageW() returned error {})",
- errnum, fm_err);
- }
-
- match String::from_utf16(&buf[..res]) {
- Ok(mut msg) => {
- // Trim trailing CRLF inserted by FormatMessageW
- let len = msg.trim_right().len();
- msg.truncate(len);
- msg
- },
- Err(..) => format!("OS Error {} (FormatMessageW() returned \
- invalid UTF-16)", errnum),
- }
- }
-}
-
-pub struct Env {
- base: c::LPWCH,
- cur: c::LPWCH,
-}
-
-impl Iterator for Env {
- type Item = (OsString, OsString);
-
- fn next(&mut self) -> Option<(OsString, OsString)> {
- loop {
- unsafe {
- if *self.cur == 0 { return None }
- let p = &*self.cur as *const u16;
- let mut len = 0;
- while *p.offset(len) != 0 {
- len += 1;
- }
- let s = slice::from_raw_parts(p, len as usize);
- self.cur = self.cur.offset(len + 1);
-
- // Windows allows environment variables to start with an equals
- // symbol (in any other position, this is the separator between
- // variable name and value). Since`s` has at least length 1 at
- // this point (because the empty string terminates the array of
- // environment variables), we can safely slice.
- let pos = match s[1..].iter().position(|&u| u == b'=' as u16).map(|p| p + 1) {
- Some(p) => p,
- None => continue,
- };
- return Some((
- OsStringExt::from_wide(&s[..pos]),
- OsStringExt::from_wide(&s[pos+1..]),
- ))
- }
- }
- }
-}
-
-impl Drop for Env {
- fn drop(&mut self) {
- unsafe { c::FreeEnvironmentStringsW(self.base); }
- }
-}
-
-pub fn env() -> Env {
- unsafe {
- let ch = c::GetEnvironmentStringsW();
- if ch as usize == 0 {
- panic!("failure getting env string from OS: {}",
- io::Error::last_os_error());
- }
- Env { base: ch, cur: ch }
- }
-}
-
-pub struct SplitPaths<'a> {
- data: EncodeWide<'a>,
- must_yield: bool,
-}
-
-pub fn split_paths(unparsed: &OsStr) -> SplitPaths {
- SplitPaths {
- data: unparsed.encode_wide(),
- must_yield: true,
- }
-}
-
-impl<'a> Iterator for SplitPaths<'a> {
- type Item = PathBuf;
- fn next(&mut self) -> Option<PathBuf> {
- // On Windows, the PATH environment variable is semicolon separated.
- // Double quotes are used as a way of introducing literal semicolons
- // (since c:\some;dir is a valid Windows path). Double quotes are not
- // themselves permitted in path names, so there is no way to escape a
- // double quote. Quoted regions can appear in arbitrary locations, so
- //
- // c:\foo;c:\som"e;di"r;c:\bar
- //
- // Should parse as [c:\foo, c:\some;dir, c:\bar].
- //
- // (The above is based on testing; there is no clear reference available
- // for the grammar.)
-
-
- let must_yield = self.must_yield;
- self.must_yield = false;
-
- let mut in_progress = Vec::new();
- let mut in_quote = false;
- for b in self.data.by_ref() {
- if b == '"' as u16 {
- in_quote = !in_quote;
- } else if b == ';' as u16 && !in_quote {
- self.must_yield = true;
- break
- } else {
- in_progress.push(b)
- }
- }
-
- if !must_yield && in_progress.is_empty() {
- None
- } else {
- Some(super::os2path(&in_progress))
- }
- }
-}
-
-#[derive(Debug)]
-pub struct JoinPathsError;
-
-pub fn join_paths<I, T>(paths: I) -> Result<OsString, JoinPathsError>
- where I: Iterator<Item=T>, T: AsRef<OsStr>
-{
- let mut joined = Vec::new();
- let sep = b';' as u16;
-
- for (i, path) in paths.enumerate() {
- let path = path.as_ref();
- if i > 0 { joined.push(sep) }
- let v = path.encode_wide().collect::<Vec<u16>>();
- if v.contains(&(b'"' as u16)) {
- return Err(JoinPathsError)
- } else if v.contains(&sep) {
- joined.push(b'"' as u16);
- joined.extend_from_slice(&v[..]);
- joined.push(b'"' as u16);
- } else {
- joined.extend_from_slice(&v[..]);
- }
- }
-
- Ok(OsStringExt::from_wide(&joined[..]))
-}
-
-impl fmt::Display for JoinPathsError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- "path segment contains `\"`".fmt(f)
- }
-}
-
-impl StdError for JoinPathsError {
- fn description(&self) -> &str { "failed to join paths" }
-}
-
-pub fn current_exe() -> io::Result<PathBuf> {
- super::fill_utf16_buf(|buf, sz| unsafe {
- c::GetModuleFileNameW(ptr::null_mut(), buf, sz)
- }, super::os2path)
-}
-
-pub fn getcwd() -> io::Result<PathBuf> {
- super::fill_utf16_buf(|buf, sz| unsafe {
- c::GetCurrentDirectoryW(sz, buf)
- }, super::os2path)
-}
-
-pub fn chdir(p: &path::Path) -> io::Result<()> {
- let p: &OsStr = p.as_ref();
- let mut p = p.encode_wide().collect::<Vec<_>>();
- p.push(0);
-
- cvt(unsafe {
- c::SetCurrentDirectoryW(p.as_ptr())
- }).map(|_| ())
-}
-
-pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
- let k = to_u16s(k)?;
- let res = super::fill_utf16_buf(|buf, sz| unsafe {
- c::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
- }, |buf| {
- OsStringExt::from_wide(buf)
- });
- match res {
- Ok(value) => Ok(Some(value)),
- Err(e) => {
- if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND as i32) {
- Ok(None)
- } else {
- Err(e)
- }
- }
- }
-}
-
-pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
- let k = to_u16s(k)?;
- let v = to_u16s(v)?;
-
- cvt(unsafe {
- c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
- }).map(|_| ())
-}
-
-pub fn unsetenv(n: &OsStr) -> io::Result<()> {
- let v = to_u16s(n)?;
- cvt(unsafe {
- c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
- }).map(|_| ())
-}
-
-pub fn temp_dir() -> PathBuf {
- super::fill_utf16_buf(|buf, sz| unsafe {
- c::GetTempPathW(sz, buf)
- }, super::os2path).unwrap()
-}
-
-pub fn home_dir() -> Option<PathBuf> {
- ::env::var_os("HOME").or_else(|| {
- ::env::var_os("USERPROFILE")
- }).map(PathBuf::from).or_else(|| unsafe {
- let me = c::GetCurrentProcess();
- let mut token = ptr::null_mut();
- if c::OpenProcessToken(me, c::TOKEN_READ, &mut token) == 0 {
- return None
- }
- let _handle = Handle::new(token);
- super::fill_utf16_buf(|buf, mut sz| {
- match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
- 0 if c::GetLastError() != c::ERROR_INSUFFICIENT_BUFFER => 0,
- 0 => sz,
- _ => sz - 1, // sz includes the null terminator
- }
- }, super::os2path).ok()
- })
-}
-
-pub fn exit(code: i32) -> ! {
- unsafe { c::ExitProcess(code as c::UINT) }
-}
-
-pub fn getpid() -> u32 {
- unsafe { c::GetCurrentProcessId() as u32 }
-}
-
-#[cfg(test)]
-mod tests {
- use io::Error;
- use sys::c;
-
- // tests `error_string` above
- #[test]
- fn ntstatus_error() {
- const STATUS_UNSUCCESSFUL: u32 = 0xc000_0001;
- assert!(!Error::from_raw_os_error((STATUS_UNSUCCESSFUL | c::FACILITY_NT_BIT) as _)
- .to_string().contains("FormatMessageW() returned error"));
- }
-}
diff --git a/ctr-std/src/sys/windows/os_str.rs b/ctr-std/src/sys/windows/os_str.rs
deleted file mode 100644
index bcc66b9..0000000
--- a/ctr-std/src/sys/windows/os_str.rs
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/// The underlying OsString/OsStr implementation on Windows is a
-/// wrapper around the "WTF-8" encoding; see the `wtf8` module for more.
-
-use borrow::Cow;
-use fmt;
-use sys_common::wtf8::{Wtf8, Wtf8Buf};
-use mem;
-use rc::Rc;
-use sync::Arc;
-use sys_common::{AsInner, IntoInner, FromInner};
-
-#[derive(Clone, Hash)]
-pub struct Buf {
- pub inner: Wtf8Buf
-}
-
-impl IntoInner<Wtf8Buf> for Buf {
- fn into_inner(self) -> Wtf8Buf {
- self.inner
- }
-}
-
-impl FromInner<Wtf8Buf> for Buf {
- fn from_inner(inner: Wtf8Buf) -> Self {
- Buf { inner }
- }
-}
-
-impl AsInner<Wtf8> for Buf {
- fn as_inner(&self) -> &Wtf8 {
- &self.inner
- }
-}
-
-impl fmt::Debug for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(self.as_slice(), formatter)
- }
-}
-
-impl fmt::Display for Buf {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(self.as_slice(), formatter)
- }
-}
-
-pub struct Slice {
- pub inner: Wtf8
-}
-
-impl fmt::Debug for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Debug::fmt(&self.inner, formatter)
- }
-}
-
-impl fmt::Display for Slice {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- fmt::Display::fmt(&self.inner, formatter)
- }
-}
-
-impl Buf {
- pub fn with_capacity(capacity: usize) -> Buf {
- Buf {
- inner: Wtf8Buf::with_capacity(capacity)
- }
- }
-
- pub fn clear(&mut self) {
- self.inner.clear()
- }
-
- pub fn capacity(&self) -> usize {
- self.inner.capacity()
- }
-
- pub fn from_string(s: String) -> Buf {
- Buf { inner: Wtf8Buf::from_string(s) }
- }
-
- pub fn as_slice(&self) -> &Slice {
- unsafe { mem::transmute(self.inner.as_slice()) }
- }
-
- pub fn into_string(self) -> Result<String, Buf> {
- self.inner.into_string().map_err(|buf| Buf { inner: buf })
- }
-
- pub fn push_slice(&mut self, s: &Slice) {
- self.inner.push_wtf8(&s.inner)
- }
-
- pub fn reserve(&mut self, additional: usize) {
- self.inner.reserve(additional)
- }
-
- pub fn reserve_exact(&mut self, additional: usize) {
- self.inner.reserve_exact(additional)
- }
-
- pub fn shrink_to_fit(&mut self) {
- self.inner.shrink_to_fit()
- }
-
- #[inline]
- pub fn shrink_to(&mut self, min_capacity: usize) {
- self.inner.shrink_to(min_capacity)
- }
-
- #[inline]
- pub fn into_box(self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_box()) }
- }
-
- #[inline]
- pub fn from_box(boxed: Box<Slice>) -> Buf {
- let inner: Box<Wtf8> = unsafe { mem::transmute(boxed) };
- Buf { inner: Wtf8Buf::from_box(inner) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- self.as_slice().into_arc()
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- self.as_slice().into_rc()
- }
-}
-
-impl Slice {
- pub fn from_str(s: &str) -> &Slice {
- unsafe { mem::transmute(Wtf8::from_str(s)) }
- }
-
- pub fn to_str(&self) -> Option<&str> {
- self.inner.as_str()
- }
-
- pub fn to_string_lossy(&self) -> Cow<str> {
- self.inner.to_string_lossy()
- }
-
- pub fn to_owned(&self) -> Buf {
- let mut buf = Wtf8Buf::with_capacity(self.inner.len());
- buf.push_wtf8(&self.inner);
- Buf { inner: buf }
- }
-
- #[inline]
- pub fn into_box(&self) -> Box<Slice> {
- unsafe { mem::transmute(self.inner.into_box()) }
- }
-
- pub fn empty_box() -> Box<Slice> {
- unsafe { mem::transmute(Wtf8::empty_box()) }
- }
-
- #[inline]
- pub fn into_arc(&self) -> Arc<Slice> {
- let arc = self.inner.into_arc();
- unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
- }
-
- #[inline]
- pub fn into_rc(&self) -> Rc<Slice> {
- let rc = self.inner.into_rc();
- unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
- }
-}
diff --git a/ctr-std/src/sys/windows/path.rs b/ctr-std/src/sys/windows/path.rs
deleted file mode 100644
index 98d62a0..0000000
--- a/ctr-std/src/sys/windows/path.rs
+++ /dev/null
@@ -1,106 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use path::Prefix;
-use ffi::OsStr;
-use mem;
-
-fn os_str_as_u8_slice(s: &OsStr) -> &[u8] {
- unsafe { mem::transmute(s) }
-}
-unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
- mem::transmute(s)
-}
-
-#[inline]
-pub fn is_sep_byte(b: u8) -> bool {
- b == b'/' || b == b'\\'
-}
-
-#[inline]
-pub fn is_verbatim_sep(b: u8) -> bool {
- b == b'\\'
-}
-
-pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
- use path::Prefix::*;
- unsafe {
- // The unsafety here stems from converting between &OsStr and &[u8]
- // and back. This is safe to do because (1) we only look at ASCII
- // contents of the encoding and (2) new &OsStr values are produced
- // only from ASCII-bounded slices of existing &OsStr values.
- let mut path = os_str_as_u8_slice(path);
-
- if path.starts_with(br"\\") {
- // \\
- path = &path[2..];
- if path.starts_with(br"?\") {
- // \\?\
- path = &path[2..];
- if path.starts_with(br"UNC\") {
- // \\?\UNC\server\share
- path = &path[4..];
- let (server, share) = match parse_two_comps(path, is_verbatim_sep) {
- Some((server, share)) =>
- (u8_slice_as_os_str(server), u8_slice_as_os_str(share)),
- None => (u8_slice_as_os_str(path), u8_slice_as_os_str(&[])),
- };
- return Some(VerbatimUNC(server, share));
- } else {
- // \\?\path
- let idx = path.iter().position(|&b| b == b'\\');
- if idx == Some(2) && path[1] == b':' {
- let c = path[0];
- if c.is_ascii() && (c as char).is_alphabetic() {
- // \\?\C:\ path
- return Some(VerbatimDisk(c.to_ascii_uppercase()));
- }
- }
- let slice = &path[..idx.unwrap_or(path.len())];
- return Some(Verbatim(u8_slice_as_os_str(slice)));
- }
- } else if path.starts_with(b".\\") {
- // \\.\path
- path = &path[2..];
- let pos = path.iter().position(|&b| b == b'\\');
- let slice = &path[..pos.unwrap_or(path.len())];
- return Some(DeviceNS(u8_slice_as_os_str(slice)));
- }
- match parse_two_comps(path, is_sep_byte) {
- Some((server, share)) if !server.is_empty() && !share.is_empty() => {
- // \\server\share
- return Some(UNC(u8_slice_as_os_str(server), u8_slice_as_os_str(share)));
- }
- _ => (),
- }
- } else if path.get(1) == Some(& b':') {
- // C:
- let c = path[0];
- if c.is_ascii() && (c as char).is_alphabetic() {
- return Some(Disk(c.to_ascii_uppercase()));
- }
- }
- return None;
- }
-
- fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> {
- let first = match path.iter().position(|x| f(*x)) {
- None => return None,
- Some(x) => &path[..x],
- };
- path = &path[(first.len() + 1)..];
- let idx = path.iter().position(|x| f(*x));
- let second = &path[..idx.unwrap_or(path.len())];
- Some((first, second))
- }
-}
-
-pub const MAIN_SEP_STR: &'static str = "\\";
-pub const MAIN_SEP: char = '\\';
diff --git a/ctr-std/src/sys/windows/pipe.rs b/ctr-std/src/sys/windows/pipe.rs
deleted file mode 100644
index df1dd74..0000000
--- a/ctr-std/src/sys/windows/pipe.rs
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use os::windows::prelude::*;
-
-use ffi::OsStr;
-use io;
-use mem;
-use path::Path;
-use ptr;
-use slice;
-use sync::atomic::Ordering::SeqCst;
-use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT};
-use sys::c;
-use sys::fs::{File, OpenOptions};
-use sys::handle::Handle;
-use sys::hashmap_random_keys;
-
-////////////////////////////////////////////////////////////////////////////////
-// Anonymous pipes
-////////////////////////////////////////////////////////////////////////////////
-
-pub struct AnonPipe {
- inner: Handle,
-}
-
-pub struct Pipes {
- pub ours: AnonPipe,
- pub theirs: AnonPipe,
-}
-
-/// Although this looks similar to `anon_pipe` in the Unix module it's actually
-/// subtly different. Here we'll return two pipes in the `Pipes` return value,
-/// but one is intended for "us" where as the other is intended for "someone
-/// else".
-///
-/// Currently the only use case for this function is pipes for stdio on
-/// processes in the standard library, so "ours" is the one that'll stay in our
-/// process whereas "theirs" will be inherited to a child.
-///
-/// The ours/theirs pipes are *not* specifically readable or writable. Each
-/// one only supports a read or a write, but which is which depends on the
-/// boolean flag given. If `ours_readable` is true then `ours` is readable where
-/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is
-/// writable where `theirs` is readable.
-///
-/// Also note that the `ours` pipe is always a handle opened up in overlapped
-/// mode. This means that technically speaking it should only ever be used
-/// with `OVERLAPPED` instances, but also works out ok if it's only ever used
-/// once at a time (which we do indeed guarantee).
-pub fn anon_pipe(ours_readable: bool) -> io::Result<Pipes> {
- // Note that we specifically do *not* use `CreatePipe` here because
- // unfortunately the anonymous pipes returned do not support overlapped
- // operations. Instead, we create a "hopefully unique" name and create a
- // named pipe which has overlapped operations enabled.
- //
- // Once we do this, we connect do it as usual via `CreateFileW`, and then
- // we return those reader/writer halves. Note that the `ours` pipe return
- // value is always the named pipe, whereas `theirs` is just the normal file.
- // This should hopefully shield us from child processes which assume their
- // stdout is a named pipe, which would indeed be odd!
- unsafe {
- let ours;
- let mut name;
- let mut tries = 0;
- let mut reject_remote_clients_flag = c::PIPE_REJECT_REMOTE_CLIENTS;
- loop {
- tries += 1;
- name = format!(r"\\.\pipe\__rust_anonymous_pipe1__.{}.{}",
- c::GetCurrentProcessId(),
- random_number());
- let wide_name = OsStr::new(&name)
- .encode_wide()
- .chain(Some(0))
- .collect::<Vec<_>>();
- let mut flags = c::FILE_FLAG_FIRST_PIPE_INSTANCE |
- c::FILE_FLAG_OVERLAPPED;
- if ours_readable {
- flags |= c::PIPE_ACCESS_INBOUND;
- } else {
- flags |= c::PIPE_ACCESS_OUTBOUND;
- }
-
- let handle = c::CreateNamedPipeW(wide_name.as_ptr(),
- flags,
- c::PIPE_TYPE_BYTE |
- c::PIPE_READMODE_BYTE |
- c::PIPE_WAIT |
- reject_remote_clients_flag,
- 1,
- 4096,
- 4096,
- 0,
- ptr::null_mut());
-
- // We pass the FILE_FLAG_FIRST_PIPE_INSTANCE flag above, and we're
- // also just doing a best effort at selecting a unique name. If
- // ERROR_ACCESS_DENIED is returned then it could mean that we
- // accidentally conflicted with an already existing pipe, so we try
- // again.
- //
- // Don't try again too much though as this could also perhaps be a
- // legit error.
- // If ERROR_INVALID_PARAMETER is returned, this probably means we're
- // running on pre-Vista version where PIPE_REJECT_REMOTE_CLIENTS is
- // not supported, so we continue retrying without it. This implies
- // reduced security on Windows versions older than Vista by allowing
- // connections to this pipe from remote machines.
- // Proper fix would increase the number of FFI imports and introduce
- // significant amount of Windows XP specific code with no clean
- // testing strategy
- // for more info see https://github.com/rust-lang/rust/pull/37677
- if handle == c::INVALID_HANDLE_VALUE {
- let err = io::Error::last_os_error();
- let raw_os_err = err.raw_os_error();
- if tries < 10 {
- if raw_os_err == Some(c::ERROR_ACCESS_DENIED as i32) {
- continue
- } else if reject_remote_clients_flag != 0 &&
- raw_os_err == Some(c::ERROR_INVALID_PARAMETER as i32) {
- reject_remote_clients_flag = 0;
- tries -= 1;
- continue
- }
- }
- return Err(err)
- }
- ours = Handle::new(handle);
- break
- }
-
- // Connect to the named pipe we just created. This handle is going to be
- // returned in `theirs`, so if `ours` is readable we want this to be
- // writable, otherwise if `ours` is writable we want this to be
- // readable.
- //
- // Additionally we don't enable overlapped mode on this because most
- // client processes aren't enabled to work with that.
- let mut opts = OpenOptions::new();
- opts.write(ours_readable);
- opts.read(!ours_readable);
- opts.share_mode(0);
- let theirs = File::open(Path::new(&name), &opts)?;
- let theirs = AnonPipe { inner: theirs.into_handle() };
-
- Ok(Pipes {
- ours: AnonPipe { inner: ours },
- theirs: AnonPipe { inner: theirs.into_handle() },
- })
- }
-}
-
-fn random_number() -> usize {
- static N: AtomicUsize = ATOMIC_USIZE_INIT;
- loop {
- if N.load(SeqCst) != 0 {
- return N.fetch_add(1, SeqCst)
- }
-
- N.store(hashmap_random_keys().0 as usize, SeqCst);
- }
-}
-
-impl AnonPipe {
- pub fn handle(&self) -> &Handle { &self.inner }
- pub fn into_handle(self) -> Handle { self.inner }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- self.inner.read(buf)
- }
-
- pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
- self.inner.write(buf)
- }
-}
-
-pub fn read2(p1: AnonPipe,
- v1: &mut Vec<u8>,
- p2: AnonPipe,
- v2: &mut Vec<u8>) -> io::Result<()> {
- let p1 = p1.into_handle();
- let p2 = p2.into_handle();
-
- let mut p1 = AsyncPipe::new(p1, v1)?;
- let mut p2 = AsyncPipe::new(p2, v2)?;
- let objs = [p1.event.raw(), p2.event.raw()];
-
- // In a loop we wait for either pipe's scheduled read operation to complete.
- // If the operation completes with 0 bytes, that means EOF was reached, in
- // which case we just finish out the other pipe entirely.
- //
- // Note that overlapped I/O is in general super unsafe because we have to
- // be careful to ensure that all pointers in play are valid for the entire
- // duration of the I/O operation (where tons of operations can also fail).
- // The destructor for `AsyncPipe` ends up taking care of most of this.
- loop {
- let res = unsafe {
- c::WaitForMultipleObjects(2, objs.as_ptr(), c::FALSE, c::INFINITE)
- };
- if res == c::WAIT_OBJECT_0 {
- if !p1.result()? || !p1.schedule_read()? {
- return p2.finish()
- }
- } else if res == c::WAIT_OBJECT_0 + 1 {
- if !p2.result()? || !p2.schedule_read()? {
- return p1.finish()
- }
- } else {
- return Err(io::Error::last_os_error())
- }
- }
-}
-
-struct AsyncPipe<'a> {
- pipe: Handle,
- event: Handle,
- overlapped: Box<c::OVERLAPPED>, // needs a stable address
- dst: &'a mut Vec<u8>,
- state: State,
-}
-
-#[derive(PartialEq, Debug)]
-enum State {
- NotReading,
- Reading,
- Read(usize),
-}
-
-impl<'a> AsyncPipe<'a> {
- fn new(pipe: Handle, dst: &'a mut Vec<u8>) -> io::Result<AsyncPipe<'a>> {
- // Create an event which we'll use to coordinate our overlapped
- // operations, this event will be used in WaitForMultipleObjects
- // and passed as part of the OVERLAPPED handle.
- //
- // Note that we do a somewhat clever thing here by flagging the
- // event as being manually reset and setting it initially to the
- // signaled state. This means that we'll naturally fall through the
- // WaitForMultipleObjects call above for pipes created initially,
- // and the only time an even will go back to "unset" will be once an
- // I/O operation is successfully scheduled (what we want).
- let event = Handle::new_event(true, true)?;
- let mut overlapped: Box<c::OVERLAPPED> = unsafe {
- Box::new(mem::zeroed())
- };
- overlapped.hEvent = event.raw();
- Ok(AsyncPipe {
- pipe,
- overlapped,
- event,
- dst,
- state: State::NotReading,
- })
- }
-
- /// Executes an overlapped read operation.
- ///
- /// Must not currently be reading, and returns whether the pipe is currently
- /// at EOF or not. If the pipe is not at EOF then `result()` must be called
- /// to complete the read later on (may block), but if the pipe is at EOF
- /// then `result()` should not be called as it will just block forever.
- fn schedule_read(&mut self) -> io::Result<bool> {
- assert_eq!(self.state, State::NotReading);
- let amt = unsafe {
- let slice = slice_to_end(self.dst);
- self.pipe.read_overlapped(slice, &mut *self.overlapped)?
- };
-
- // If this read finished immediately then our overlapped event will
- // remain signaled (it was signaled coming in here) and we'll progress
- // down to the method below.
- //
- // Otherwise the I/O operation is scheduled and the system set our event
- // to not signaled, so we flag ourselves into the reading state and move
- // on.
- self.state = match amt {
- Some(0) => return Ok(false),
- Some(amt) => State::Read(amt),
- None => State::Reading,
- };
- Ok(true)
- }
-
- /// Wait for the result of the overlapped operation previously executed.
- ///
- /// Takes a parameter `wait` which indicates if this pipe is currently being
- /// read whether the function should block waiting for the read to complete.
- ///
- /// Return values:
- ///
- /// * `true` - finished any pending read and the pipe is not at EOF (keep
- /// going)
- /// * `false` - finished any pending read and pipe is at EOF (stop issuing
- /// reads)
- fn result(&mut self) -> io::Result<bool> {
- let amt = match self.state {
- State::NotReading => return Ok(true),
- State::Reading => {
- self.pipe.overlapped_result(&mut *self.overlapped, true)?
- }
- State::Read(amt) => amt,
- };
- self.state = State::NotReading;
- unsafe {
- let len = self.dst.len();
- self.dst.set_len(len + amt);
- }
- Ok(amt != 0)
- }
-
- /// Finishes out reading this pipe entirely.
- ///
- /// Waits for any pending and schedule read, and then calls `read_to_end`
- /// if necessary to read all the remaining information.
- fn finish(&mut self) -> io::Result<()> {
- while self.result()? && self.schedule_read()? {
- // ...
- }
- Ok(())
- }
-}
-
-impl<'a> Drop for AsyncPipe<'a> {
- fn drop(&mut self) {
- match self.state {
- State::Reading => {}
- _ => return,
- }
-
- // If we have a pending read operation, then we have to make sure that
- // it's *done* before we actually drop this type. The kernel requires
- // that the `OVERLAPPED` and buffer pointers are valid for the entire
- // I/O operation.
- //
- // To do that, we call `CancelIo` to cancel any pending operation, and
- // if that succeeds we wait for the overlapped result.
- //
- // If anything here fails, there's not really much we can do, so we leak
- // the buffer/OVERLAPPED pointers to ensure we're at least memory safe.
- if self.pipe.cancel_io().is_err() || self.result().is_err() {
- let buf = mem::replace(self.dst, Vec::new());
- let overlapped = Box::new(unsafe { mem::zeroed() });
- let overlapped = mem::replace(&mut self.overlapped, overlapped);
- mem::forget((buf, overlapped));
- }
- }
-}
-
-unsafe fn slice_to_end(v: &mut Vec<u8>) -> &mut [u8] {
- if v.capacity() == 0 {
- v.reserve(16);
- }
- if v.capacity() == v.len() {
- v.reserve(1);
- }
- slice::from_raw_parts_mut(v.as_mut_ptr().offset(v.len() as isize),
- v.capacity() - v.len())
-}
diff --git a/ctr-std/src/sys/windows/process.rs b/ctr-std/src/sys/windows/process.rs
deleted file mode 100644
index 4974a8d..0000000
--- a/ctr-std/src/sys/windows/process.rs
+++ /dev/null
@@ -1,581 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(feature = "process_internals", issue = "0")]
-
-use collections::BTreeMap;
-use env::split_paths;
-use env;
-use ffi::{OsString, OsStr};
-use fmt;
-use fs;
-use io::{self, Error, ErrorKind};
-use libc::{c_void, EXIT_SUCCESS, EXIT_FAILURE};
-use mem;
-use os::windows::ffi::OsStrExt;
-use path::Path;
-use ptr;
-use sys::mutex::Mutex;
-use sys::c;
-use sys::fs::{OpenOptions, File};
-use sys::handle::Handle;
-use sys::pipe::{self, AnonPipe};
-use sys::stdio;
-use sys::cvt;
-use sys_common::{AsInner, FromInner, IntoInner};
-use sys_common::process::{CommandEnv, EnvKey};
-use borrow::Borrow;
-
-////////////////////////////////////////////////////////////////////////////////
-// Command
-////////////////////////////////////////////////////////////////////////////////
-
-#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd)]
-#[doc(hidden)]
-pub struct WindowsEnvKey(OsString);
-
-impl From<OsString> for WindowsEnvKey {
- fn from(k: OsString) -> Self {
- let mut buf = k.into_inner().into_inner();
- buf.make_ascii_uppercase();
- WindowsEnvKey(FromInner::from_inner(FromInner::from_inner(buf)))
- }
-}
-
-impl From<WindowsEnvKey> for OsString {
- fn from(k: WindowsEnvKey) -> Self { k.0 }
-}
-
-impl Borrow<OsStr> for WindowsEnvKey {
- fn borrow(&self) -> &OsStr { &self.0 }
-}
-
-impl AsRef<OsStr> for WindowsEnvKey {
- fn as_ref(&self) -> &OsStr { &self.0 }
-}
-
-impl EnvKey for WindowsEnvKey {}
-
-
-fn ensure_no_nuls<T: AsRef<OsStr>>(str: T) -> io::Result<T> {
- if str.as_ref().encode_wide().any(|b| b == 0) {
- Err(io::Error::new(ErrorKind::InvalidInput, "nul byte found in provided data"))
- } else {
- Ok(str)
- }
-}
-
-pub struct Command {
- program: OsString,
- args: Vec<OsString>,
- env: CommandEnv<WindowsEnvKey>,
- cwd: Option<OsString>,
- flags: u32,
- detach: bool, // not currently exposed in std::process
- stdin: Option<Stdio>,
- stdout: Option<Stdio>,
- stderr: Option<Stdio>,
-}
-
-pub enum Stdio {
- Inherit,
- Null,
- MakePipe,
- Handle(Handle),
-}
-
-pub struct StdioPipes {
- pub stdin: Option<AnonPipe>,
- pub stdout: Option<AnonPipe>,
- pub stderr: Option<AnonPipe>,
-}
-
-struct DropGuard<'a> {
- lock: &'a Mutex,
-}
-
-impl Command {
- pub fn new(program: &OsStr) -> Command {
- Command {
- program: program.to_os_string(),
- args: Vec::new(),
- env: Default::default(),
- cwd: None,
- flags: 0,
- detach: false,
- stdin: None,
- stdout: None,
- stderr: None,
- }
- }
-
- pub fn arg(&mut self, arg: &OsStr) {
- self.args.push(arg.to_os_string())
- }
- pub fn env_mut(&mut self) -> &mut CommandEnv<WindowsEnvKey> {
- &mut self.env
- }
- pub fn cwd(&mut self, dir: &OsStr) {
- self.cwd = Some(dir.to_os_string())
- }
- pub fn stdin(&mut self, stdin: Stdio) {
- self.stdin = Some(stdin);
- }
- pub fn stdout(&mut self, stdout: Stdio) {
- self.stdout = Some(stdout);
- }
- pub fn stderr(&mut self, stderr: Stdio) {
- self.stderr = Some(stderr);
- }
- pub fn creation_flags(&mut self, flags: u32) {
- self.flags = flags;
- }
-
- pub fn spawn(&mut self, default: Stdio, needs_stdin: bool)
- -> io::Result<(Process, StdioPipes)> {
- let maybe_env = self.env.capture_if_changed();
- // To have the spawning semantics of unix/windows stay the same, we need
- // to read the *child's* PATH if one is provided. See #15149 for more
- // details.
- let program = maybe_env.as_ref().and_then(|env| {
- if let Some(v) = env.get(OsStr::new("PATH")) {
- // Split the value and test each path to see if the
- // program exists.
- for path in split_paths(&v) {
- let path = path.join(self.program.to_str().unwrap())
- .with_extension(env::consts::EXE_EXTENSION);
- if fs::metadata(&path).is_ok() {
- return Some(path.into_os_string())
- }
- }
- }
- None
- });
-
- let mut si = zeroed_startupinfo();
- si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
- si.dwFlags = c::STARTF_USESTDHANDLES;
-
- let program = program.as_ref().unwrap_or(&self.program);
- let mut cmd_str = make_command_line(program, &self.args)?;
- cmd_str.push(0); // add null terminator
-
- // stolen from the libuv code.
- let mut flags = self.flags | c::CREATE_UNICODE_ENVIRONMENT;
- if self.detach {
- flags |= c::DETACHED_PROCESS | c::CREATE_NEW_PROCESS_GROUP;
- }
-
- let (envp, _data) = make_envp(maybe_env)?;
- let (dirp, _data) = make_dirp(self.cwd.as_ref())?;
- let mut pi = zeroed_process_information();
-
- // Prepare all stdio handles to be inherited by the child. This
- // currently involves duplicating any existing ones with the ability to
- // be inherited by child processes. Note, however, that once an
- // inheritable handle is created, *any* spawned child will inherit that
- // handle. We only want our own child to inherit this handle, so we wrap
- // the remaining portion of this spawn in a mutex.
- //
- // For more information, msdn also has an article about this race:
- // http://support.microsoft.com/kb/315939
- static CREATE_PROCESS_LOCK: Mutex = Mutex::new();
- let _guard = DropGuard::new(&CREATE_PROCESS_LOCK);
-
- let mut pipes = StdioPipes {
- stdin: None,
- stdout: None,
- stderr: None,
- };
- let null = Stdio::Null;
- let default_stdin = if needs_stdin {&default} else {&null};
- let stdin = self.stdin.as_ref().unwrap_or(default_stdin);
- let stdout = self.stdout.as_ref().unwrap_or(&default);
- let stderr = self.stderr.as_ref().unwrap_or(&default);
- let stdin = stdin.to_handle(c::STD_INPUT_HANDLE, &mut pipes.stdin)?;
- let stdout = stdout.to_handle(c::STD_OUTPUT_HANDLE,
- &mut pipes.stdout)?;
- let stderr = stderr.to_handle(c::STD_ERROR_HANDLE,
- &mut pipes.stderr)?;
- si.hStdInput = stdin.raw();
- si.hStdOutput = stdout.raw();
- si.hStdError = stderr.raw();
-
- unsafe {
- cvt(c::CreateProcessW(ptr::null(),
- cmd_str.as_mut_ptr(),
- ptr::null_mut(),
- ptr::null_mut(),
- c::TRUE, flags, envp, dirp,
- &mut si, &mut pi))
- }?;
-
- // We close the thread handle because we don't care about keeping
- // the thread id valid, and we aren't keeping the thread handle
- // around to be able to close it later.
- drop(Handle::new(pi.hThread));
-
- Ok((Process { handle: Handle::new(pi.hProcess) }, pipes))
- }
-
-}
-
-impl fmt::Debug for Command {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}", self.program)?;
- for arg in &self.args {
- write!(f, " {:?}", arg)?;
- }
- Ok(())
- }
-}
-
-impl<'a> DropGuard<'a> {
- fn new(lock: &'a Mutex) -> DropGuard<'a> {
- unsafe {
- lock.lock();
- DropGuard { lock: lock }
- }
- }
-}
-
-impl<'a> Drop for DropGuard<'a> {
- fn drop(&mut self) {
- unsafe {
- self.lock.unlock();
- }
- }
-}
-
-impl Stdio {
- fn to_handle(&self, stdio_id: c::DWORD, pipe: &mut Option<AnonPipe>)
- -> io::Result<Handle> {
- match *self {
- // If no stdio handle is available, then inherit means that it
- // should still be unavailable so propagate the
- // INVALID_HANDLE_VALUE.
- Stdio::Inherit => {
- match stdio::get(stdio_id) {
- Ok(io) => {
- let io = Handle::new(io.handle());
- let ret = io.duplicate(0, true,
- c::DUPLICATE_SAME_ACCESS);
- io.into_raw();
- return ret
- }
- Err(..) => Ok(Handle::new(c::INVALID_HANDLE_VALUE)),
- }
- }
-
- Stdio::MakePipe => {
- let ours_readable = stdio_id != c::STD_INPUT_HANDLE;
- let pipes = pipe::anon_pipe(ours_readable)?;
- *pipe = Some(pipes.ours);
- cvt(unsafe {
- c::SetHandleInformation(pipes.theirs.handle().raw(),
- c::HANDLE_FLAG_INHERIT,
- c::HANDLE_FLAG_INHERIT)
- })?;
- Ok(pipes.theirs.into_handle())
- }
-
- Stdio::Handle(ref handle) => {
- handle.duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
- }
-
- // Open up a reference to NUL with appropriate read/write
- // permissions as well as the ability to be inherited to child
- // processes (as this is about to be inherited).
- Stdio::Null => {
- let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
- let mut sa = c::SECURITY_ATTRIBUTES {
- nLength: size as c::DWORD,
- lpSecurityDescriptor: ptr::null_mut(),
- bInheritHandle: 1,
- };
- let mut opts = OpenOptions::new();
- opts.read(stdio_id == c::STD_INPUT_HANDLE);
- opts.write(stdio_id != c::STD_INPUT_HANDLE);
- opts.security_attributes(&mut sa);
- File::open(Path::new("NUL"), &opts).map(|file| {
- file.into_handle()
- })
- }
- }
- }
-}
-
-impl From<AnonPipe> for Stdio {
- fn from(pipe: AnonPipe) -> Stdio {
- Stdio::Handle(pipe.into_handle())
- }
-}
-
-impl From<File> for Stdio {
- fn from(file: File) -> Stdio {
- Stdio::Handle(file.into_handle())
- }
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Processes
-////////////////////////////////////////////////////////////////////////////////
-
-/// A value representing a child process.
-///
-/// The lifetime of this value is linked to the lifetime of the actual
-/// process - the Process destructor calls self.finish() which waits
-/// for the process to terminate.
-pub struct Process {
- handle: Handle,
-}
-
-impl Process {
- pub fn kill(&mut self) -> io::Result<()> {
- cvt(unsafe {
- c::TerminateProcess(self.handle.raw(), 1)
- })?;
- Ok(())
- }
-
- pub fn id(&self) -> u32 {
- unsafe {
- c::GetProcessId(self.handle.raw()) as u32
- }
- }
-
- pub fn wait(&mut self) -> io::Result<ExitStatus> {
- unsafe {
- let res = c::WaitForSingleObject(self.handle.raw(), c::INFINITE);
- if res != c::WAIT_OBJECT_0 {
- return Err(Error::last_os_error())
- }
- let mut status = 0;
- cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?;
- Ok(ExitStatus(status))
- }
- }
-
- pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
- unsafe {
- match c::WaitForSingleObject(self.handle.raw(), 0) {
- c::WAIT_OBJECT_0 => {}
- c::WAIT_TIMEOUT => {
- return Ok(None);
- }
- _ => return Err(io::Error::last_os_error()),
- }
- let mut status = 0;
- cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status))?;
- Ok(Some(ExitStatus(status)))
- }
- }
-
- pub fn handle(&self) -> &Handle { &self.handle }
-
- pub fn into_handle(self) -> Handle { self.handle }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitStatus(c::DWORD);
-
-impl ExitStatus {
- pub fn success(&self) -> bool {
- self.0 == 0
- }
- pub fn code(&self) -> Option<i32> {
- Some(self.0 as i32)
- }
-}
-
-impl From<c::DWORD> for ExitStatus {
- fn from(u: c::DWORD) -> ExitStatus {
- ExitStatus(u)
- }
-}
-
-impl fmt::Display for ExitStatus {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "exit code: {}", self.0)
- }
-}
-
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitCode(c::DWORD);
-
-impl ExitCode {
- pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
- pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);
-
- #[inline]
- pub fn as_i32(&self) -> i32 {
- self.0 as i32
- }
-}
-
-fn zeroed_startupinfo() -> c::STARTUPINFO {
- c::STARTUPINFO {
- cb: 0,
- lpReserved: ptr::null_mut(),
- lpDesktop: ptr::null_mut(),
- lpTitle: ptr::null_mut(),
- dwX: 0,
- dwY: 0,
- dwXSize: 0,
- dwYSize: 0,
- dwXCountChars: 0,
- dwYCountCharts: 0,
- dwFillAttribute: 0,
- dwFlags: 0,
- wShowWindow: 0,
- cbReserved2: 0,
- lpReserved2: ptr::null_mut(),
- hStdInput: c::INVALID_HANDLE_VALUE,
- hStdOutput: c::INVALID_HANDLE_VALUE,
- hStdError: c::INVALID_HANDLE_VALUE,
- }
-}
-
-fn zeroed_process_information() -> c::PROCESS_INFORMATION {
- c::PROCESS_INFORMATION {
- hProcess: ptr::null_mut(),
- hThread: ptr::null_mut(),
- dwProcessId: 0,
- dwThreadId: 0
- }
-}
-
-// Produces a wide string *without terminating null*; returns an error if
-// `prog` or any of the `args` contain a nul.
-fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result<Vec<u16>> {
- // Encode the command and arguments in a command line string such
- // that the spawned process may recover them using CommandLineToArgvW.
- let mut cmd: Vec<u16> = Vec::new();
- // Always quote the program name so CreateProcess doesn't interpret args as
- // part of the name if the binary wasn't found first time.
- append_arg(&mut cmd, prog, true)?;
- for arg in args {
- cmd.push(' ' as u16);
- append_arg(&mut cmd, arg, false)?;
- }
- return Ok(cmd);
-
- fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, force_quotes: bool) -> io::Result<()> {
- // If an argument has 0 characters then we need to quote it to ensure
- // that it actually gets passed through on the command line or otherwise
- // it will be dropped entirely when parsed on the other end.
- ensure_no_nuls(arg)?;
- let arg_bytes = &arg.as_inner().inner.as_inner();
- let quote = force_quotes || arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t')
- || arg_bytes.is_empty();
- if quote {
- cmd.push('"' as u16);
- }
-
- let mut iter = arg.encode_wide();
- let mut backslashes: usize = 0;
- while let Some(x) = iter.next() {
- if x == '\\' as u16 {
- backslashes += 1;
- } else {
- if x == '"' as u16 {
- // Add n+1 backslashes to total 2n+1 before internal '"'.
- cmd.extend((0..(backslashes + 1)).map(|_| '\\' as u16));
- }
- backslashes = 0;
- }
- cmd.push(x);
- }
-
- if quote {
- // Add n backslashes to total 2n before ending '"'.
- cmd.extend((0..backslashes).map(|_| '\\' as u16));
- cmd.push('"' as u16);
- }
- Ok(())
- }
-}
-
-fn make_envp(maybe_env: Option<BTreeMap<WindowsEnvKey, OsString>>)
- -> io::Result<(*mut c_void, Vec<u16>)> {
- // On Windows we pass an "environment block" which is not a char**, but
- // rather a concatenation of null-terminated k=v\0 sequences, with a final
- // \0 to terminate.
- if let Some(env) = maybe_env {
- let mut blk = Vec::new();
-
- for (k, v) in env {
- blk.extend(ensure_no_nuls(k.0)?.encode_wide());
- blk.push('=' as u16);
- blk.extend(ensure_no_nuls(v)?.encode_wide());
- blk.push(0);
- }
- blk.push(0);
- Ok((blk.as_mut_ptr() as *mut c_void, blk))
- } else {
- Ok((ptr::null_mut(), Vec::new()))
- }
-}
-
-fn make_dirp(d: Option<&OsString>) -> io::Result<(*const u16, Vec<u16>)> {
-
- match d {
- Some(dir) => {
- let mut dir_str: Vec<u16> = ensure_no_nuls(dir)?.encode_wide().collect();
- dir_str.push(0);
- Ok((dir_str.as_ptr(), dir_str))
- },
- None => Ok((ptr::null(), Vec::new()))
- }
-}
-
-#[cfg(test)]
-mod tests {
- use ffi::{OsStr, OsString};
- use super::make_command_line;
-
- #[test]
- fn test_make_command_line() {
- fn test_wrapper(prog: &str, args: &[&str]) -> String {
- let command_line = &make_command_line(OsStr::new(prog),
- &args.iter()
- .map(|a| OsString::from(a))
- .collect::<Vec<OsString>>())
- .unwrap();
- String::from_utf16(command_line).unwrap()
- }
-
- assert_eq!(
- test_wrapper("prog", &["aaa", "bbb", "ccc"]),
- "\"prog\" aaa bbb ccc"
- );
-
- assert_eq!(
- test_wrapper("C:\\Program Files\\blah\\blah.exe", &["aaa"]),
- "\"C:\\Program Files\\blah\\blah.exe\" aaa"
- );
- assert_eq!(
- test_wrapper("C:\\Program Files\\test", &["aa\"bb"]),
- "\"C:\\Program Files\\test\" aa\\\"bb"
- );
- assert_eq!(
- test_wrapper("echo", &["a b c"]),
- "\"echo\" \"a b c\""
- );
- assert_eq!(
- test_wrapper("echo", &["\" \\\" \\", "\\"]),
- "\"echo\" \"\\\" \\\\\\\" \\\\\" \\"
- );
- assert_eq!(
- test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]),
- "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\""
- );
- }
-}
diff --git a/ctr-std/src/sys/windows/rand.rs b/ctr-std/src/sys/windows/rand.rs
deleted file mode 100644
index 2623236..0000000
--- a/ctr-std/src/sys/windows/rand.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use io;
-use mem;
-use sys::c;
-
-pub fn hashmap_random_keys() -> (u64, u64) {
- let mut v = (0, 0);
- let ret = unsafe {
- c::RtlGenRandom(&mut v as *mut _ as *mut u8,
- mem::size_of_val(&v) as c::ULONG)
- };
- if ret == 0 {
- panic!("couldn't generate random bytes: {}",
- io::Error::last_os_error());
- }
- return v
-}
diff --git a/ctr-std/src/sys/windows/rwlock.rs b/ctr-std/src/sys/windows/rwlock.rs
deleted file mode 100644
index 3e81ebf..0000000
--- a/ctr-std/src/sys/windows/rwlock.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cell::UnsafeCell;
-use sys::c;
-
-pub struct RWLock { inner: UnsafeCell<c::SRWLOCK> }
-
-unsafe impl Send for RWLock {}
-unsafe impl Sync for RWLock {}
-
-impl RWLock {
- pub const fn new() -> RWLock {
- RWLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) }
- }
- #[inline]
- pub unsafe fn read(&self) {
- c::AcquireSRWLockShared(self.inner.get())
- }
- #[inline]
- pub unsafe fn try_read(&self) -> bool {
- c::TryAcquireSRWLockShared(self.inner.get()) != 0
- }
- #[inline]
- pub unsafe fn write(&self) {
- c::AcquireSRWLockExclusive(self.inner.get())
- }
- #[inline]
- pub unsafe fn try_write(&self) -> bool {
- c::TryAcquireSRWLockExclusive(self.inner.get()) != 0
- }
- #[inline]
- pub unsafe fn read_unlock(&self) {
- c::ReleaseSRWLockShared(self.inner.get())
- }
- #[inline]
- pub unsafe fn write_unlock(&self) {
- c::ReleaseSRWLockExclusive(self.inner.get())
- }
-
- #[inline]
- pub unsafe fn destroy(&self) {
- // ...
- }
-}
diff --git a/ctr-std/src/sys/windows/stack_overflow.rs b/ctr-std/src/sys/windows/stack_overflow.rs
deleted file mode 100644
index 4a406d7..0000000
--- a/ctr-std/src/sys/windows/stack_overflow.rs
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![cfg_attr(test, allow(dead_code))]
-
-use sys_common::util::report_overflow;
-use sys::c;
-
-pub struct Handler;
-
-impl Handler {
- pub unsafe fn new() -> Handler {
- // This API isn't available on XP, so don't panic in that case and just
- // pray it works out ok.
- if c::SetThreadStackGuarantee(&mut 0x5000) == 0 {
- if c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32 {
- panic!("failed to reserve stack space for exception handling");
- }
- }
- Handler
- }
-}
-
-extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS)
- -> c::LONG {
- unsafe {
- let rec = &(*(*ExceptionInfo).ExceptionRecord);
- let code = rec.ExceptionCode;
-
- if code == c::EXCEPTION_STACK_OVERFLOW {
- report_overflow();
- }
- c::EXCEPTION_CONTINUE_SEARCH
- }
-}
-
-pub unsafe fn init() {
- if c::AddVectoredExceptionHandler(0, vectored_handler).is_null() {
- panic!("failed to install exception handler");
- }
- // Set the thread stack guarantee for the main thread.
- let _h = Handler::new();
-}
-
-pub unsafe fn cleanup() {}
diff --git a/ctr-std/src/sys/windows/stdio.rs b/ctr-std/src/sys/windows/stdio.rs
deleted file mode 100644
index 81b89da..0000000
--- a/ctr-std/src/sys/windows/stdio.rs
+++ /dev/null
@@ -1,233 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![unstable(issue = "0", feature = "windows_stdio")]
-
-use io::prelude::*;
-
-use cmp;
-use io::{self, Cursor};
-use ptr;
-use str;
-use sync::Mutex;
-use sys::c;
-use sys::cvt;
-use sys::handle::Handle;
-
-pub enum Output {
- Console(c::HANDLE),
- Pipe(c::HANDLE),
-}
-
-pub struct Stdin {
- utf8: Mutex<io::Cursor<Vec<u8>>>,
-}
-pub struct Stdout;
-pub struct Stderr;
-
-pub fn get(handle: c::DWORD) -> io::Result<Output> {
- let handle = unsafe { c::GetStdHandle(handle) };
- if handle == c::INVALID_HANDLE_VALUE {
- Err(io::Error::last_os_error())
- } else if handle.is_null() {
- Err(io::Error::from_raw_os_error(c::ERROR_INVALID_HANDLE as i32))
- } else {
- let mut out = 0;
- match unsafe { c::GetConsoleMode(handle, &mut out) } {
- 0 => Ok(Output::Pipe(handle)),
- _ => Ok(Output::Console(handle)),
- }
- }
-}
-
-fn write(handle: c::DWORD, data: &[u8]) -> io::Result<usize> {
- let handle = match try!(get(handle)) {
- Output::Console(c) => c,
- Output::Pipe(p) => {
- let handle = Handle::new(p);
- let ret = handle.write(data);
- handle.into_raw();
- return ret
- }
- };
-
- // As with stdin on windows, stdout often can't handle writes of large
- // sizes. For an example, see #14940. For this reason, don't try to
- // write the entire output buffer on windows.
- //
- // For some other references, it appears that this problem has been
- // encountered by others [1] [2]. We choose the number 8K just because
- // libuv does the same.
- //
- // [1]: https://tahoe-lafs.org/trac/tahoe-lafs/ticket/1232
- // [2]: http://www.mail-archive.com/[email protected]/msg00661.html
- const OUT_MAX: usize = 8192;
- let len = cmp::min(data.len(), OUT_MAX);
- let utf8 = match str::from_utf8(&data[..len]) {
- Ok(s) => s,
- Err(ref e) if e.valid_up_to() == 0 => return Err(invalid_encoding()),
- Err(e) => str::from_utf8(&data[..e.valid_up_to()]).unwrap(),
- };
- let utf16 = utf8.encode_utf16().collect::<Vec<u16>>();
- let mut written = 0;
- cvt(unsafe {
- c::WriteConsoleW(handle,
- utf16.as_ptr() as c::LPCVOID,
- utf16.len() as u32,
- &mut written,
- ptr::null_mut())
- })?;
-
- // FIXME if this only partially writes the utf16 buffer then we need to
- // figure out how many bytes of `data` were actually written
- assert_eq!(written as usize, utf16.len());
- Ok(utf8.len())
-}
-
-impl Stdin {
- pub fn new() -> io::Result<Stdin> {
- Ok(Stdin {
- utf8: Mutex::new(Cursor::new(Vec::new())),
- })
- }
-
- pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
- let handle = match try!(get(c::STD_INPUT_HANDLE)) {
- Output::Console(c) => c,
- Output::Pipe(p) => {
- let handle = Handle::new(p);
- let ret = handle.read(buf);
- handle.into_raw();
- return ret
- }
- };
- let mut utf8 = self.utf8.lock().unwrap();
- // Read more if the buffer is empty
- if utf8.position() as usize == utf8.get_ref().len() {
- let mut utf16 = vec![0u16; 0x1000];
- let mut num = 0;
- let mut input_control = readconsole_input_control(CTRL_Z_MASK);
- cvt(unsafe {
- c::ReadConsoleW(handle,
- utf16.as_mut_ptr() as c::LPVOID,
- utf16.len() as u32,
- &mut num,
- &mut input_control as c::PCONSOLE_READCONSOLE_CONTROL)
- })?;
- utf16.truncate(num as usize);
- // FIXME: what to do about this data that has already been read?
- let mut data = match String::from_utf16(&utf16) {
- Ok(utf8) => utf8.into_bytes(),
- Err(..) => return Err(invalid_encoding()),
- };
- if let Some(&last_byte) = data.last() {
- if last_byte == CTRL_Z {
- data.pop();
- }
- }
- *utf8 = Cursor::new(data);
- }
-
- // MemReader shouldn't error here since we just filled it
- utf8.read(buf)
- }
-
- pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
- let mut me = self;
- (&mut me).read_to_end(buf)
- }
-}
-
-#[unstable(reason = "not public", issue = "0", feature = "fd_read")]
-impl<'a> Read for &'a Stdin {
- fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
- (**self).read(buf)
- }
-}
-
-impl Stdout {
- pub fn new() -> io::Result<Stdout> {
- Ok(Stdout)
- }
-
- pub fn write(&self, data: &[u8]) -> io::Result<usize> {
- write(c::STD_OUTPUT_HANDLE, data)
- }
-
- pub fn flush(&self) -> io::Result<()> {
- Ok(())
- }
-}
-
-impl Stderr {
- pub fn new() -> io::Result<Stderr> {
- Ok(Stderr)
- }
-
- pub fn write(&self, data: &[u8]) -> io::Result<usize> {
- write(c::STD_ERROR_HANDLE, data)
- }
-
- pub fn flush(&self) -> io::Result<()> {
- Ok(())
- }
-}
-
-// FIXME: right now this raw stderr handle is used in a few places because
-// std::io::stderr_raw isn't exposed, but once that's exposed this impl
-// should go away
-impl io::Write for Stderr {
- fn write(&mut self, data: &[u8]) -> io::Result<usize> {
- Stderr::write(self, data)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Stderr::flush(self)
- }
-}
-
-impl Output {
- pub fn handle(&self) -> c::HANDLE {
- match *self {
- Output::Console(c) => c,
- Output::Pipe(c) => c,
- }
- }
-}
-
-fn invalid_encoding() -> io::Error {
- io::Error::new(io::ErrorKind::InvalidData, "text was not valid unicode")
-}
-
-fn readconsole_input_control(wakeup_mask: c::ULONG) -> c::CONSOLE_READCONSOLE_CONTROL {
- c::CONSOLE_READCONSOLE_CONTROL {
- nLength: ::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as c::ULONG,
- nInitialChars: 0,
- dwCtrlWakeupMask: wakeup_mask,
- dwControlKeyState: 0,
- }
-}
-
-const CTRL_Z: u8 = 0x1A;
-const CTRL_Z_MASK: c::ULONG = 0x4000000; //1 << 0x1A
-
-pub fn is_ebadf(err: &io::Error) -> bool {
- err.raw_os_error() == Some(c::ERROR_INVALID_HANDLE as i32)
-}
-
-// The default buffer capacity is 64k, but apparently windows
-// doesn't like 64k reads on stdin. See #13304 for details, but the
-// idea is that on windows we use a slightly smaller buffer that's
-// been seen to be acceptable.
-pub const STDIN_BUF_SIZE: usize = 8 * 1024;
-
-pub fn stderr_prints_nothing() -> bool {
- false
-}
diff --git a/ctr-std/src/sys/windows/thread.rs b/ctr-std/src/sys/windows/thread.rs
deleted file mode 100644
index 85588cc..0000000
--- a/ctr-std/src/sys/windows/thread.rs
+++ /dev/null
@@ -1,101 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use boxed::FnBox;
-use io;
-use ffi::CStr;
-use mem;
-use libc::c_void;
-use ptr;
-use sys::c;
-use sys::handle::Handle;
-use sys_common::thread::*;
-use time::Duration;
-
-use super::to_u16s;
-
-pub const DEFAULT_MIN_STACK_SIZE: usize = 2 * 1024 * 1024;
-
-pub struct Thread {
- handle: Handle
-}
-
-impl Thread {
- pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
- -> io::Result<Thread> {
- let p = box p;
-
- // FIXME On UNIX, we guard against stack sizes that are too small but
- // that's because pthreads enforces that stacks are at least
- // PTHREAD_STACK_MIN bytes big. Windows has no such lower limit, it's
- // just that below a certain threshold you can't do anything useful.
- // That threshold is application and architecture-specific, however.
- // Round up to the next 64 kB because that's what the NT kernel does,
- // might as well make it explicit.
- let stack_size = (stack + 0xfffe) & (!0xfffe);
- let ret = c::CreateThread(ptr::null_mut(), stack_size,
- thread_start, &*p as *const _ as *mut _,
- c::STACK_SIZE_PARAM_IS_A_RESERVATION,
- ptr::null_mut());
-
- return if ret as usize == 0 {
- Err(io::Error::last_os_error())
- } else {
- mem::forget(p); // ownership passed to CreateThread
- Ok(Thread { handle: Handle::new(ret) })
- };
-
- extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
- unsafe { start_thread(main as *mut u8); }
- 0
- }
- }
-
- pub fn set_name(name: &CStr) {
- if let Ok(utf8) = name.to_str() {
- if let Ok(utf16) = to_u16s(utf8) {
- unsafe { c::SetThreadDescription(c::GetCurrentThread(), utf16.as_ptr()); };
- };
- };
- }
-
- pub fn join(self) {
- let rc = unsafe { c::WaitForSingleObject(self.handle.raw(), c::INFINITE) };
- if rc == c::WAIT_FAILED {
- panic!("failed to join on thread: {}",
- io::Error::last_os_error());
- }
- }
-
- pub fn yield_now() {
- // This function will return 0 if there are no other threads to execute,
- // but this also means that the yield was useless so this isn't really a
- // case that needs to be worried about.
- unsafe { c::SwitchToThread(); }
- }
-
- pub fn sleep(dur: Duration) {
- unsafe {
- c::Sleep(super::dur2timeout(dur))
- }
- }
-
- pub fn handle(&self) -> &Handle { &self.handle }
-
- pub fn into_handle(self) -> Handle { self.handle }
-}
-
-#[cfg_attr(test, allow(dead_code))]
-pub mod guard {
- pub type Guard = !;
- pub unsafe fn current() -> Option<Guard> { None }
- pub unsafe fn init() -> Option<Guard> { None }
- pub unsafe fn deinit() {}
-}
diff --git a/ctr-std/src/sys/windows/thread_local.rs b/ctr-std/src/sys/windows/thread_local.rs
deleted file mode 100644
index cdad320..0000000
--- a/ctr-std/src/sys/windows/thread_local.rs
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use mem;
-use ptr;
-use sync::atomic::AtomicPtr;
-use sync::atomic::Ordering::SeqCst;
-use sys::c;
-
-pub type Key = c::DWORD;
-pub type Dtor = unsafe extern fn(*mut u8);
-
-// Turns out, like pretty much everything, Windows is pretty close the
-// functionality that Unix provides, but slightly different! In the case of
-// TLS, Windows does not provide an API to provide a destructor for a TLS
-// variable. This ends up being pretty crucial to this implementation, so we
-// need a way around this.
-//
-// The solution here ended up being a little obscure, but fear not, the
-// internet has informed me [1][2] that this solution is not unique (no way
-// I could have thought of it as well!). The key idea is to insert some hook
-// somewhere to run arbitrary code on thread termination. With this in place
-// we'll be able to run anything we like, including all TLS destructors!
-//
-// To accomplish this feat, we perform a number of threads, all contained
-// within this module:
-//
-// * All TLS destructors are tracked by *us*, not the windows runtime. This
-// means that we have a global list of destructors for each TLS key that
-// we know about.
-// * When a thread exits, we run over the entire list and run dtors for all
-// non-null keys. This attempts to match Unix semantics in this regard.
-//
-// This ends up having the overhead of using a global list, having some
-// locks here and there, and in general just adding some more code bloat. We
-// attempt to optimize runtime by forgetting keys that don't have
-// destructors, but this only gets us so far.
-//
-// For more details and nitty-gritty, see the code sections below!
-//
-// [1]: http://www.codeproject.com/Articles/8113/Thread-Local-Storage-The-C-Way
-// [2]: https://github.com/ChromiumWebApps/chromium/blob/master/base
-// /threading/thread_local_storage_win.cc#L42
-
-// -------------------------------------------------------------------------
-// Native bindings
-//
-// This section is just raw bindings to the native functions that Windows
-// provides, There's a few extra calls to deal with destructors.
-
-#[inline]
-pub unsafe fn create(dtor: Option<Dtor>) -> Key {
- let key = c::TlsAlloc();
- assert!(key != c::TLS_OUT_OF_INDEXES);
- if let Some(f) = dtor {
- register_dtor(key, f);
- }
- return key;
-}
-
-#[inline]
-pub unsafe fn set(key: Key, value: *mut u8) {
- let r = c::TlsSetValue(key, value as c::LPVOID);
- debug_assert!(r != 0);
-}
-
-#[inline]
-pub unsafe fn get(key: Key) -> *mut u8 {
- c::TlsGetValue(key) as *mut u8
-}
-
-#[inline]
-pub unsafe fn destroy(_key: Key) {
- rtabort!("can't destroy tls keys on windows")
-}
-
-#[inline]
-pub fn requires_synchronized_create() -> bool {
- true
-}
-
-// -------------------------------------------------------------------------
-// Dtor registration
-//
-// Windows has no native support for running destructors so we manage our own
-// list of destructors to keep track of how to destroy keys. We then install a
-// callback later to get invoked whenever a thread exits, running all
-// appropriate destructors.
-//
-// Currently unregistration from this list is not supported. A destructor can be
-// registered but cannot be unregistered. There's various simplifying reasons
-// for doing this, the big ones being:
-//
-// 1. Currently we don't even support deallocating TLS keys, so normal operation
-// doesn't need to deallocate a destructor.
-// 2. There is no point in time where we know we can unregister a destructor
-// because it could always be getting run by some remote thread.
-//
-// Typically processes have a statically known set of TLS keys which is pretty
-// small, and we'd want to keep this memory alive for the whole process anyway
-// really.
-//
-// Perhaps one day we can fold the `Box` here into a static allocation,
-// expanding the `StaticKey` structure to contain not only a slot for the TLS
-// key but also a slot for the destructor queue on windows. An optimization for
-// another day!
-
-static DTORS: AtomicPtr<Node> = AtomicPtr::new(ptr::null_mut());
-
-struct Node {
- dtor: Dtor,
- key: Key,
- next: *mut Node,
-}
-
-unsafe fn register_dtor(key: Key, dtor: Dtor) {
- let mut node = Box::new(Node {
- key,
- dtor,
- next: ptr::null_mut(),
- });
-
- let mut head = DTORS.load(SeqCst);
- loop {
- node.next = head;
- match DTORS.compare_exchange(head, &mut *node, SeqCst, SeqCst) {
- Ok(_) => return mem::forget(node),
- Err(cur) => head = cur,
- }
- }
-}
-
-// -------------------------------------------------------------------------
-// Where the Magic (TM) Happens
-//
-// If you're looking at this code, and wondering "what is this doing?",
-// you're not alone! I'll try to break this down step by step:
-//
-// # What's up with CRT$XLB?
-//
-// For anything about TLS destructors to work on Windows, we have to be able
-// to run *something* when a thread exits. To do so, we place a very special
-// static in a very special location. If this is encoded in just the right
-// way, the kernel's loader is apparently nice enough to run some function
-// of ours whenever a thread exits! How nice of the kernel!
-//
-// Lots of detailed information can be found in source [1] above, but the
-// gist of it is that this is leveraging a feature of Microsoft's PE format
-// (executable format) which is not actually used by any compilers today.
-// This apparently translates to any callbacks in the ".CRT$XLB" section
-// being run on certain events.
-//
-// So after all that, we use the compiler's #[link_section] feature to place
-// a callback pointer into the magic section so it ends up being called.
-//
-// # What's up with this callback?
-//
-// The callback specified receives a number of parameters from... someone!
-// (the kernel? the runtime? I'm not quite sure!) There are a few events that
-// this gets invoked for, but we're currently only interested on when a
-// thread or a process "detaches" (exits). The process part happens for the
-// last thread and the thread part happens for any normal thread.
-//
-// # Ok, what's up with running all these destructors?
-//
-// This will likely need to be improved over time, but this function
-// attempts a "poor man's" destructor callback system. Once we've got a list
-// of what to run, we iterate over all keys, check their values, and then run
-// destructors if the values turn out to be non null (setting them to null just
-// beforehand). We do this a few times in a loop to basically match Unix
-// semantics. If we don't reach a fixed point after a short while then we just
-// inevitably leak something most likely.
-//
-// # The article mentions weird stuff about "/INCLUDE"?
-//
-// It sure does! Specifically we're talking about this quote:
-//
-// The Microsoft run-time library facilitates this process by defining a
-// memory image of the TLS Directory and giving it the special name
-// “__tls_used” (Intel x86 platforms) or “_tls_used” (other platforms). The
-// linker looks for this memory image and uses the data there to create the
-// TLS Directory. Other compilers that support TLS and work with the
-// Microsoft linker must use this same technique.
-//
-// Basically what this means is that if we want support for our TLS
-// destructors/our hook being called then we need to make sure the linker does
-// not omit this symbol. Otherwise it will omit it and our callback won't be
-// wired up.
-//
-// We don't actually use the `/INCLUDE` linker flag here like the article
-// mentions because the Rust compiler doesn't propagate linker flags, but
-// instead we use a shim function which performs a volatile 1-byte load from
-// the address of the symbol to ensure it sticks around.
-
-#[link_section = ".CRT$XLB"]
-#[allow(dead_code, unused_variables)]
-#[used] // we don't want LLVM eliminating this symbol for any reason, and
- // when the symbol makes it to the linker the linker will take over
-pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD,
- c::LPVOID) =
- on_tls_callback;
-
-#[allow(dead_code, unused_variables)]
-unsafe extern "system" fn on_tls_callback(h: c::LPVOID,
- dwReason: c::DWORD,
- pv: c::LPVOID) {
- if dwReason == c::DLL_THREAD_DETACH || dwReason == c::DLL_PROCESS_DETACH {
- run_dtors();
- }
-
- // See comments above for what this is doing. Note that we don't need this
- // trickery on GNU windows, just on MSVC.
- reference_tls_used();
- #[cfg(target_env = "msvc")]
- unsafe fn reference_tls_used() {
- extern { static _tls_used: u8; }
- ::intrinsics::volatile_load(&_tls_used);
- }
- #[cfg(not(target_env = "msvc"))]
- unsafe fn reference_tls_used() {}
-}
-
-#[allow(dead_code)] // actually called above
-unsafe fn run_dtors() {
- let mut any_run = true;
- for _ in 0..5 {
- if !any_run {
- break
- }
- any_run = false;
- let mut cur = DTORS.load(SeqCst);
- while !cur.is_null() {
- let ptr = c::TlsGetValue((*cur).key);
-
- if !ptr.is_null() {
- c::TlsSetValue((*cur).key, ptr::null_mut());
- ((*cur).dtor)(ptr as *mut _);
- any_run = true;
- }
-
- cur = (*cur).next;
- }
- }
-}
diff --git a/ctr-std/src/sys/windows/time.rs b/ctr-std/src/sys/windows/time.rs
deleted file mode 100644
index 07e64d3..0000000
--- a/ctr-std/src/sys/windows/time.rs
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use cmp::Ordering;
-use fmt;
-use mem;
-use sync::Once;
-use sys::c;
-use sys::cvt;
-use sys_common::mul_div_u64;
-use time::Duration;
-use convert::TryInto;
-use core::hash::{Hash, Hasher};
-
-const NANOS_PER_SEC: u64 = 1_000_000_000;
-const INTERVALS_PER_SEC: u64 = NANOS_PER_SEC / 100;
-
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
-pub struct Instant {
- t: c::LARGE_INTEGER,
-}
-
-#[derive(Copy, Clone)]
-pub struct SystemTime {
- t: c::FILETIME,
-}
-
-const INTERVALS_TO_UNIX_EPOCH: u64 = 11_644_473_600 * INTERVALS_PER_SEC;
-
-pub const UNIX_EPOCH: SystemTime = SystemTime {
- t: c::FILETIME {
- dwLowDateTime: INTERVALS_TO_UNIX_EPOCH as u32,
- dwHighDateTime: (INTERVALS_TO_UNIX_EPOCH >> 32) as u32,
- },
-};
-
-impl Instant {
- pub fn now() -> Instant {
- let mut t = Instant { t: 0 };
- cvt(unsafe {
- c::QueryPerformanceCounter(&mut t.t)
- }).unwrap();
- t
- }
-
- pub fn sub_instant(&self, other: &Instant) -> Duration {
- // Values which are +- 1 need to be considered as basically the same
- // units in time due to various measurement oddities, according to
- // Windows [1]
- //
- // [1]:
- // https://msdn.microsoft.com/en-us/library/windows/desktop
- // /dn553408%28v=vs.85%29.aspx#guidance
- if other.t > self.t && other.t - self.t == 1 {
- return Duration::new(0, 0)
- }
- let diff = (self.t as u64).checked_sub(other.t as u64)
- .expect("specified instant was later than \
- self");
- let nanos = mul_div_u64(diff, NANOS_PER_SEC, frequency() as u64);
- Duration::new(nanos / NANOS_PER_SEC, (nanos % NANOS_PER_SEC) as u32)
- }
-
- pub fn add_duration(&self, other: &Duration) -> Instant {
- let freq = frequency() as u64;
- let t = other.as_secs().checked_mul(freq).and_then(|i| {
- (self.t as u64).checked_add(i)
- }).and_then(|i| {
- i.checked_add(mul_div_u64(other.subsec_nanos() as u64, freq,
- NANOS_PER_SEC))
- }).expect("overflow when adding duration to time");
- Instant {
- t: t as c::LARGE_INTEGER,
- }
- }
-
- pub fn sub_duration(&self, other: &Duration) -> Instant {
- let freq = frequency() as u64;
- let t = other.as_secs().checked_mul(freq).and_then(|i| {
- (self.t as u64).checked_sub(i)
- }).and_then(|i| {
- i.checked_sub(mul_div_u64(other.subsec_nanos() as u64, freq,
- NANOS_PER_SEC))
- }).expect("overflow when subtracting duration from time");
- Instant {
- t: t as c::LARGE_INTEGER,
- }
- }
-}
-
-impl SystemTime {
- pub fn now() -> SystemTime {
- unsafe {
- let mut t: SystemTime = mem::zeroed();
- c::GetSystemTimeAsFileTime(&mut t.t);
- return t
- }
- }
-
- fn from_intervals(intervals: i64) -> SystemTime {
- SystemTime {
- t: c::FILETIME {
- dwLowDateTime: intervals as c::DWORD,
- dwHighDateTime: (intervals >> 32) as c::DWORD,
- }
- }
- }
-
- fn intervals(&self) -> i64 {
- (self.t.dwLowDateTime as i64) | ((self.t.dwHighDateTime as i64) << 32)
- }
-
- pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
- let me = self.intervals();
- let other = other.intervals();
- if me >= other {
- Ok(intervals2dur((me - other) as u64))
- } else {
- Err(intervals2dur((other - me) as u64))
- }
- }
-
- pub fn add_duration(&self, other: &Duration) -> SystemTime {
- let intervals = self.intervals().checked_add(dur2intervals(other))
- .expect("overflow when adding duration to time");
- SystemTime::from_intervals(intervals)
- }
-
- pub fn sub_duration(&self, other: &Duration) -> SystemTime {
- let intervals = self.intervals().checked_sub(dur2intervals(other))
- .expect("overflow when subtracting from time");
- SystemTime::from_intervals(intervals)
- }
-}
-
-impl PartialEq for SystemTime {
- fn eq(&self, other: &SystemTime) -> bool {
- self.intervals() == other.intervals()
- }
-}
-
-impl Eq for SystemTime {}
-
-impl PartialOrd for SystemTime {
- fn partial_cmp(&self, other: &SystemTime) -> Option<Ordering> {
- Some(self.cmp(other))
- }
-}
-
-impl Ord for SystemTime {
- fn cmp(&self, other: &SystemTime) -> Ordering {
- self.intervals().cmp(&other.intervals())
- }
-}
-
-impl fmt::Debug for SystemTime {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- f.debug_struct("SystemTime")
- .field("intervals", &self.intervals())
- .finish()
- }
-}
-
-impl From<c::FILETIME> for SystemTime {
- fn from(t: c::FILETIME) -> SystemTime {
- SystemTime { t: t }
- }
-}
-
-impl Hash for SystemTime {
- fn hash<H : Hasher>(&self, state: &mut H) {
- self.intervals().hash(state)
- }
-}
-
-fn dur2intervals(d: &Duration) -> i64 {
- d.as_secs()
- .checked_mul(INTERVALS_PER_SEC)
- .and_then(|i| i.checked_add(d.subsec_nanos() as u64 / 100))
- .and_then(|i| i.try_into().ok())
- .expect("overflow when converting duration to intervals")
-}
-
-fn intervals2dur(intervals: u64) -> Duration {
- Duration::new(intervals / INTERVALS_PER_SEC,
- ((intervals % INTERVALS_PER_SEC) * 100) as u32)
-}
-
-fn frequency() -> c::LARGE_INTEGER {
- static mut FREQUENCY: c::LARGE_INTEGER = 0;
- static ONCE: Once = Once::new();
-
- unsafe {
- ONCE.call_once(|| {
- cvt(c::QueryPerformanceFrequency(&mut FREQUENCY)).unwrap();
- });
- FREQUENCY
- }
-}