std: Migrate to the new libc
* Delete `sys::unix::{c, sync}` as these are now all folded into libc itself * Update all references to use `libc` as a result. * Update all references to the new flat namespace. * Moves all windows bindings into sys::c
This commit is contained in:
parent
c8a29c2092
commit
3d28b8b98e
62 changed files with 1889 additions and 2431 deletions
|
@ -174,3 +174,6 @@ $(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate))))
|
|||
ifdef CFG_DISABLE_ELF_TLS
|
||||
RUSTFLAGS_std := --cfg no_elf_tls
|
||||
endif
|
||||
|
||||
CRATEFILE_libc := $(SREL)src/liblibc/src/lib.rs
|
||||
RUSTFLAGS_libc := --cfg stdbuild
|
||||
|
|
|
@ -22,7 +22,7 @@ $(eval $(call RUST_CRATE,coretest))
|
|||
DEPS_collectionstest :=
|
||||
$(eval $(call RUST_CRATE,collectionstest))
|
||||
|
||||
TEST_TARGET_CRATES = $(filter-out core rustc_unicode alloc_system \
|
||||
TEST_TARGET_CRATES = $(filter-out core rustc_unicode alloc_system libc \
|
||||
alloc_jemalloc,$(TARGET_CRATES)) \
|
||||
collectionstest coretest
|
||||
TEST_DOC_CRATES = $(DOC_CRATES)
|
||||
|
@ -283,6 +283,7 @@ tidy-binaries:
|
|||
| grep '^$(S)src/compiler-rt' -v \
|
||||
| grep '^$(S)src/libbacktrace' -v \
|
||||
| grep '^$(S)src/rust-installer' -v \
|
||||
| grep '^$(S)src/liblibc' -v \
|
||||
| xargs $(CFG_PYTHON) $(S)src/etc/check-binaries.py
|
||||
|
||||
.PHONY: tidy-errors
|
||||
|
|
|
@ -108,7 +108,8 @@ try:
|
|||
'src/rustllvm',
|
||||
'src/rt/valgrind',
|
||||
'src/rt/msvc',
|
||||
'src/rust-installer'
|
||||
'src/rust-installer',
|
||||
'src/liblibc',
|
||||
}
|
||||
|
||||
if any(d in dirpath for d in skippable_dirs):
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#![staged_api]
|
||||
#![no_std]
|
||||
#![cfg_attr(not(stage0), allocator)]
|
||||
#![cfg_attr(stage0, allow(improper_ctypes))]
|
||||
#![unstable(feature = "alloc_jemalloc",
|
||||
reason = "this library is unlikely to be stabilized in its current \
|
||||
form or name",
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#![staged_api]
|
||||
#![no_std]
|
||||
#![cfg_attr(not(stage0), allocator)]
|
||||
#![cfg_attr(stage0, allow(improper_ctypes))]
|
||||
#![unstable(feature = "alloc_system",
|
||||
reason = "this library is unlikely to be stabilized in its current \
|
||||
form or name",
|
||||
|
@ -141,10 +142,16 @@ mod imp {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[allow(bad_style)]
|
||||
mod imp {
|
||||
use libc::{BOOL, DWORD, HANDLE, LPVOID, SIZE_T};
|
||||
use MIN_ALIGN;
|
||||
|
||||
type LPVOID = *mut u8;
|
||||
type HANDLE = LPVOID;
|
||||
type SIZE_T = usize;
|
||||
type DWORD = u32;
|
||||
type BOOL = i32;
|
||||
|
||||
extern "system" {
|
||||
fn GetProcessHeap() -> HANDLE;
|
||||
fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#![feature(staged_api)]
|
||||
#![feature(unique)]
|
||||
#![cfg_attr(test, feature(rustc_private, rand, vec_push_all))]
|
||||
#![cfg_attr(stage0, allow(improper_ctypes))]
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
|
|
|
@ -96,25 +96,30 @@ fn get_resident() -> Option<usize> {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[cfg_attr(stage0, allow(improper_ctypes))]
|
||||
fn get_resident() -> Option<usize> {
|
||||
use libc::{BOOL, DWORD, HANDLE, SIZE_T, GetCurrentProcess};
|
||||
type BOOL = i32;
|
||||
type DWORD = u32;
|
||||
type HANDLE = *mut u8;
|
||||
use libc::size_t;
|
||||
use std::mem;
|
||||
#[repr(C)] #[allow(non_snake_case)]
|
||||
struct PROCESS_MEMORY_COUNTERS {
|
||||
cb: DWORD,
|
||||
PageFaultCount: DWORD,
|
||||
PeakWorkingSetSize: SIZE_T,
|
||||
WorkingSetSize: SIZE_T,
|
||||
QuotaPeakPagedPoolUsage: SIZE_T,
|
||||
QuotaPagedPoolUsage: SIZE_T,
|
||||
QuotaPeakNonPagedPoolUsage: SIZE_T,
|
||||
QuotaNonPagedPoolUsage: SIZE_T,
|
||||
PagefileUsage: SIZE_T,
|
||||
PeakPagefileUsage: SIZE_T,
|
||||
PeakWorkingSetSize: size_t,
|
||||
WorkingSetSize: size_t,
|
||||
QuotaPeakPagedPoolUsage: size_t,
|
||||
QuotaPagedPoolUsage: size_t,
|
||||
QuotaPeakNonPagedPoolUsage: size_t,
|
||||
QuotaNonPagedPoolUsage: size_t,
|
||||
PagefileUsage: size_t,
|
||||
PeakPagefileUsage: size_t,
|
||||
}
|
||||
type PPROCESS_MEMORY_COUNTERS = *mut PROCESS_MEMORY_COUNTERS;
|
||||
#[link(name = "psapi")]
|
||||
extern "system" {
|
||||
fn GetCurrentProcess() -> HANDLE;
|
||||
fn GetProcessMemoryInfo(Process: HANDLE,
|
||||
ppsmemCounters: PPROCESS_MEMORY_COUNTERS,
|
||||
cb: DWORD) -> BOOL;
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#![allow(dead_code)]
|
||||
#![allow(trivial_casts)]
|
||||
|
||||
#![cfg_attr(stage0, allow(improper_ctypes))]
|
||||
|
||||
#![crate_name = "rustc_llvm"]
|
||||
#![unstable(feature = "rustc_private", issue = "27812")]
|
||||
#![staged_api]
|
||||
|
|
|
@ -13,8 +13,14 @@ use std::ffi::{OsString, OsStr};
|
|||
use std::os::windows::prelude::*;
|
||||
use std::ops::RangeFrom;
|
||||
use std::ptr;
|
||||
use libc::{DWORD, LPCWSTR, LONG, LPDWORD, LPBYTE, ERROR_SUCCESS};
|
||||
use libc::c_void;
|
||||
use libc::{c_void, c_long};
|
||||
|
||||
type DWORD = u32;
|
||||
type LPCWSTR = *const u16;
|
||||
type LONG = c_long;
|
||||
type LPDWORD = *mut DWORD;
|
||||
type LPBYTE = *mut u8;
|
||||
|
||||
|
||||
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
|
||||
const KEY_WOW64_32KEY: REGSAM = 0x0200;
|
||||
|
@ -27,6 +33,7 @@ const KEY_ENUMERATE_SUB_KEYS: REGSAM = 0x0008;
|
|||
const KEY_NOTIFY: REGSAM = 0x0010;
|
||||
const SYNCHRONIZE: REGSAM = 0x00100000;
|
||||
const REG_SZ: DWORD = 1;
|
||||
const ERROR_SUCCESS: i32 = 0;
|
||||
const ERROR_NO_MORE_ITEMS: DWORD = 259;
|
||||
|
||||
enum __HKEY__ {}
|
||||
|
|
|
@ -121,7 +121,7 @@ mod imp {
|
|||
let buf = CString::new(os.as_bytes()).unwrap();
|
||||
let fd = unsafe {
|
||||
libc::open(buf.as_ptr(), libc::O_RDWR | libc::O_CREAT,
|
||||
libc::S_IRWXU)
|
||||
libc::S_IRWXU as libc::c_int)
|
||||
};
|
||||
assert!(fd > 0, "failed to open lockfile: {}",
|
||||
io::Error::last_os_error());
|
||||
|
@ -164,77 +164,55 @@ mod imp {
|
|||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[allow(bad_style)]
|
||||
mod imp {
|
||||
use libc;
|
||||
use std::io;
|
||||
use std::mem;
|
||||
use std::ffi::OsStr;
|
||||
use std::os::windows::prelude::*;
|
||||
use std::os::windows::raw::HANDLE;
|
||||
use std::path::Path;
|
||||
use std::ptr;
|
||||
use std::fs::{File, OpenOptions};
|
||||
|
||||
const LOCKFILE_EXCLUSIVE_LOCK: libc::DWORD = 0x00000002;
|
||||
type DWORD = u32;
|
||||
type LPOVERLAPPED = *mut OVERLAPPED;
|
||||
type BOOL = i32;
|
||||
const LOCKFILE_EXCLUSIVE_LOCK: DWORD = 0x00000002;
|
||||
|
||||
#[repr(C)]
|
||||
struct OVERLAPPED {
|
||||
Internal: usize,
|
||||
InternalHigh: usize,
|
||||
Pointer: *mut u8,
|
||||
hEvent: *mut u8,
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
extern "system" {
|
||||
fn LockFileEx(hFile: libc::HANDLE,
|
||||
dwFlags: libc::DWORD,
|
||||
dwReserved: libc::DWORD,
|
||||
nNumberOfBytesToLockLow: libc::DWORD,
|
||||
nNumberOfBytesToLockHigh: libc::DWORD,
|
||||
lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
|
||||
fn UnlockFileEx(hFile: libc::HANDLE,
|
||||
dwReserved: libc::DWORD,
|
||||
nNumberOfBytesToLockLow: libc::DWORD,
|
||||
nNumberOfBytesToLockHigh: libc::DWORD,
|
||||
lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
|
||||
fn LockFileEx(hFile: HANDLE,
|
||||
dwFlags: DWORD,
|
||||
dwReserved: DWORD,
|
||||
nNumberOfBytesToLockLow: DWORD,
|
||||
nNumberOfBytesToLockHigh: DWORD,
|
||||
lpOverlapped: LPOVERLAPPED) -> BOOL;
|
||||
}
|
||||
|
||||
pub struct Lock {
|
||||
handle: libc::HANDLE,
|
||||
_file: File,
|
||||
}
|
||||
|
||||
impl Lock {
|
||||
pub fn new(p: &Path) -> Lock {
|
||||
let os: &OsStr = p.as_ref();
|
||||
let mut p_16: Vec<_> = os.encode_wide().collect();
|
||||
p_16.push(0);
|
||||
let handle = unsafe {
|
||||
libc::CreateFileW(p_16.as_ptr(),
|
||||
libc::FILE_GENERIC_READ |
|
||||
libc::FILE_GENERIC_WRITE,
|
||||
libc::FILE_SHARE_READ |
|
||||
libc::FILE_SHARE_DELETE |
|
||||
libc::FILE_SHARE_WRITE,
|
||||
ptr::null_mut(),
|
||||
libc::CREATE_ALWAYS,
|
||||
libc::FILE_ATTRIBUTE_NORMAL,
|
||||
ptr::null_mut())
|
||||
};
|
||||
if handle == libc::INVALID_HANDLE_VALUE {
|
||||
panic!("create file error: {}", io::Error::last_os_error());
|
||||
}
|
||||
let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
|
||||
let f = OpenOptions::new().read(true).write(true).create(true)
|
||||
.open(p).unwrap();
|
||||
let ret = unsafe {
|
||||
LockFileEx(handle, LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0,
|
||||
let mut overlapped: OVERLAPPED = mem::zeroed();
|
||||
LockFileEx(f.as_raw_handle(), LOCKFILE_EXCLUSIVE_LOCK, 0, 100, 0,
|
||||
&mut overlapped)
|
||||
};
|
||||
if ret == 0 {
|
||||
let err = io::Error::last_os_error();
|
||||
unsafe { libc::CloseHandle(handle); }
|
||||
panic!("could not lock `{}`: {}", p.display(), err);
|
||||
}
|
||||
Lock { handle: handle }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Lock {
|
||||
fn drop(&mut self) {
|
||||
let mut overlapped: libc::OVERLAPPED = unsafe { mem::zeroed() };
|
||||
unsafe {
|
||||
UnlockFileEx(self.handle, 0, 100, 0, &mut overlapped);
|
||||
libc::CloseHandle(self.handle);
|
||||
}
|
||||
Lock { _file: f }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,11 +207,11 @@ mod dl {
|
|||
|
||||
unsafe fn open_external(filename: &OsStr) -> *mut u8 {
|
||||
let s = filename.to_cstring().unwrap();
|
||||
dlopen(s.as_ptr(), LAZY) as *mut u8
|
||||
libc::dlopen(s.as_ptr(), LAZY) as *mut u8
|
||||
}
|
||||
|
||||
unsafe fn open_internal() -> *mut u8 {
|
||||
dlopen(ptr::null(), LAZY) as *mut u8
|
||||
libc::dlopen(ptr::null(), LAZY) as *mut u8
|
||||
}
|
||||
|
||||
pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
|
||||
|
@ -223,11 +223,11 @@ mod dl {
|
|||
// dlerror isn't thread safe, so we need to lock around this entire
|
||||
// sequence
|
||||
let _guard = LOCK.lock();
|
||||
let _old_error = dlerror();
|
||||
let _old_error = libc::dlerror();
|
||||
|
||||
let result = f();
|
||||
|
||||
let last_error = dlerror() as *const _;
|
||||
let last_error = libc::dlerror() as *const _;
|
||||
let ret = if ptr::null() == last_error {
|
||||
Ok(result)
|
||||
} else {
|
||||
|
@ -241,19 +241,10 @@ mod dl {
|
|||
|
||||
pub unsafe fn symbol(handle: *mut u8,
|
||||
symbol: *const libc::c_char) -> *mut u8 {
|
||||
dlsym(handle as *mut libc::c_void, symbol) as *mut u8
|
||||
libc::dlsym(handle as *mut libc::c_void, symbol) as *mut u8
|
||||
}
|
||||
pub unsafe fn close(handle: *mut u8) {
|
||||
dlclose(handle as *mut libc::c_void); ()
|
||||
}
|
||||
|
||||
extern {
|
||||
fn dlopen(filename: *const libc::c_char,
|
||||
flag: libc::c_int) -> *mut libc::c_void;
|
||||
fn dlerror() -> *mut libc::c_char;
|
||||
fn dlsym(handle: *mut libc::c_void,
|
||||
symbol: *const libc::c_char) -> *mut libc::c_void;
|
||||
fn dlclose(handle: *mut libc::c_void) -> libc::c_int;
|
||||
libc::dlclose(handle as *mut libc::c_void); ()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -263,11 +254,10 @@ mod dl {
|
|||
|
||||
use ffi::OsStr;
|
||||
use libc;
|
||||
use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
|
||||
use sys::os;
|
||||
use os::windows::prelude::*;
|
||||
use ptr;
|
||||
use sys::c::SetThreadErrorMode;
|
||||
use sys::c;
|
||||
use sys::os;
|
||||
|
||||
pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
|
||||
// disable "dll load failed" error dialog.
|
||||
|
@ -277,24 +267,25 @@ mod dl {
|
|||
let new_error_mode = 1;
|
||||
let mut prev_error_mode = 0;
|
||||
// Windows >= 7 supports thread error mode.
|
||||
let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode);
|
||||
let result = c::SetThreadErrorMode(new_error_mode,
|
||||
&mut prev_error_mode);
|
||||
if result == 0 {
|
||||
let err = os::errno();
|
||||
if err as libc::c_int == ERROR_CALL_NOT_IMPLEMENTED {
|
||||
if err == c::ERROR_CALL_NOT_IMPLEMENTED as i32 {
|
||||
use_thread_mode = false;
|
||||
// SetThreadErrorMode not found. use fallback solution:
|
||||
// SetErrorMode() Note that SetErrorMode is process-wide so
|
||||
// this can cause race condition! However, since even
|
||||
// Windows APIs do not care of such problem (#20650), we
|
||||
// just assume SetErrorMode race is not a great deal.
|
||||
prev_error_mode = SetErrorMode(new_error_mode);
|
||||
prev_error_mode = c::SetErrorMode(new_error_mode);
|
||||
}
|
||||
}
|
||||
prev_error_mode
|
||||
};
|
||||
|
||||
unsafe {
|
||||
SetLastError(0);
|
||||
c::SetLastError(0);
|
||||
}
|
||||
|
||||
let result = match filename {
|
||||
|
@ -302,7 +293,7 @@ mod dl {
|
|||
let filename_str: Vec<_> =
|
||||
filename.encode_wide().chain(Some(0)).collect();
|
||||
let result = unsafe {
|
||||
LoadLibraryW(filename_str.as_ptr() as *const libc::c_void)
|
||||
c::LoadLibraryW(filename_str.as_ptr())
|
||||
};
|
||||
// beware: Vec/String may change errno during drop!
|
||||
// so we get error here.
|
||||
|
@ -316,9 +307,10 @@ mod dl {
|
|||
None => {
|
||||
let mut handle = ptr::null_mut();
|
||||
let succeeded = unsafe {
|
||||
GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &mut handle)
|
||||
c::GetModuleHandleExW(0 as c::DWORD, ptr::null(),
|
||||
&mut handle)
|
||||
};
|
||||
if succeeded == libc::FALSE {
|
||||
if succeeded == c::FALSE {
|
||||
let errno = os::errno();
|
||||
Err(os::error_string(errno))
|
||||
} else {
|
||||
|
@ -329,9 +321,9 @@ mod dl {
|
|||
|
||||
unsafe {
|
||||
if use_thread_mode {
|
||||
SetThreadErrorMode(prev_error_mode, ptr::null_mut());
|
||||
c::SetThreadErrorMode(prev_error_mode, ptr::null_mut());
|
||||
} else {
|
||||
SetErrorMode(prev_error_mode);
|
||||
c::SetErrorMode(prev_error_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,7 +334,7 @@ mod dl {
|
|||
F: FnOnce() -> T,
|
||||
{
|
||||
unsafe {
|
||||
SetLastError(0);
|
||||
c::SetLastError(0);
|
||||
|
||||
let result = f();
|
||||
|
||||
|
@ -356,22 +348,10 @@ mod dl {
|
|||
}
|
||||
|
||||
pub unsafe fn symbol(handle: *mut u8, symbol: *const libc::c_char) -> *mut u8 {
|
||||
GetProcAddress(handle as *mut libc::c_void, symbol) as *mut u8
|
||||
c::GetProcAddress(handle as c::HMODULE, symbol) as *mut u8
|
||||
}
|
||||
pub unsafe fn close(handle: *mut u8) {
|
||||
FreeLibrary(handle as *mut libc::c_void); ()
|
||||
}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
extern "system" {
|
||||
fn SetLastError(error: libc::size_t);
|
||||
fn LoadLibraryW(name: *const libc::c_void) -> *mut libc::c_void;
|
||||
fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *const u16,
|
||||
handle: *mut *mut libc::c_void) -> libc::BOOL;
|
||||
fn GetProcAddress(handle: *mut libc::c_void,
|
||||
name: *const libc::c_char) -> *mut libc::c_void;
|
||||
fn FreeLibrary(handle: *mut libc::c_void);
|
||||
fn SetErrorMode(uMode: libc::c_uint) -> libc::c_uint;
|
||||
c::FreeLibrary(handle as c::HMODULE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ use cmp;
|
|||
use fmt;
|
||||
use io::lazy::Lazy;
|
||||
use io::{self, BufReader, LineWriter};
|
||||
use libc;
|
||||
use sync::{Arc, Mutex, MutexGuard};
|
||||
use sys::stdio;
|
||||
use sys_common::io::{read_to_end_uninitialized};
|
||||
|
@ -121,9 +120,9 @@ impl<R: io::Read> io::Read for Maybe<R> {
|
|||
|
||||
fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
|
||||
#[cfg(windows)]
|
||||
const ERR: libc::c_int = libc::ERROR_INVALID_HANDLE;
|
||||
const ERR: i32 = ::sys::c::ERROR_INVALID_HANDLE as i32;
|
||||
#[cfg(not(windows))]
|
||||
const ERR: libc::c_int = libc::EBADF;
|
||||
const ERR: i32 = ::libc::EBADF as i32;
|
||||
|
||||
match r {
|
||||
Err(ref e) if e.raw_os_error() == Some(ERR) => Ok(default),
|
||||
|
|
|
@ -213,13 +213,12 @@
|
|||
test(no_crate_inject, attr(deny(warnings))),
|
||||
test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))))]
|
||||
|
||||
// SNAP 1af31d4
|
||||
#![allow(unused_features)]
|
||||
// SNAP 1af31d4
|
||||
#![allow(unused_attributes)]
|
||||
#![cfg_attr(stage0, allow(unused_attributes))]
|
||||
#![cfg_attr(stage0, allow(improper_ctypes))]
|
||||
|
||||
#![feature(alloc)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(asm)]
|
||||
#![feature(associated_consts)]
|
||||
#![feature(borrow_state)]
|
||||
#![feature(box_syntax)]
|
||||
|
@ -233,49 +232,52 @@
|
|||
#![feature(core_float)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_simd)]
|
||||
#![feature(decode_utf16)]
|
||||
#![feature(drain)]
|
||||
#![feature(drop_in_place)]
|
||||
#![feature(dropck_parametricity)]
|
||||
#![feature(float_extras)]
|
||||
#![feature(float_from_str_radix)]
|
||||
#![feature(fnbox)]
|
||||
#![feature(heap_api)]
|
||||
#![feature(int_error_internals)]
|
||||
#![feature(into_cow)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(libc)]
|
||||
#![feature(linkage, thread_local, asm)]
|
||||
#![feature(link_args)]
|
||||
#![feature(linkage)]
|
||||
#![feature(macro_reexport)]
|
||||
#![feature(slice_concat_ext)]
|
||||
#![feature(no_std)]
|
||||
#![feature(oom)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(placement_in_syntax)]
|
||||
#![feature(rand)]
|
||||
#![feature(range_inclusive)]
|
||||
#![feature(raw)]
|
||||
#![feature(reflect_marker)]
|
||||
#![feature(slice_bytes)]
|
||||
#![feature(slice_concat_ext)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_char)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(str_utf16)]
|
||||
#![feature(test, rustc_private)]
|
||||
#![feature(thread_local)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode)]
|
||||
#![feature(unique)]
|
||||
#![feature(dropck_parametricity)]
|
||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(decode_utf16)]
|
||||
#![feature(unwind_attributes)]
|
||||
#![feature(vec_push_all)]
|
||||
#![feature(wrapping)]
|
||||
#![feature(zero_one)]
|
||||
#![feature(drop_in_place)]
|
||||
|
||||
#![cfg_attr(windows, feature(str_utf16))]
|
||||
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
|
||||
#![cfg_attr(test, feature(test, rustc_private))]
|
||||
#![cfg_attr(target_env = "msvc", feature(link_args))]
|
||||
|
||||
// Don't link to std. We are std.
|
||||
#![no_std]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![allow(unused_features)] // std may use features in a platform-specific way
|
||||
|
||||
#[cfg(test)] extern crate test;
|
||||
#[cfg(test)] #[macro_use] extern crate log;
|
||||
|
|
|
@ -13,10 +13,10 @@ use prelude::v1::*;
|
|||
use fmt;
|
||||
use hash;
|
||||
use io;
|
||||
use libc::{self, socklen_t, sa_family_t};
|
||||
use mem;
|
||||
use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
|
||||
use option;
|
||||
use sys::net::netc as c;
|
||||
use sys_common::{FromInner, AsInner, IntoInner};
|
||||
use vec;
|
||||
|
||||
|
@ -39,12 +39,12 @@ pub enum SocketAddr {
|
|||
/// An IPv4 socket address which is a (ip, port) combination.
|
||||
#[derive(Copy)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct SocketAddrV4 { inner: libc::sockaddr_in }
|
||||
pub struct SocketAddrV4 { inner: c::sockaddr_in }
|
||||
|
||||
/// An IPv6 socket address.
|
||||
#[derive(Copy)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
|
||||
pub struct SocketAddrV6 { inner: c::sockaddr_in6 }
|
||||
|
||||
impl SocketAddr {
|
||||
/// Creates a new socket address from the (ip, port) pair.
|
||||
|
@ -80,8 +80,8 @@ impl SocketAddrV4 {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
|
||||
SocketAddrV4 {
|
||||
inner: libc::sockaddr_in {
|
||||
sin_family: libc::AF_INET as sa_family_t,
|
||||
inner: c::sockaddr_in {
|
||||
sin_family: c::AF_INET as c::sa_family_t,
|
||||
sin_port: hton(port),
|
||||
sin_addr: *ip.as_inner(),
|
||||
.. unsafe { mem::zeroed() }
|
||||
|
@ -93,7 +93,7 @@ impl SocketAddrV4 {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ip(&self) -> &Ipv4Addr {
|
||||
unsafe {
|
||||
&*(&self.inner.sin_addr as *const libc::in_addr as *const Ipv4Addr)
|
||||
&*(&self.inner.sin_addr as *const c::in_addr as *const Ipv4Addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -109,8 +109,8 @@ impl SocketAddrV6 {
|
|||
pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32)
|
||||
-> SocketAddrV6 {
|
||||
SocketAddrV6 {
|
||||
inner: libc::sockaddr_in6 {
|
||||
sin6_family: libc::AF_INET6 as sa_family_t,
|
||||
inner: c::sockaddr_in6 {
|
||||
sin6_family: c::AF_INET6 as c::sa_family_t,
|
||||
sin6_port: hton(port),
|
||||
sin6_addr: *ip.as_inner(),
|
||||
sin6_flowinfo: hton(flowinfo),
|
||||
|
@ -124,7 +124,7 @@ impl SocketAddrV6 {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ip(&self) -> &Ipv6Addr {
|
||||
unsafe {
|
||||
&*(&self.inner.sin6_addr as *const libc::in6_addr as *const Ipv6Addr)
|
||||
&*(&self.inner.sin6_addr as *const c::in6_addr as *const Ipv6Addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,26 +143,26 @@ impl SocketAddrV6 {
|
|||
pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) }
|
||||
}
|
||||
|
||||
impl FromInner<libc::sockaddr_in> for SocketAddrV4 {
|
||||
fn from_inner(addr: libc::sockaddr_in) -> SocketAddrV4 {
|
||||
impl FromInner<c::sockaddr_in> for SocketAddrV4 {
|
||||
fn from_inner(addr: c::sockaddr_in) -> SocketAddrV4 {
|
||||
SocketAddrV4 { inner: addr }
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<libc::sockaddr_in6> for SocketAddrV6 {
|
||||
fn from_inner(addr: libc::sockaddr_in6) -> SocketAddrV6 {
|
||||
impl FromInner<c::sockaddr_in6> for SocketAddrV6 {
|
||||
fn from_inner(addr: c::sockaddr_in6) -> SocketAddrV6 {
|
||||
SocketAddrV6 { inner: addr }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> IntoInner<(*const libc::sockaddr, socklen_t)> for &'a SocketAddr {
|
||||
fn into_inner(self) -> (*const libc::sockaddr, socklen_t) {
|
||||
impl<'a> IntoInner<(*const c::sockaddr, c::socklen_t)> for &'a SocketAddr {
|
||||
fn into_inner(self) -> (*const c::sockaddr, c::socklen_t) {
|
||||
match *self {
|
||||
SocketAddr::V4(ref a) => {
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
|
||||
}
|
||||
SocketAddr::V6(ref a) => {
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
|
||||
(a as *const _ as *const _, mem::size_of_val(a) as c::socklen_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
use prelude::v1::*;
|
||||
|
||||
use cmp::Ordering;
|
||||
use hash;
|
||||
use fmt;
|
||||
use libc;
|
||||
use sys_common::{AsInner, FromInner};
|
||||
use hash;
|
||||
use mem;
|
||||
use net::{hton, ntoh};
|
||||
use sys::net::netc as c;
|
||||
use sys_common::{AsInner, FromInner};
|
||||
|
||||
/// An IP address, either an IPv4 or IPv6 address.
|
||||
#[unstable(feature = "ip_addr", reason = "recent addition", issue = "27801")]
|
||||
|
@ -36,14 +37,14 @@ pub enum IpAddr {
|
|||
#[derive(Copy)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Ipv4Addr {
|
||||
inner: libc::in_addr,
|
||||
inner: c::in_addr,
|
||||
}
|
||||
|
||||
/// Representation of an IPv6 address.
|
||||
#[derive(Copy)]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Ipv6Addr {
|
||||
inner: libc::in6_addr,
|
||||
inner: c::in6_addr,
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
|
@ -65,7 +66,7 @@ impl Ipv4Addr {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
|
||||
Ipv4Addr {
|
||||
inner: libc::in_addr {
|
||||
inner: c::in_addr {
|
||||
s_addr: hton(((a as u32) << 24) |
|
||||
((b as u32) << 16) |
|
||||
((c as u32) << 8) |
|
||||
|
@ -239,11 +240,11 @@ impl Ord for Ipv4Addr {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsInner<libc::in_addr> for Ipv4Addr {
|
||||
fn as_inner(&self) -> &libc::in_addr { &self.inner }
|
||||
impl AsInner<c::in_addr> for Ipv4Addr {
|
||||
fn as_inner(&self) -> &c::in_addr { &self.inner }
|
||||
}
|
||||
impl FromInner<libc::in_addr> for Ipv4Addr {
|
||||
fn from_inner(addr: libc::in_addr) -> Ipv4Addr {
|
||||
impl FromInner<c::in_addr> for Ipv4Addr {
|
||||
fn from_inner(addr: c::in_addr) -> Ipv4Addr {
|
||||
Ipv4Addr { inner: addr }
|
||||
}
|
||||
}
|
||||
|
@ -270,25 +271,32 @@ impl Ipv6Addr {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
|
||||
h: u16) -> Ipv6Addr {
|
||||
Ipv6Addr {
|
||||
inner: libc::in6_addr {
|
||||
s6_addr: [hton(a), hton(b), hton(c), hton(d),
|
||||
hton(e), hton(f), hton(g), hton(h)]
|
||||
}
|
||||
}
|
||||
let mut addr: c::in6_addr = unsafe { mem::zeroed() };
|
||||
addr.s6_addr = [(a >> 8) as u8, a as u8,
|
||||
(b >> 8) as u8, b as u8,
|
||||
(c >> 8) as u8, c as u8,
|
||||
(d >> 8) as u8, d as u8,
|
||||
(e >> 8) as u8, e as u8,
|
||||
(f >> 8) as u8, f as u8,
|
||||
(g >> 8) as u8, g as u8,
|
||||
(h >> 8) as u8, h as u8];
|
||||
Ipv6Addr { inner: addr }
|
||||
}
|
||||
|
||||
/// Returns the eight 16-bit segments that make up this address.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn segments(&self) -> [u16; 8] {
|
||||
[ntoh(self.inner.s6_addr[0]),
|
||||
ntoh(self.inner.s6_addr[1]),
|
||||
ntoh(self.inner.s6_addr[2]),
|
||||
ntoh(self.inner.s6_addr[3]),
|
||||
ntoh(self.inner.s6_addr[4]),
|
||||
ntoh(self.inner.s6_addr[5]),
|
||||
ntoh(self.inner.s6_addr[6]),
|
||||
ntoh(self.inner.s6_addr[7])]
|
||||
let arr = &self.inner.s6_addr;
|
||||
[
|
||||
(arr[0] as u16) << 8 | (arr[1] as u16),
|
||||
(arr[2] as u16) << 8 | (arr[3] as u16),
|
||||
(arr[4] as u16) << 8 | (arr[5] as u16),
|
||||
(arr[6] as u16) << 8 | (arr[7] as u16),
|
||||
(arr[8] as u16) << 8 | (arr[9] as u16),
|
||||
(arr[10] as u16) << 8 | (arr[11] as u16),
|
||||
(arr[12] as u16) << 8 | (arr[13] as u16),
|
||||
(arr[14] as u16) << 8 | (arr[15] as u16),
|
||||
]
|
||||
}
|
||||
|
||||
/// Returns true for the special 'unspecified' address ::.
|
||||
|
@ -502,11 +510,11 @@ impl Ord for Ipv6Addr {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsInner<libc::in6_addr> for Ipv6Addr {
|
||||
fn as_inner(&self) -> &libc::in6_addr { &self.inner }
|
||||
impl AsInner<c::in6_addr> for Ipv6Addr {
|
||||
fn as_inner(&self) -> &c::in6_addr { &self.inner }
|
||||
}
|
||||
impl FromInner<libc::in6_addr> for Ipv6Addr {
|
||||
fn from_inner(addr: libc::in6_addr) -> Ipv6Addr {
|
||||
impl FromInner<c::in6_addr> for Ipv6Addr {
|
||||
fn from_inner(addr: c::in6_addr) -> Ipv6Addr {
|
||||
Ipv6Addr { inner: addr }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
#![stable(feature = "raw_os", since = "1.1.0")]
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[cfg(any(target_arch = "aarch64", target_os = "android"))]
|
||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
|
||||
#[cfg(not(target_arch = "aarch64"))]
|
||||
#[cfg(not(any(target_arch = "aarch64", target_os = "android")))]
|
||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
|
||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
|
||||
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
|
||||
|
|
|
@ -252,10 +252,7 @@ mod imp {
|
|||
use io;
|
||||
use mem;
|
||||
use rand::Rng;
|
||||
use libc::types::os::arch::extra::{LONG_PTR};
|
||||
use libc::{DWORD, BYTE, LPCSTR, BOOL};
|
||||
|
||||
type HCRYPTPROV = LONG_PTR;
|
||||
use sys::c;
|
||||
|
||||
/// A random number generator that retrieves randomness straight from
|
||||
/// the operating system. Platform sources:
|
||||
|
@ -268,25 +265,7 @@ mod imp {
|
|||
///
|
||||
/// This does not block.
|
||||
pub struct OsRng {
|
||||
hcryptprov: HCRYPTPROV
|
||||
}
|
||||
|
||||
const PROV_RSA_FULL: DWORD = 1;
|
||||
const CRYPT_SILENT: DWORD = 64;
|
||||
const CRYPT_VERIFYCONTEXT: DWORD = 0xF0000000;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[link(name = "advapi32")]
|
||||
extern "system" {
|
||||
fn CryptAcquireContextA(phProv: *mut HCRYPTPROV,
|
||||
pszContainer: LPCSTR,
|
||||
pszProvider: LPCSTR,
|
||||
dwProvType: DWORD,
|
||||
dwFlags: DWORD) -> BOOL;
|
||||
fn CryptGenRandom(hProv: HCRYPTPROV,
|
||||
dwLen: DWORD,
|
||||
pbBuffer: *mut BYTE) -> BOOL;
|
||||
fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) -> BOOL;
|
||||
hcryptprov: c::HCRYPTPROV
|
||||
}
|
||||
|
||||
impl OsRng {
|
||||
|
@ -294,9 +273,9 @@ mod imp {
|
|||
pub fn new() -> io::Result<OsRng> {
|
||||
let mut hcp = 0;
|
||||
let ret = unsafe {
|
||||
CryptAcquireContextA(&mut hcp, 0 as LPCSTR, 0 as LPCSTR,
|
||||
PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_SILENT)
|
||||
c::CryptAcquireContextA(&mut hcp, 0 as c::LPCSTR, 0 as c::LPCSTR,
|
||||
c::PROV_RSA_FULL,
|
||||
c::CRYPT_VERIFYCONTEXT | c::CRYPT_SILENT)
|
||||
};
|
||||
|
||||
if ret == 0 {
|
||||
|
@ -320,8 +299,8 @@ mod imp {
|
|||
}
|
||||
fn fill_bytes(&mut self, v: &mut [u8]) {
|
||||
let ret = unsafe {
|
||||
CryptGenRandom(self.hcryptprov, v.len() as DWORD,
|
||||
v.as_mut_ptr())
|
||||
c::CryptGenRandom(self.hcryptprov, v.len() as c::DWORD,
|
||||
v.as_mut_ptr())
|
||||
};
|
||||
if ret == 0 {
|
||||
panic!("couldn't generate random bytes: {}",
|
||||
|
@ -333,7 +312,7 @@ mod imp {
|
|||
impl Drop for OsRng {
|
||||
fn drop(&mut self) {
|
||||
let ret = unsafe {
|
||||
CryptReleaseContext(self.hcryptprov, 0)
|
||||
c::CryptReleaseContext(self.hcryptprov, 0)
|
||||
};
|
||||
if ret == 0 {
|
||||
panic!("couldn't release context: {}",
|
||||
|
|
|
@ -12,10 +12,10 @@ use prelude::v1::*;
|
|||
|
||||
use sync::atomic::{AtomicUsize, Ordering};
|
||||
use sync::{mutex, MutexGuard, PoisonError};
|
||||
use sys::time::SteadyTime;
|
||||
use sys_common::condvar as sys;
|
||||
use sys_common::mutex as sys_mutex;
|
||||
use sys_common::poison::{self, LockResult};
|
||||
use sys::time::SteadyTime;
|
||||
use time::Duration;
|
||||
|
||||
/// A type indicating whether a timed wait on a condition variable returned
|
||||
|
|
|
@ -13,13 +13,13 @@ use prelude::v1::*;
|
|||
use ffi::{CStr, CString};
|
||||
use fmt;
|
||||
use io::{self, Error, ErrorKind};
|
||||
use libc::{self, c_int, c_char, c_void, socklen_t};
|
||||
use libc::{c_int, c_char, c_void};
|
||||
use mem;
|
||||
use net::{SocketAddr, Shutdown, IpAddr};
|
||||
use ptr;
|
||||
use str::from_utf8;
|
||||
use sys::c;
|
||||
use sys::net::{cvt, cvt_r, cvt_gai, Socket, init, wrlen_t};
|
||||
use sys::net::netc as c;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use time::Duration;
|
||||
|
||||
|
@ -31,8 +31,8 @@ pub fn setsockopt<T>(sock: &Socket, opt: c_int, val: c_int,
|
|||
payload: T) -> io::Result<()> {
|
||||
unsafe {
|
||||
let payload = &payload as *const T as *const c_void;
|
||||
try!(cvt(libc::setsockopt(*sock.as_inner(), opt, val, payload,
|
||||
mem::size_of::<T>() as socklen_t)));
|
||||
try!(cvt(c::setsockopt(*sock.as_inner(), opt, val, payload,
|
||||
mem::size_of::<T>() as c::socklen_t)));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int,
|
|||
val: c_int) -> io::Result<T> {
|
||||
unsafe {
|
||||
let mut slot: T = mem::zeroed();
|
||||
let mut len = mem::size_of::<T>() as socklen_t;
|
||||
let mut len = mem::size_of::<T>() as c::socklen_t;
|
||||
try!(cvt(c::getsockopt(*sock.as_inner(), opt, val,
|
||||
&mut slot as *mut _ as *mut _,
|
||||
&mut len)));
|
||||
|
@ -51,29 +51,29 @@ pub fn getsockopt<T: Copy>(sock: &Socket, opt: c_int,
|
|||
}
|
||||
|
||||
fn sockname<F>(f: F) -> io::Result<SocketAddr>
|
||||
where F: FnOnce(*mut libc::sockaddr, *mut socklen_t) -> c_int
|
||||
where F: FnOnce(*mut c::sockaddr, *mut c::socklen_t) -> c_int
|
||||
{
|
||||
unsafe {
|
||||
let mut storage: libc::sockaddr_storage = mem::zeroed();
|
||||
let mut len = mem::size_of_val(&storage) as socklen_t;
|
||||
let mut storage: c::sockaddr_storage = mem::zeroed();
|
||||
let mut len = mem::size_of_val(&storage) as c::socklen_t;
|
||||
try!(cvt(f(&mut storage as *mut _ as *mut _, &mut len)));
|
||||
sockaddr_to_addr(&storage, len as usize)
|
||||
}
|
||||
}
|
||||
|
||||
fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
|
||||
fn sockaddr_to_addr(storage: &c::sockaddr_storage,
|
||||
len: usize) -> io::Result<SocketAddr> {
|
||||
match storage.ss_family as libc::c_int {
|
||||
libc::AF_INET => {
|
||||
assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
|
||||
match storage.ss_family as c_int {
|
||||
c::AF_INET => {
|
||||
assert!(len as usize >= mem::size_of::<c::sockaddr_in>());
|
||||
Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
|
||||
*(storage as *const _ as *const libc::sockaddr_in)
|
||||
*(storage as *const _ as *const c::sockaddr_in)
|
||||
})))
|
||||
}
|
||||
libc::AF_INET6 => {
|
||||
assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
|
||||
c::AF_INET6 => {
|
||||
assert!(len as usize >= mem::size_of::<c::sockaddr_in6>());
|
||||
Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
|
||||
*(storage as *const _ as *const libc::sockaddr_in6)
|
||||
*(storage as *const _ as *const c::sockaddr_in6)
|
||||
})))
|
||||
}
|
||||
_ => {
|
||||
|
@ -86,16 +86,9 @@ fn sockaddr_to_addr(storage: &libc::sockaddr_storage,
|
|||
// get_host_addresses
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "system" {
|
||||
fn getaddrinfo(node: *const c_char, service: *const c_char,
|
||||
hints: *const libc::addrinfo,
|
||||
res: *mut *mut libc::addrinfo) -> c_int;
|
||||
fn freeaddrinfo(res: *mut libc::addrinfo);
|
||||
}
|
||||
|
||||
pub struct LookupHost {
|
||||
original: *mut libc::addrinfo,
|
||||
cur: *mut libc::addrinfo,
|
||||
original: *mut c::addrinfo,
|
||||
cur: *mut c::addrinfo,
|
||||
}
|
||||
|
||||
impl Iterator for LookupHost {
|
||||
|
@ -105,7 +98,7 @@ impl Iterator for LookupHost {
|
|||
if self.cur.is_null() { return None }
|
||||
let ret = sockaddr_to_addr(mem::transmute((*self.cur).ai_addr),
|
||||
(*self.cur).ai_addrlen as usize);
|
||||
self.cur = (*self.cur).ai_next as *mut libc::addrinfo;
|
||||
self.cur = (*self.cur).ai_next as *mut c::addrinfo;
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +109,7 @@ unsafe impl Send for LookupHost {}
|
|||
|
||||
impl Drop for LookupHost {
|
||||
fn drop(&mut self) {
|
||||
unsafe { freeaddrinfo(self.original) }
|
||||
unsafe { c::freeaddrinfo(self.original) }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,8 +119,8 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
|||
let c_host = try!(CString::new(host));
|
||||
let mut res = ptr::null_mut();
|
||||
unsafe {
|
||||
try!(cvt_gai(getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
|
||||
&mut res)));
|
||||
try!(cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
|
||||
&mut res)));
|
||||
Ok(LookupHost { original: res, cur: res })
|
||||
}
|
||||
}
|
||||
|
@ -136,26 +129,18 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
|
|||
// lookup_addr
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "system" {
|
||||
fn getnameinfo(sa: *const libc::sockaddr, salen: socklen_t,
|
||||
host: *mut c_char, hostlen: libc::size_t,
|
||||
serv: *mut c_char, servlen: libc::size_t,
|
||||
flags: c_int) -> c_int;
|
||||
}
|
||||
|
||||
const NI_MAXHOST: usize = 1025;
|
||||
|
||||
pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
|
||||
init();
|
||||
|
||||
let saddr = SocketAddr::new(*addr, 0);
|
||||
let (inner, len) = saddr.into_inner();
|
||||
let mut hostbuf = [0 as c_char; NI_MAXHOST];
|
||||
let mut hostbuf = [0 as c_char; c::NI_MAXHOST as usize];
|
||||
|
||||
let data = unsafe {
|
||||
try!(cvt_gai(getnameinfo(inner, len,
|
||||
hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
|
||||
ptr::null_mut(), 0, 0)));
|
||||
try!(cvt_gai(c::getnameinfo(inner, len,
|
||||
hostbuf.as_mut_ptr(),
|
||||
c::NI_MAXHOST,
|
||||
ptr::null_mut(), 0, 0)));
|
||||
|
||||
CStr::from_ptr(hostbuf.as_ptr())
|
||||
};
|
||||
|
@ -179,10 +164,10 @@ impl TcpStream {
|
|||
pub fn connect(addr: &SocketAddr) -> io::Result<TcpStream> {
|
||||
init();
|
||||
|
||||
let sock = try!(Socket::new(addr, libc::SOCK_STREAM));
|
||||
let sock = try!(Socket::new(addr, c::SOCK_STREAM));
|
||||
|
||||
let (addrp, len) = addr.into_inner();
|
||||
try!(cvt_r(|| unsafe { libc::connect(*sock.as_inner(), addrp, len) }));
|
||||
try!(cvt_r(|| unsafe { c::connect(*sock.as_inner(), addrp, len) }));
|
||||
Ok(TcpStream { inner: sock })
|
||||
}
|
||||
|
||||
|
@ -191,19 +176,19 @@ impl TcpStream {
|
|||
pub fn into_socket(self) -> Socket { self.inner }
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, libc::SO_RCVTIMEO)
|
||||
self.inner.set_timeout(dur, c::SO_RCVTIMEO)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, libc::SO_SNDTIMEO)
|
||||
self.inner.set_timeout(dur, c::SO_SNDTIMEO)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(libc::SO_RCVTIMEO)
|
||||
self.inner.timeout(c::SO_RCVTIMEO)
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(libc::SO_SNDTIMEO)
|
||||
self.inner.timeout(c::SO_SNDTIMEO)
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
|
@ -212,36 +197,28 @@ impl TcpStream {
|
|||
|
||||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let ret = try!(cvt(unsafe {
|
||||
libc::send(*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len() as wrlen_t,
|
||||
0)
|
||||
c::send(*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void,
|
||||
buf.len() as wrlen_t,
|
||||
0)
|
||||
}));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
||||
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe {
|
||||
libc::getpeername(*self.inner.as_inner(), buf, len)
|
||||
c::getpeername(*self.inner.as_inner(), buf, len)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe {
|
||||
libc::getsockname(*self.inner.as_inner(), buf, len)
|
||||
c::getsockname(*self.inner.as_inner(), buf, len)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
use libc::consts::os::bsd44::SHUT_RDWR;
|
||||
|
||||
let how = match how {
|
||||
Shutdown::Write => libc::SHUT_WR,
|
||||
Shutdown::Read => libc::SHUT_RD,
|
||||
Shutdown::Both => SHUT_RDWR,
|
||||
};
|
||||
try!(cvt(unsafe { libc::shutdown(*self.inner.as_inner(), how) }));
|
||||
Ok(())
|
||||
self.inner.shutdown(how)
|
||||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<TcpStream> {
|
||||
|
@ -285,22 +262,22 @@ impl TcpListener {
|
|||
pub fn bind(addr: &SocketAddr) -> io::Result<TcpListener> {
|
||||
init();
|
||||
|
||||
let sock = try!(Socket::new(addr, libc::SOCK_STREAM));
|
||||
let sock = try!(Socket::new(addr, c::SOCK_STREAM));
|
||||
|
||||
// On platforms with Berkeley-derived sockets, this allows
|
||||
// to quickly rebind a socket, without needing to wait for
|
||||
// the OS to clean up the previous one.
|
||||
if !cfg!(windows) {
|
||||
try!(setsockopt(&sock, libc::SOL_SOCKET, libc::SO_REUSEADDR,
|
||||
try!(setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR,
|
||||
1 as c_int));
|
||||
}
|
||||
|
||||
// Bind our new socket
|
||||
let (addrp, len) = addr.into_inner();
|
||||
try!(cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len) }));
|
||||
try!(cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }));
|
||||
|
||||
// Start listening
|
||||
try!(cvt(unsafe { libc::listen(*sock.as_inner(), 128) }));
|
||||
try!(cvt(unsafe { c::listen(*sock.as_inner(), 128) }));
|
||||
Ok(TcpListener { inner: sock })
|
||||
}
|
||||
|
||||
|
@ -310,13 +287,13 @@ impl TcpListener {
|
|||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe {
|
||||
libc::getsockname(*self.inner.as_inner(), buf, len)
|
||||
c::getsockname(*self.inner.as_inner(), buf, len)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut len = mem::size_of_val(&storage) as socklen_t;
|
||||
let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut len = mem::size_of_val(&storage) as c::socklen_t;
|
||||
let sock = try!(self.inner.accept(&mut storage as *mut _ as *mut _,
|
||||
&mut len));
|
||||
let addr = try!(sockaddr_to_addr(&storage, len as usize));
|
||||
|
@ -360,9 +337,9 @@ impl UdpSocket {
|
|||
pub fn bind(addr: &SocketAddr) -> io::Result<UdpSocket> {
|
||||
init();
|
||||
|
||||
let sock = try!(Socket::new(addr, libc::SOCK_DGRAM));
|
||||
let sock = try!(Socket::new(addr, c::SOCK_DGRAM));
|
||||
let (addrp, len) = addr.into_inner();
|
||||
try!(cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len) }));
|
||||
try!(cvt(unsafe { c::bind(*sock.as_inner(), addrp, len) }));
|
||||
Ok(UdpSocket { inner: sock })
|
||||
}
|
||||
|
||||
|
@ -372,19 +349,19 @@ impl UdpSocket {
|
|||
|
||||
pub fn socket_addr(&self) -> io::Result<SocketAddr> {
|
||||
sockname(|buf, len| unsafe {
|
||||
libc::getsockname(*self.inner.as_inner(), buf, len)
|
||||
c::getsockname(*self.inner.as_inner(), buf, len)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
|
||||
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut addrlen = mem::size_of_val(&storage) as socklen_t;
|
||||
let mut storage: c::sockaddr_storage = unsafe { mem::zeroed() };
|
||||
let mut addrlen = mem::size_of_val(&storage) as c::socklen_t;
|
||||
|
||||
let n = try!(cvt(unsafe {
|
||||
libc::recvfrom(*self.inner.as_inner(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len() as wrlen_t, 0,
|
||||
&mut storage as *mut _ as *mut _, &mut addrlen)
|
||||
c::recvfrom(*self.inner.as_inner(),
|
||||
buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len() as wrlen_t, 0,
|
||||
&mut storage as *mut _ as *mut _, &mut addrlen)
|
||||
}));
|
||||
Ok((n as usize, try!(sockaddr_to_addr(&storage, addrlen as usize))))
|
||||
}
|
||||
|
@ -392,9 +369,9 @@ impl UdpSocket {
|
|||
pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
|
||||
let (dstp, dstlen) = dst.into_inner();
|
||||
let ret = try!(cvt(unsafe {
|
||||
libc::sendto(*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void, buf.len() as wrlen_t,
|
||||
0, dstp, dstlen)
|
||||
c::sendto(*self.inner.as_inner(),
|
||||
buf.as_ptr() as *const c_void, buf.len() as wrlen_t,
|
||||
0, dstp, dstlen)
|
||||
}));
|
||||
Ok(ret as usize)
|
||||
}
|
||||
|
@ -404,19 +381,19 @@ impl UdpSocket {
|
|||
}
|
||||
|
||||
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, libc::SO_RCVTIMEO)
|
||||
self.inner.set_timeout(dur, c::SO_RCVTIMEO)
|
||||
}
|
||||
|
||||
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
|
||||
self.inner.set_timeout(dur, libc::SO_SNDTIMEO)
|
||||
self.inner.set_timeout(dur, c::SO_SNDTIMEO)
|
||||
}
|
||||
|
||||
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(libc::SO_RCVTIMEO)
|
||||
self.inner.timeout(c::SO_RCVTIMEO)
|
||||
}
|
||||
|
||||
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
|
||||
self.inner.timeout(libc::SO_SNDTIMEO)
|
||||
self.inner.timeout(c::SO_SNDTIMEO)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,45 +52,14 @@
|
|||
use prelude::v1::*;
|
||||
|
||||
use any::Any;
|
||||
use libc::{c_ulong, DWORD, c_void};
|
||||
use ptr;
|
||||
use sys_common::thread_local::StaticKey;
|
||||
use sys::c;
|
||||
|
||||
// 0x R U S T
|
||||
const RUST_PANIC: DWORD = 0x52555354;
|
||||
// 0x R U S T
|
||||
const RUST_PANIC: c::DWORD = 0x52555354;
|
||||
static PANIC_DATA: StaticKey = StaticKey::new(None);
|
||||
|
||||
// This function is provided by kernel32.dll
|
||||
extern "system" {
|
||||
#[unwind]
|
||||
fn RaiseException(dwExceptionCode: DWORD,
|
||||
dwExceptionFlags: DWORD,
|
||||
nNumberOfArguments: DWORD,
|
||||
lpArguments: *const c_ulong);
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EXCEPTION_POINTERS {
|
||||
ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||
ContextRecord: *mut CONTEXT,
|
||||
}
|
||||
|
||||
enum CONTEXT {}
|
||||
|
||||
#[repr(C)]
|
||||
struct EXCEPTION_RECORD {
|
||||
ExceptionCode: DWORD,
|
||||
ExceptionFlags: DWORD,
|
||||
ExceptionRecord: *mut _EXCEPTION_RECORD,
|
||||
ExceptionAddress: *mut c_void,
|
||||
NumberParameters: DWORD,
|
||||
ExceptionInformation: [*mut c_ulong; EXCEPTION_MAXIMUM_PARAMETERS],
|
||||
}
|
||||
|
||||
enum _EXCEPTION_RECORD {}
|
||||
|
||||
const EXCEPTION_MAXIMUM_PARAMETERS: usize = 15;
|
||||
|
||||
pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
|
||||
// See module docs above for an explanation of why `data` is stored in a
|
||||
// thread local instead of being passed as an argument to the
|
||||
|
@ -100,14 +69,14 @@ pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
|
|||
rtassert!(PANIC_DATA.get().is_null());
|
||||
PANIC_DATA.set(Box::into_raw(exception) as *mut u8);
|
||||
|
||||
RaiseException(RUST_PANIC, 0, 0, ptr::null());
|
||||
c::RaiseException(RUST_PANIC, 0, 0, ptr::null());
|
||||
rtabort!("could not unwind stack");
|
||||
}
|
||||
|
||||
pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
|
||||
// The `ptr` here actually corresponds to the code of the exception, and our
|
||||
// real data is stored in our thread local.
|
||||
rtassert!(ptr as DWORD == RUST_PANIC);
|
||||
rtassert!(ptr as c::DWORD == RUST_PANIC);
|
||||
|
||||
let data = PANIC_DATA.get() as *mut Box<Any + Send + 'static>;
|
||||
PANIC_DATA.set(ptr::null_mut());
|
||||
|
@ -139,7 +108,7 @@ fn rust_eh_personality() {
|
|||
#[lang = "msvc_try_filter"]
|
||||
#[linkage = "external"]
|
||||
#[allow(private_no_mangle_fns)]
|
||||
extern fn __rust_try_filter(eh_ptrs: *mut EXCEPTION_POINTERS,
|
||||
extern fn __rust_try_filter(eh_ptrs: *mut c::EXCEPTION_POINTERS,
|
||||
_rbp: *mut u8) -> i32 {
|
||||
unsafe {
|
||||
((*(*eh_ptrs).ExceptionRecord).ExceptionCode == RUST_PANIC) as i32
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
use prelude::v1::*;
|
||||
|
||||
use any::Any;
|
||||
use self::EXCEPTION_DISPOSITION::*;
|
||||
use sys_common::dwarf::eh;
|
||||
use core::mem;
|
||||
use core::ptr;
|
||||
use libc::{c_void, c_ulonglong, DWORD, LPVOID};
|
||||
type ULONG_PTR = c_ulonglong;
|
||||
use sys::c;
|
||||
|
||||
// Define our exception codes:
|
||||
// according to http://msdn.microsoft.com/en-us/library/het71c37(v=VS.80).aspx,
|
||||
|
@ -32,80 +30,10 @@ type ULONG_PTR = c_ulonglong;
|
|||
// we define bits:
|
||||
// [24:27] = type
|
||||
// [0:23] = magic
|
||||
const ETYPE: DWORD = 0b1110_u32 << 28;
|
||||
const MAGIC: DWORD = 0x525354; // "RST"
|
||||
const ETYPE: c::DWORD = 0b1110_u32 << 28;
|
||||
const MAGIC: c::DWORD = 0x525354; // "RST"
|
||||
|
||||
const RUST_PANIC: DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||
|
||||
const EXCEPTION_NONCONTINUABLE: DWORD = 0x1; // Noncontinuable exception
|
||||
const EXCEPTION_UNWINDING: DWORD = 0x2; // Unwind is in progress
|
||||
const EXCEPTION_EXIT_UNWIND: DWORD = 0x4; // Exit unwind is in progress
|
||||
const EXCEPTION_STACK_INVALID: DWORD = 0x8; // Stack out of limits or unaligned
|
||||
const EXCEPTION_NESTED_CALL: DWORD = 0x10; // Nested exception handler call
|
||||
const EXCEPTION_TARGET_UNWIND: DWORD = 0x20; // Target unwind in progress
|
||||
const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
|
||||
const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
|
||||
EXCEPTION_EXIT_UNWIND |
|
||||
EXCEPTION_TARGET_UNWIND |
|
||||
EXCEPTION_COLLIDED_UNWIND;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct EXCEPTION_RECORD {
|
||||
ExceptionCode: DWORD,
|
||||
ExceptionFlags: DWORD,
|
||||
ExceptionRecord: *const EXCEPTION_RECORD,
|
||||
ExceptionAddress: LPVOID,
|
||||
NumberParameters: DWORD,
|
||||
ExceptionInformation: [ULONG_PTR; 15],
|
||||
}
|
||||
|
||||
pub enum CONTEXT {}
|
||||
pub enum UNWIND_HISTORY_TABLE {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct RUNTIME_FUNCTION {
|
||||
BeginAddress: DWORD,
|
||||
EndAddress: DWORD,
|
||||
UnwindData: DWORD,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DISPATCHER_CONTEXT {
|
||||
ControlPc: LPVOID,
|
||||
ImageBase: LPVOID,
|
||||
FunctionEntry: *const RUNTIME_FUNCTION,
|
||||
EstablisherFrame: LPVOID,
|
||||
TargetIp: LPVOID,
|
||||
ContextRecord: *const CONTEXT,
|
||||
LanguageHandler: LPVOID,
|
||||
HandlerData: *const u8,
|
||||
HistoryTable: *const UNWIND_HISTORY_TABLE,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum EXCEPTION_DISPOSITION {
|
||||
ExceptionContinueExecution,
|
||||
ExceptionContinueSearch,
|
||||
ExceptionNestedException,
|
||||
ExceptionCollidedUnwind
|
||||
}
|
||||
|
||||
// From kernel32.dll
|
||||
extern "system" {
|
||||
#[unwind]
|
||||
fn RaiseException(dwExceptionCode: DWORD,
|
||||
dwExceptionFlags: DWORD,
|
||||
nNumberOfArguments: DWORD,
|
||||
lpArguments: *const ULONG_PTR);
|
||||
|
||||
fn RtlUnwindEx(TargetFrame: LPVOID,
|
||||
TargetIp: LPVOID,
|
||||
ExceptionRecord: *const EXCEPTION_RECORD,
|
||||
ReturnValue: LPVOID,
|
||||
OriginalContext: *const CONTEXT,
|
||||
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
||||
}
|
||||
const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||
|
||||
#[repr(C)]
|
||||
struct PanicData {
|
||||
|
@ -114,11 +42,11 @@ struct PanicData {
|
|||
|
||||
pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
|
||||
let panic_ctx = Box::new(PanicData { data: data });
|
||||
let params = [Box::into_raw(panic_ctx) as ULONG_PTR];
|
||||
RaiseException(RUST_PANIC,
|
||||
EXCEPTION_NONCONTINUABLE,
|
||||
params.len() as DWORD,
|
||||
¶ms as *const ULONG_PTR);
|
||||
let params = [Box::into_raw(panic_ctx) as c::ULONG_PTR];
|
||||
c::RaiseException(RUST_PANIC,
|
||||
c::EXCEPTION_NONCONTINUABLE,
|
||||
params.len() as c::DWORD,
|
||||
¶ms as *const c::ULONG_PTR);
|
||||
rtabort!("could not unwind stack");
|
||||
}
|
||||
|
||||
|
@ -152,11 +80,11 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send + 'static> {
|
|||
#[lang = "eh_personality_catch"]
|
||||
#[cfg(not(test))]
|
||||
unsafe extern fn rust_eh_personality_catch(
|
||||
exceptionRecord: *mut EXCEPTION_RECORD,
|
||||
establisherFrame: LPVOID,
|
||||
contextRecord: *mut CONTEXT,
|
||||
dispatcherContext: *mut DISPATCHER_CONTEXT
|
||||
) -> EXCEPTION_DISPOSITION
|
||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
||||
) -> c::EXCEPTION_DISPOSITION
|
||||
{
|
||||
rust_eh_personality(exceptionRecord, establisherFrame,
|
||||
contextRecord, dispatcherContext)
|
||||
|
@ -165,44 +93,44 @@ unsafe extern fn rust_eh_personality_catch(
|
|||
#[lang = "eh_personality"]
|
||||
#[cfg(not(test))]
|
||||
unsafe extern fn rust_eh_personality(
|
||||
exceptionRecord: *mut EXCEPTION_RECORD,
|
||||
establisherFrame: LPVOID,
|
||||
contextRecord: *mut CONTEXT,
|
||||
dispatcherContext: *mut DISPATCHER_CONTEXT
|
||||
) -> EXCEPTION_DISPOSITION
|
||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||
establisherFrame: c::LPVOID,
|
||||
contextRecord: *mut c::CONTEXT,
|
||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
||||
) -> c::EXCEPTION_DISPOSITION
|
||||
{
|
||||
let er = &*exceptionRecord;
|
||||
let dc = &*dispatcherContext;
|
||||
|
||||
if er.ExceptionFlags & EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
|
||||
if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
|
||||
if er.ExceptionCode == RUST_PANIC {
|
||||
if let Some(lpad) = find_landing_pad(dc) {
|
||||
RtlUnwindEx(establisherFrame,
|
||||
lpad as LPVOID,
|
||||
exceptionRecord,
|
||||
er.ExceptionInformation[0] as LPVOID, // pointer to PanicData
|
||||
contextRecord,
|
||||
dc.HistoryTable);
|
||||
c::RtlUnwindEx(establisherFrame,
|
||||
lpad as c::LPVOID,
|
||||
exceptionRecord,
|
||||
er.ExceptionInformation[0] as c::LPVOID, // pointer to PanicData
|
||||
contextRecord,
|
||||
dc.HistoryTable);
|
||||
rtabort!("could not unwind");
|
||||
}
|
||||
}
|
||||
}
|
||||
ExceptionContinueSearch
|
||||
c::ExceptionContinueSearch
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[lang = "eh_unwind_resume"]
|
||||
#[unwind]
|
||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: LPVOID) -> ! {
|
||||
let params = [panic_ctx as ULONG_PTR];
|
||||
RaiseException(RUST_PANIC,
|
||||
EXCEPTION_NONCONTINUABLE,
|
||||
params.len() as DWORD,
|
||||
¶ms as *const ULONG_PTR);
|
||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
|
||||
let params = [panic_ctx as c::ULONG_PTR];
|
||||
c::RaiseException(RUST_PANIC,
|
||||
c::EXCEPTION_NONCONTINUABLE,
|
||||
params.len() as c::DWORD,
|
||||
¶ms as *const c::ULONG_PTR);
|
||||
rtabort!("could not resume unwind");
|
||||
}
|
||||
|
||||
unsafe fn find_landing_pad(dc: &DISPATCHER_CONTEXT) -> Option<usize> {
|
||||
unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option<usize> {
|
||||
let eh_ctx = eh::EHContext {
|
||||
ip: dc.ControlPc as usize,
|
||||
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
||||
|
|
|
@ -1,452 +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.
|
||||
|
||||
//! C definitions used by std::sys that don't belong in liblibc
|
||||
|
||||
// These are definitions sufficient for the users in this directory.
|
||||
// This is not a general-purpose binding to this functionality, and in
|
||||
// some cases (notably the definition of siginfo_t), we intentionally
|
||||
// have incomplete bindings so that we don't need to fight with unions.
|
||||
//
|
||||
// Note that these types need to match the definitions from the platform
|
||||
// libc (currently glibc on Linux), not the kernel definitions / the
|
||||
// syscall interface. This has a few weirdnesses, like glibc's sigset_t
|
||||
// being 1024 bits on all platforms. If you're adding a new GNU/Linux
|
||||
// port, check glibc's sysdeps/unix/sysv/linux, not the kernel headers.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
pub use self::signal_os::*;
|
||||
use libc;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
pub const FIOCLEX: libc::c_ulong = 0x20006601;
|
||||
|
||||
#[cfg(any(all(target_os = "linux",
|
||||
any(target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64")),
|
||||
target_os = "android"))]
|
||||
pub const FIOCLEX: libc::c_ulong = 0x5451;
|
||||
|
||||
#[cfg(all(target_os = "linux",
|
||||
any(target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc")))]
|
||||
pub const FIOCLEX: libc::c_ulong = 0x6601;
|
||||
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub const FD_CLOEXEC: libc::c_int = 1;
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub const F_GETFD: libc::c_int = 1;
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub const F_SETFD: libc::c_int = 2;
|
||||
|
||||
pub const WNOHANG: libc::c_int = 1;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 70;
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly"))]
|
||||
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 71;
|
||||
#[cfg(any(target_os = "bitrig",
|
||||
target_os = "openbsd"))]
|
||||
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 101;
|
||||
#[cfg(target_os = "netbsd")]
|
||||
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 48;
|
||||
#[cfg(target_os = "android")]
|
||||
pub const _SC_GETPW_R_SIZE_MAX: libc::c_int = 0x0048;
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub struct passwd {
|
||||
pub pw_name: *mut libc::c_char,
|
||||
pub pw_passwd: *mut libc::c_char,
|
||||
pub pw_uid: libc::uid_t,
|
||||
pub pw_gid: libc::gid_t,
|
||||
pub pw_gecos: *mut libc::c_char,
|
||||
pub pw_dir: *mut libc::c_char,
|
||||
pub pw_shell: *mut libc::c_char,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub struct passwd {
|
||||
pub pw_name: *mut libc::c_char,
|
||||
pub pw_passwd: *mut libc::c_char,
|
||||
pub pw_uid: libc::uid_t,
|
||||
pub pw_gid: libc::gid_t,
|
||||
pub pw_comment: *mut libc::c_char,
|
||||
pub pw_gecos: *mut libc::c_char,
|
||||
pub pw_dir: *mut libc::c_char,
|
||||
pub pw_shell: *mut libc::c_char,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
pub struct passwd {
|
||||
pub pw_name: *mut libc::c_char,
|
||||
pub pw_passwd: *mut libc::c_char,
|
||||
pub pw_uid: libc::uid_t,
|
||||
pub pw_gid: libc::gid_t,
|
||||
pub pw_change: libc::time_t,
|
||||
pub pw_class: *mut libc::c_char,
|
||||
pub pw_gecos: *mut libc::c_char,
|
||||
pub pw_dir: *mut libc::c_char,
|
||||
pub pw_shell: *mut libc::c_char,
|
||||
pub pw_expire: libc::time_t,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[cfg(target_os = "android")]
|
||||
pub struct passwd {
|
||||
pub pw_name: *mut libc::c_char,
|
||||
pub pw_passwd: *mut libc::c_char,
|
||||
pub pw_uid: libc::uid_t,
|
||||
pub pw_gid: libc::gid_t,
|
||||
pub pw_dir: *mut libc::c_char,
|
||||
pub pw_shell: *mut libc::c_char,
|
||||
}
|
||||
|
||||
// This is really a function pointer (or a union of multiple function
|
||||
// pointers), except for constants like SIG_DFL.
|
||||
pub type sighandler_t = *mut libc::c_void;
|
||||
|
||||
pub const SIG_DFL: sighandler_t = 0 as sighandler_t;
|
||||
pub const SIG_ERR: sighandler_t = !0 as sighandler_t;
|
||||
|
||||
extern {
|
||||
pub fn getsockopt(sockfd: libc::c_int,
|
||||
level: libc::c_int,
|
||||
optname: libc::c_int,
|
||||
optval: *mut libc::c_void,
|
||||
optlen: *mut libc::socklen_t) -> libc::c_int;
|
||||
#[cfg(not(target_env = "newlib"))]
|
||||
pub fn ioctl(fd: libc::c_int, req: libc::c_ulong, ...) -> libc::c_int;
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub fn fnctl(fd: libc::c_int, req: libc::c_int, ...) -> libc::c_int;
|
||||
|
||||
|
||||
pub fn waitpid(pid: libc::pid_t, status: *mut libc::c_int,
|
||||
options: libc::c_int) -> libc::pid_t;
|
||||
|
||||
pub fn raise(signum: libc::c_int) -> libc::c_int;
|
||||
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigaction14")]
|
||||
pub fn sigaction(signum: libc::c_int,
|
||||
act: *const sigaction,
|
||||
oldact: *mut sigaction) -> libc::c_int;
|
||||
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigaltstack14")]
|
||||
#[cfg(not(target_env = "newlib"))]
|
||||
pub fn sigaltstack(ss: *const sigaltstack,
|
||||
oss: *mut sigaltstack) -> libc::c_int;
|
||||
|
||||
#[cfg(not(target_os = "android"))]
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")]
|
||||
pub fn sigemptyset(set: *mut sigset_t) -> libc::c_int;
|
||||
|
||||
pub fn pthread_sigmask(how: libc::c_int, set: *const sigset_t,
|
||||
oldset: *mut sigset_t) -> libc::c_int;
|
||||
|
||||
#[cfg(not(target_os = "ios"))]
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__getpwuid_r50")]
|
||||
pub fn getpwuid_r(uid: libc::uid_t,
|
||||
pwd: *mut passwd,
|
||||
buf: *mut libc::c_char,
|
||||
buflen: libc::size_t,
|
||||
result: *mut *mut passwd) -> libc::c_int;
|
||||
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__utimes50")]
|
||||
pub fn utimes(filename: *const libc::c_char,
|
||||
times: *const libc::timeval) -> libc::c_int;
|
||||
pub fn gai_strerror(errcode: libc::c_int) -> *const libc::c_char;
|
||||
/// Newlib has this, but only for Cygwin.
|
||||
#[cfg(not(target_os = "nacl"))]
|
||||
pub fn setgroups(ngroups: libc::c_int,
|
||||
ptr: *const libc::c_void) -> libc::c_int;
|
||||
pub fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
|
||||
-> *mut libc::c_char;
|
||||
}
|
||||
|
||||
// Ugh. This is only available as an inline until Android API 21.
|
||||
#[cfg(target_os = "android")]
|
||||
pub unsafe fn sigemptyset(set: *mut sigset_t) -> libc::c_int {
|
||||
use intrinsics;
|
||||
intrinsics::write_bytes(set, 0, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux",
|
||||
target_os = "android"))]
|
||||
mod signal_os {
|
||||
pub use self::arch::{SA_ONSTACK, SA_SIGINFO, SIGBUS, SIG_SETMASK,
|
||||
sigaction, sigaltstack};
|
||||
use libc;
|
||||
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
pub const SIGSTKSZ: libc::size_t = 8192;
|
||||
|
||||
// This is smaller on musl and Android, but no harm in being generous.
|
||||
#[cfg(any(target_arch = "aarch64",
|
||||
target_arch = "powerpc"))]
|
||||
pub const SIGSTKSZ: libc::size_t = 16384;
|
||||
|
||||
// This definition is intentionally a subset of the C structure: the
|
||||
// fields after si_code are actually a giant union. We're only
|
||||
// interested in si_addr for this module, though.
|
||||
#[repr(C)]
|
||||
pub struct siginfo {
|
||||
_signo: libc::c_int,
|
||||
_errno: libc::c_int,
|
||||
_code: libc::c_int,
|
||||
// This structure will need extra padding here for MIPS64.
|
||||
pub si_addr: *mut libc::c_void
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux", target_pointer_width = "32"))]
|
||||
#[repr(C)]
|
||||
pub struct sigset_t {
|
||||
__val: [libc::c_ulong; 32],
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "linux", target_pointer_width = "64"))]
|
||||
#[repr(C)]
|
||||
pub struct sigset_t {
|
||||
__val: [libc::c_ulong; 16],
|
||||
}
|
||||
|
||||
// Android for MIPS has a 128-bit sigset_t, but we don't currently
|
||||
// support it. Android for AArch64 technically has a structure of a
|
||||
// single ulong.
|
||||
#[cfg(target_os = "android")]
|
||||
pub type sigset_t = libc::c_ulong;
|
||||
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "x86_64",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64"))]
|
||||
mod arch {
|
||||
use libc;
|
||||
use super::super::sighandler_t;
|
||||
use super::sigset_t;
|
||||
|
||||
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub const SA_SIGINFO: libc::c_ulong = 0x00000004;
|
||||
|
||||
pub const SIGBUS: libc::c_int = 7;
|
||||
|
||||
pub const SIG_SETMASK: libc::c_int = 2;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
pub sa_flags: libc::c_ulong,
|
||||
_restorer: *mut libc::c_void,
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "32"))]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_flags: libc::c_ulong,
|
||||
_restorer: *mut libc::c_void,
|
||||
pub sa_mask: sigset_t,
|
||||
}
|
||||
|
||||
#[cfg(all(target_os = "android", target_pointer_width = "64"))]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_flags: libc::c_uint,
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
_restorer: *mut libc::c_void,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaltstack {
|
||||
pub ss_sp: *mut libc::c_void,
|
||||
pub ss_flags: libc::c_int,
|
||||
pub ss_size: libc::size_t
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "mips",
|
||||
target_arch = "mipsel"))]
|
||||
mod arch {
|
||||
use libc;
|
||||
use super::super::sighandler_t;
|
||||
use super::sigset_t;
|
||||
|
||||
pub const SA_ONSTACK: libc::c_ulong = 0x08000000;
|
||||
pub const SA_SIGINFO: libc::c_ulong = 0x00000008;
|
||||
|
||||
pub const SIGBUS: libc::c_int = 10;
|
||||
|
||||
pub const SIG_SETMASK: libc::c_int = 3;
|
||||
|
||||
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_flags: libc::c_uint,
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
_restorer: *mut libc::c_void,
|
||||
_resv: [libc::c_int; 1],
|
||||
}
|
||||
|
||||
#[cfg(target_env = "musl")]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
pub sa_flags: libc::c_ulong,
|
||||
_restorer: *mut libc::c_void,
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_flags: libc::c_uint,
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaltstack {
|
||||
pub ss_sp: *mut libc::c_void,
|
||||
pub ss_size: libc::size_t,
|
||||
pub ss_flags: libc::c_int,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Note: Although the signal functions are defined on NaCl, they always fail.
|
||||
/// Also, this could be cfg-ed on newlib instead of nacl, but these structures
|
||||
/// can differ depending on the platform, so I've played it safe here.
|
||||
#[cfg(target_os = "nacl")]
|
||||
mod signal_os {
|
||||
use libc;
|
||||
|
||||
pub static SA_NOCLDSTOP: libc::c_ulong = 1;
|
||||
pub static SA_SIGINFO: libc::c_ulong = 2;
|
||||
|
||||
pub type sigset_t = libc::c_ulong;
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_flags: libc::c_int,
|
||||
pub sa_mask: sigset_t,
|
||||
pub handler: extern fn(libc::c_int),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"))]
|
||||
mod signal_os {
|
||||
use libc;
|
||||
use super::sighandler_t;
|
||||
|
||||
pub const SA_ONSTACK: libc::c_int = 0x0001;
|
||||
pub const SA_SIGINFO: libc::c_int = 0x0040;
|
||||
|
||||
pub const SIGBUS: libc::c_int = 10;
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub const SIGSTKSZ: libc::size_t = 131072;
|
||||
// FreeBSD's is actually arch-dependent, but never more than 40960.
|
||||
// No harm in being generous.
|
||||
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
|
||||
pub const SIGSTKSZ: libc::size_t = 40960;
|
||||
|
||||
pub const SIG_SETMASK: libc::c_int = 3;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios"))]
|
||||
pub type sigset_t = u32;
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))]
|
||||
#[repr(C)]
|
||||
pub struct sigset_t {
|
||||
bits: [u32; 4],
|
||||
}
|
||||
#[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
|
||||
pub type sigset_t = libc::c_uint;
|
||||
|
||||
// This structure has more fields, but we're not all that interested in
|
||||
// them.
|
||||
#[cfg(any(target_os = "macos", target_os = "ios",
|
||||
target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[repr(C)]
|
||||
pub struct siginfo {
|
||||
pub _signo: libc::c_int,
|
||||
pub _errno: libc::c_int,
|
||||
pub _code: libc::c_int,
|
||||
pub _pid: libc::pid_t,
|
||||
pub _uid: libc::uid_t,
|
||||
pub _status: libc::c_int,
|
||||
pub si_addr: *mut libc::c_void
|
||||
}
|
||||
#[cfg(any(target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
|
||||
#[repr(C)]
|
||||
pub struct siginfo {
|
||||
pub si_signo: libc::c_int,
|
||||
pub si_code: libc::c_int,
|
||||
pub si_errno: libc::c_int,
|
||||
pub si_addr: *mut libc::c_void
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios",
|
||||
target_os = "bitrig", target_os = "netbsd", target_os = "openbsd"))]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_mask: sigset_t,
|
||||
pub sa_flags: libc::c_int,
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd", target_os = "dragonfly"))]
|
||||
#[repr(C)]
|
||||
pub struct sigaction {
|
||||
pub sa_sigaction: sighandler_t,
|
||||
pub sa_flags: libc::c_int,
|
||||
pub sa_mask: sigset_t,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct sigaltstack {
|
||||
pub ss_sp: *mut libc::c_void,
|
||||
pub ss_size: libc::size_t,
|
||||
pub ss_flags: libc::c_int,
|
||||
}
|
||||
}
|
|
@ -13,10 +13,9 @@ use libc;
|
|||
use ptr;
|
||||
use sys::mutex::{self, Mutex};
|
||||
use sys::time;
|
||||
use sys::sync as ffi;
|
||||
use time::Duration;
|
||||
|
||||
pub struct Condvar { inner: UnsafeCell<ffi::pthread_cond_t> }
|
||||
pub struct Condvar { inner: UnsafeCell<libc::pthread_cond_t> }
|
||||
|
||||
unsafe impl Send for Condvar {}
|
||||
unsafe impl Sync for Condvar {}
|
||||
|
@ -25,24 +24,24 @@ impl Condvar {
|
|||
pub const fn new() -> Condvar {
|
||||
// Might be moved and address is changing it is better to avoid
|
||||
// initialization of potentially opaque OS data before it landed
|
||||
Condvar { inner: UnsafeCell::new(ffi::PTHREAD_COND_INITIALIZER) }
|
||||
Condvar { inner: UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn notify_one(&self) {
|
||||
let r = ffi::pthread_cond_signal(self.inner.get());
|
||||
let r = libc::pthread_cond_signal(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn notify_all(&self) {
|
||||
let r = ffi::pthread_cond_broadcast(self.inner.get());
|
||||
let r = libc::pthread_cond_broadcast(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||
let r = ffi::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
|
||||
let r = libc::pthread_cond_wait(self.inner.get(), mutex::raw(mutex));
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
|
@ -55,7 +54,7 @@ impl Condvar {
|
|||
// report timeout based on stable time.
|
||||
let mut sys_now = libc::timeval { tv_sec: 0, tv_usec: 0 };
|
||||
let stable_now = time::SteadyTime::now();
|
||||
let r = ffi::gettimeofday(&mut sys_now, ptr::null_mut());
|
||||
let r = libc::gettimeofday(&mut sys_now, ptr::null_mut());
|
||||
debug_assert_eq!(r, 0);
|
||||
|
||||
let nsec = dur.subsec_nanos() as libc::c_long +
|
||||
|
@ -76,7 +75,7 @@ impl Condvar {
|
|||
});
|
||||
|
||||
// And wait!
|
||||
let r = ffi::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
|
||||
let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
|
||||
&timeout);
|
||||
debug_assert!(r == libc::ETIMEDOUT || r == 0);
|
||||
|
||||
|
@ -88,17 +87,17 @@ impl Condvar {
|
|||
#[inline]
|
||||
#[cfg(not(target_os = "dragonfly"))]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = ffi::pthread_cond_destroy(self.inner.get());
|
||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = ffi::pthread_cond_destroy(self.inner.get());
|
||||
let r = libc::pthread_cond_destroy(self.inner.get());
|
||||
// On DragonFly pthread_cond_destroy() returns EINVAL if called on
|
||||
// a condvar that was just initialized with
|
||||
// ffi::PTHREAD_COND_INITIALIZER. Once it is used or
|
||||
// libc::PTHREAD_COND_INITIALIZER. Once it is used or
|
||||
// pthread_cond_init() is called, this behaviour no longer occurs.
|
||||
debug_assert!(r == 0 || r == libc::EINVAL);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
use io;
|
||||
use libc::{self, c_int, size_t, c_void};
|
||||
use mem;
|
||||
use sys::c;
|
||||
use sys::cvt;
|
||||
use sys_common::AsInner;
|
||||
|
||||
|
@ -54,15 +53,15 @@ impl FileDesc {
|
|||
#[cfg(not(target_env = "newlib"))]
|
||||
pub fn set_cloexec(&self) {
|
||||
unsafe {
|
||||
let ret = c::ioctl(self.fd, c::FIOCLEX);
|
||||
let ret = libc::ioctl(self.fd, libc::FIOCLEX);
|
||||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
}
|
||||
#[cfg(target_env = "newlib")]
|
||||
pub fn set_cloexec(&self) {
|
||||
unsafe {
|
||||
let previous = c::fnctl(self.fd, c::F_GETFD);
|
||||
let ret = c::fnctl(self.fd, c::F_SETFD, previous | c::FD_CLOEXEC);
|
||||
let previous = libc::fnctl(self.fd, libc::F_GETFD);
|
||||
let ret = libc::fnctl(self.fd, libc::F_SETFD, previous | libc::FD_CLOEXEC);
|
||||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ use ptr;
|
|||
use sync::Arc;
|
||||
use sys::fd::FileDesc;
|
||||
use sys::platform::raw;
|
||||
use sys::{c, cvt, cvt_r};
|
||||
use sys::{cvt, cvt_r};
|
||||
use sys_common::{AsInner, FromInner};
|
||||
use vec::Vec;
|
||||
|
||||
|
@ -43,7 +43,7 @@ unsafe impl Send for Dir {}
|
|||
unsafe impl Sync for Dir {}
|
||||
|
||||
pub struct DirEntry {
|
||||
buf: Vec<u8>, // actually *mut libc::dirent_t
|
||||
buf: Vec<u8>, // actually *mut libc::dirent
|
||||
root: Arc<PathBuf>,
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ impl Iterator for ReadDir {
|
|||
let mut buf: Vec<u8> = Vec::with_capacity(unsafe {
|
||||
rust_dirent_t_size() as usize
|
||||
});
|
||||
let ptr = buf.as_mut_ptr() as *mut libc::dirent_t;
|
||||
let ptr = buf.as_mut_ptr() as *mut libc::dirent;
|
||||
|
||||
let mut entry_ptr = ptr::null_mut();
|
||||
loop {
|
||||
|
@ -179,7 +179,7 @@ impl DirEntry {
|
|||
|
||||
pub fn file_type(&self) -> io::Result<FileType> {
|
||||
extern {
|
||||
fn rust_dir_get_mode(ptr: *mut libc::dirent_t) -> c_int;
|
||||
fn rust_dir_get_mode(ptr: *mut libc::dirent) -> c_int;
|
||||
}
|
||||
unsafe {
|
||||
match rust_dir_get_mode(self.dirent()) {
|
||||
|
@ -191,21 +191,21 @@ impl DirEntry {
|
|||
|
||||
pub fn ino(&self) -> raw::ino_t {
|
||||
extern {
|
||||
fn rust_dir_get_ino(ptr: *mut libc::dirent_t) -> raw::ino_t;
|
||||
fn rust_dir_get_ino(ptr: *mut libc::dirent) -> raw::ino_t;
|
||||
}
|
||||
unsafe { rust_dir_get_ino(self.dirent()) }
|
||||
}
|
||||
|
||||
fn name_bytes(&self) -> &[u8] {
|
||||
extern {
|
||||
fn rust_list_dir_val(ptr: *mut libc::dirent_t) -> *const c_char;
|
||||
fn rust_list_dir_val(ptr: *mut libc::dirent) -> *const c_char;
|
||||
}
|
||||
unsafe {
|
||||
CStr::from_ptr(rust_list_dir_val(self.dirent())).to_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
fn dirent(&self) -> *mut libc::dirent_t {
|
||||
fn dirent(&self) -> *mut libc::dirent {
|
||||
self.buf.as_ptr() as *mut _
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ impl File {
|
|||
(false, false) => libc::O_RDONLY,
|
||||
};
|
||||
let fd = try!(cvt_r(|| unsafe {
|
||||
libc::open(path.as_ptr(), flags, opts.mode)
|
||||
libc::open(path.as_ptr(), flags, opts.mode as c_int)
|
||||
}));
|
||||
let fd = FileDesc::new(fd);
|
||||
// Even though we open with the O_CLOEXEC flag, still set CLOEXEC here,
|
||||
|
@ -532,7 +532,7 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
|||
let path = try!(CString::new(p.as_os_str().as_bytes()));
|
||||
let buf;
|
||||
unsafe {
|
||||
let r = c::realpath(path.as_ptr(), ptr::null_mut());
|
||||
let r = libc::realpath(path.as_ptr(), ptr::null_mut());
|
||||
if r.is_null() {
|
||||
return Err(io::Error::last_os_error())
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ use ops::Neg;
|
|||
#[cfg(target_os = "openbsd")] pub use os::openbsd as platform;
|
||||
|
||||
pub mod backtrace;
|
||||
pub mod c;
|
||||
pub mod condvar;
|
||||
pub mod ext;
|
||||
pub mod fd;
|
||||
|
@ -41,7 +40,6 @@ pub mod pipe;
|
|||
pub mod process;
|
||||
pub mod rwlock;
|
||||
pub mod stack_overflow;
|
||||
pub mod sync;
|
||||
pub mod thread;
|
||||
pub mod thread_local;
|
||||
pub mod time;
|
||||
|
@ -49,7 +47,7 @@ pub mod stdio;
|
|||
|
||||
#[cfg(not(target_os = "nacl"))]
|
||||
pub fn init() {
|
||||
use libc::funcs::posix01::signal::signal;
|
||||
use libc::signal;
|
||||
// By default, some platforms will send a *signal* when an EPIPE error
|
||||
// would otherwise be delivered. This runtime doesn't install a SIGPIPE
|
||||
// handler, causing it to kill the program, which isn't exactly what we
|
||||
|
@ -78,7 +76,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
|||
libc::EINTR => ErrorKind::Interrupted,
|
||||
libc::EINVAL => ErrorKind::InvalidInput,
|
||||
libc::ETIMEDOUT => ErrorKind::TimedOut,
|
||||
libc::consts::os::posix88::EEXIST => ErrorKind::AlreadyExists,
|
||||
libc::EEXIST => ErrorKind::AlreadyExists,
|
||||
|
||||
// These two constants can have the same value on some systems,
|
||||
// but different values on others, so we can't use a match
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
// except according to those terms.
|
||||
|
||||
use cell::UnsafeCell;
|
||||
use sys::sync as ffi;
|
||||
use libc;
|
||||
use mem;
|
||||
|
||||
pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
|
||||
pub struct Mutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
|
||||
pub unsafe fn raw(m: &Mutex) -> *mut libc::pthread_mutex_t {
|
||||
m.inner.get()
|
||||
}
|
||||
|
||||
|
@ -27,42 +27,42 @@ impl Mutex {
|
|||
pub const fn new() -> Mutex {
|
||||
// Might be moved and address is changing it is better to avoid
|
||||
// initialization of potentially opaque OS data before it landed
|
||||
Mutex { inner: UnsafeCell::new(ffi::PTHREAD_MUTEX_INITIALIZER) }
|
||||
Mutex { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn lock(&self) {
|
||||
let r = ffi::pthread_mutex_lock(self.inner.get());
|
||||
let r = libc::pthread_mutex_lock(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn unlock(&self) {
|
||||
let r = ffi::pthread_mutex_unlock(self.inner.get());
|
||||
let r = libc::pthread_mutex_unlock(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
ffi::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
libc::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
}
|
||||
#[inline]
|
||||
#[cfg(not(target_os = "dragonfly"))]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = ffi::pthread_mutex_destroy(self.inner.get());
|
||||
let r = libc::pthread_mutex_destroy(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
#[inline]
|
||||
#[cfg(target_os = "dragonfly")]
|
||||
pub unsafe fn destroy(&self) {
|
||||
use libc;
|
||||
let r = ffi::pthread_mutex_destroy(self.inner.get());
|
||||
let r = libc::pthread_mutex_destroy(self.inner.get());
|
||||
// On DragonFly pthread_mutex_destroy() returns EINVAL if called on a
|
||||
// mutex that was just initialized with ffi::PTHREAD_MUTEX_INITIALIZER.
|
||||
// mutex that was just initialized with libc::PTHREAD_MUTEX_INITIALIZER.
|
||||
// Once it is used (locked/unlocked) or pthread_mutex_init() is called,
|
||||
// this behaviour no longer occurs.
|
||||
debug_assert!(r == 0 || r == libc::EINVAL);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReentrantMutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
|
||||
pub struct ReentrantMutex { inner: UnsafeCell<libc::pthread_mutex_t> }
|
||||
|
||||
unsafe impl Send for ReentrantMutex {}
|
||||
unsafe impl Sync for ReentrantMutex {}
|
||||
|
@ -73,35 +73,35 @@ impl ReentrantMutex {
|
|||
}
|
||||
|
||||
pub unsafe fn init(&mut self) {
|
||||
let mut attr: ffi::pthread_mutexattr_t = mem::uninitialized();
|
||||
let result = ffi::pthread_mutexattr_init(&mut attr as *mut _);
|
||||
let mut attr: libc::pthread_mutexattr_t = mem::uninitialized();
|
||||
let result = libc::pthread_mutexattr_init(&mut attr as *mut _);
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = ffi::pthread_mutexattr_settype(&mut attr as *mut _,
|
||||
ffi::PTHREAD_MUTEX_RECURSIVE);
|
||||
let result = libc::pthread_mutexattr_settype(&mut attr as *mut _,
|
||||
libc::PTHREAD_MUTEX_RECURSIVE);
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = ffi::pthread_mutex_init(self.inner.get(), &attr as *const _);
|
||||
let result = libc::pthread_mutex_init(self.inner.get(), &attr as *const _);
|
||||
debug_assert_eq!(result, 0);
|
||||
let result = ffi::pthread_mutexattr_destroy(&mut attr as *mut _);
|
||||
let result = libc::pthread_mutexattr_destroy(&mut attr as *mut _);
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
pub unsafe fn lock(&self) {
|
||||
let result = ffi::pthread_mutex_lock(self.inner.get());
|
||||
let result = libc::pthread_mutex_lock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn try_lock(&self) -> bool {
|
||||
ffi::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
libc::pthread_mutex_trylock(self.inner.get()) == 0
|
||||
}
|
||||
|
||||
pub unsafe fn unlock(&self) {
|
||||
let result = ffi::pthread_mutex_unlock(self.inner.get());
|
||||
let result = libc::pthread_mutex_unlock(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
|
||||
pub unsafe fn destroy(&self) {
|
||||
let result = ffi::pthread_mutex_destroy(self.inner.get());
|
||||
let result = libc::pthread_mutex_destroy(self.inner.get());
|
||||
debug_assert_eq!(result, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,16 +13,16 @@ use prelude::v1::*;
|
|||
use ffi::CStr;
|
||||
use io;
|
||||
use libc::{self, c_int, size_t};
|
||||
use net::SocketAddr;
|
||||
use net::{SocketAddr, Shutdown};
|
||||
use str;
|
||||
use sync::atomic::{self, AtomicBool};
|
||||
use sys::c;
|
||||
use sync::atomic::{AtomicBool, Ordering};
|
||||
use sys::fd::FileDesc;
|
||||
use sys_common::{AsInner, FromInner, IntoInner};
|
||||
use sys_common::net::{getsockopt, setsockopt};
|
||||
use time::Duration;
|
||||
|
||||
pub use sys::{cvt, cvt_r};
|
||||
pub use libc as netc;
|
||||
|
||||
pub type wrlen_t = size_t;
|
||||
|
||||
|
@ -34,7 +34,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> {
|
|||
if err == 0 { return Ok(()) }
|
||||
|
||||
let detail = unsafe {
|
||||
str::from_utf8(CStr::from_ptr(c::gai_strerror(err)).to_bytes()).unwrap()
|
||||
str::from_utf8(CStr::from_ptr(libc::gai_strerror(err)).to_bytes()).unwrap()
|
||||
.to_owned()
|
||||
};
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
|
@ -67,29 +67,44 @@ impl Socket {
|
|||
}
|
||||
|
||||
pub fn duplicate(&self) -> io::Result<Socket> {
|
||||
use libc::funcs::posix88::fcntl::fcntl;
|
||||
// We want to atomically duplicate this file descriptor and set the
|
||||
// CLOEXEC flag, and currently that's done via F_DUPFD_CLOEXEC. This
|
||||
// flag, however, isn't supported on older Linux kernels (earlier than
|
||||
// 2.6.24).
|
||||
//
|
||||
// To detect this and ensure that CLOEXEC is still set, we
|
||||
// follow a strategy similar to musl [1] where if passing
|
||||
// F_DUPFD_CLOEXEC causes `fcntl` to return EINVAL it means it's not
|
||||
// supported (the third parameter, 0, is always valid), so we stop
|
||||
// trying that. We also *still* call the `set_cloexec` method as
|
||||
// apparently some kernel at some point stopped setting CLOEXEC even
|
||||
// though it reported doing so on F_DUPFD_CLOEXEC.
|
||||
//
|
||||
// Also note that Android doesn't have F_DUPFD_CLOEXEC, but get it to
|
||||
// resolve so we at least compile this.
|
||||
//
|
||||
// [1]: http://comments.gmane.org/gmane.linux.lib.musl.general/2963
|
||||
#[cfg(target_os = "android")]
|
||||
use libc::F_DUPFD as F_DUPFD_CLOEXEC;
|
||||
#[cfg(not(target_os = "android"))]
|
||||
use libc::F_DUPFD_CLOEXEC;
|
||||
|
||||
let make_socket = |fd| {
|
||||
let fd = FileDesc::new(fd);
|
||||
fd.set_cloexec();
|
||||
Socket(fd)
|
||||
};
|
||||
static EMULATE_F_DUPFD_CLOEXEC: AtomicBool = AtomicBool::new(false);
|
||||
if !EMULATE_F_DUPFD_CLOEXEC.load(atomic::Ordering::Relaxed) {
|
||||
match cvt(unsafe { fcntl(self.0.raw(), libc::F_DUPFD_CLOEXEC, 0) }) {
|
||||
// `EINVAL` can only be returned on two occasions: Invalid
|
||||
// command (second parameter) or invalid third parameter. 0 is
|
||||
// always a valid third parameter, so it must be the second
|
||||
// parameter.
|
||||
//
|
||||
// Store the result in a global variable so we don't try each
|
||||
// syscall twice.
|
||||
static TRY_CLOEXEC: AtomicBool = AtomicBool::new(true);
|
||||
let fd = self.0.raw();
|
||||
if !cfg!(target_os = "android") && TRY_CLOEXEC.load(Ordering::Relaxed) {
|
||||
match cvt(unsafe { libc::fcntl(fd, F_DUPFD_CLOEXEC, 0) }) {
|
||||
Err(ref e) if e.raw_os_error() == Some(libc::EINVAL) => {
|
||||
EMULATE_F_DUPFD_CLOEXEC.store(true, atomic::Ordering::Relaxed);
|
||||
TRY_CLOEXEC.store(false, Ordering::Relaxed);
|
||||
}
|
||||
res => return res.map(make_socket),
|
||||
}
|
||||
}
|
||||
cvt(unsafe { fcntl(self.0.raw(), libc::F_DUPFD, 0) }).map(make_socket)
|
||||
cvt(unsafe { libc::fcntl(fd, libc::F_DUPFD, 0) }).map(make_socket)
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
|
@ -138,6 +153,16 @@ impl Socket {
|
|||
Ok(Some(Duration::new(sec, nsec)))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
|
||||
let how = match how {
|
||||
Shutdown::Write => libc::SHUT_WR,
|
||||
Shutdown::Read => libc::SHUT_RD,
|
||||
Shutdown::Both => libc::SHUT_RDWR,
|
||||
};
|
||||
try!(cvt(unsafe { libc::shutdown(self.0.raw(), how) }));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<c_int> for Socket {
|
||||
|
|
|
@ -27,9 +27,8 @@ use ptr;
|
|||
use slice;
|
||||
use str;
|
||||
use sync::StaticMutex;
|
||||
use sys::c;
|
||||
use sys::fd;
|
||||
use sys::cvt;
|
||||
use sys::fd;
|
||||
use vec;
|
||||
|
||||
const TMPBUF_SZ: usize = 128;
|
||||
|
@ -230,8 +229,11 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
|||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
extern {
|
||||
fn _NSGetExecutablePath(buf: *mut libc::c_char,
|
||||
bufsize: *mut u32) -> libc::c_int;
|
||||
}
|
||||
unsafe {
|
||||
use libc::funcs::extra::_NSGetExecutablePath;
|
||||
let mut sz: u32 = 0;
|
||||
_NSGetExecutablePath(ptr::null_mut(), &mut sz);
|
||||
if sz == 0 { return Err(io::Error::last_os_error()); }
|
||||
|
@ -425,7 +427,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
|||
let v = try!(CString::new(v.as_bytes()));
|
||||
let _g = ENV_LOCK.lock();
|
||||
cvt(unsafe {
|
||||
libc::funcs::posix01::unistd::setenv(k.as_ptr(), v.as_ptr(), 1)
|
||||
libc::setenv(k.as_ptr(), v.as_ptr(), 1)
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
|
@ -433,7 +435,7 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
|
|||
let nbuf = try!(CString::new(n.as_bytes()));
|
||||
let _g = ENV_LOCK.lock();
|
||||
cvt(unsafe {
|
||||
libc::funcs::posix01::unistd::unsetenv(nbuf.as_ptr())
|
||||
libc::unsetenv(nbuf.as_ptr())
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
|
@ -466,18 +468,18 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||
target_os = "ios",
|
||||
target_os = "nacl")))]
|
||||
unsafe fn fallback() -> Option<OsString> {
|
||||
let amt = match libc::sysconf(c::_SC_GETPW_R_SIZE_MAX) {
|
||||
let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
|
||||
n if n < 0 => 512 as usize,
|
||||
n => n as usize,
|
||||
};
|
||||
let me = libc::getuid();
|
||||
loop {
|
||||
let mut buf = Vec::with_capacity(amt);
|
||||
let mut passwd: c::passwd = mem::zeroed();
|
||||
let mut passwd: libc::passwd = mem::zeroed();
|
||||
let mut result = ptr::null_mut();
|
||||
match c::getpwuid_r(me, &mut passwd, buf.as_mut_ptr(),
|
||||
buf.capacity() as libc::size_t,
|
||||
&mut result) {
|
||||
match libc::getpwuid_r(me, &mut passwd, buf.as_mut_ptr(),
|
||||
buf.capacity() as libc::size_t,
|
||||
&mut result) {
|
||||
0 if !result.is_null() => {}
|
||||
_ => return None
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ use ptr;
|
|||
use sys::fd::FileDesc;
|
||||
use sys::fs::{File, OpenOptions};
|
||||
use sys::pipe::AnonPipe;
|
||||
use sys::{self, c, cvt, cvt_r};
|
||||
use sys::{self, cvt, cvt_r};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Command
|
||||
|
@ -163,7 +163,7 @@ const CLOEXEC_MSG_FOOTER: &'static [u8] = b"NOEX";
|
|||
|
||||
impl Process {
|
||||
pub unsafe fn kill(&self) -> io::Result<()> {
|
||||
try!(cvt(libc::funcs::posix88::signal::kill(self.pid, libc::SIGKILL)));
|
||||
try!(cvt(libc::kill(self.pid, libc::SIGKILL)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -326,7 +326,7 @@ impl Process {
|
|||
// fail if we aren't root, so don't bother checking the
|
||||
// return value, this is just done as an optimistic
|
||||
// privilege dropping function.
|
||||
let _ = c::setgroups(0, ptr::null());
|
||||
let _ = libc::setgroups(0, ptr::null());
|
||||
|
||||
if libc::setuid(u as libc::uid_t) != 0 {
|
||||
fail(&mut output);
|
||||
|
@ -355,12 +355,12 @@ impl Process {
|
|||
// UNIX programs do not reset these things on their own, so we
|
||||
// need to clean things up now to avoid confusing the program
|
||||
// we're about to run.
|
||||
let mut set: c::sigset_t = mem::uninitialized();
|
||||
if c::sigemptyset(&mut set) != 0 ||
|
||||
c::pthread_sigmask(c::SIG_SETMASK, &set, ptr::null_mut()) != 0 ||
|
||||
libc::funcs::posix01::signal::signal(
|
||||
libc::SIGPIPE, mem::transmute(c::SIG_DFL)
|
||||
) == mem::transmute(c::SIG_ERR)
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
if libc::sigemptyset(&mut set) != 0 ||
|
||||
libc::pthread_sigmask(libc::SIG_SETMASK, &set, ptr::null_mut()) != 0 ||
|
||||
libc::signal(
|
||||
libc::SIGPIPE, mem::transmute(libc::SIG_DFL)
|
||||
) == mem::transmute(libc::SIG_ERR)
|
||||
{
|
||||
fail(output);
|
||||
}
|
||||
|
@ -381,14 +381,14 @@ impl Process {
|
|||
|
||||
pub fn wait(&self) -> io::Result<ExitStatus> {
|
||||
let mut status = 0 as c_int;
|
||||
try!(cvt_r(|| unsafe { c::waitpid(self.pid, &mut status, 0) }));
|
||||
try!(cvt_r(|| unsafe { libc::waitpid(self.pid, &mut status, 0) }));
|
||||
Ok(ExitStatus(status))
|
||||
}
|
||||
|
||||
pub fn try_wait(&self) -> Option<ExitStatus> {
|
||||
let mut status = 0 as c_int;
|
||||
match cvt_r(|| unsafe {
|
||||
c::waitpid(self.pid, &mut status, c::WNOHANG)
|
||||
libc::waitpid(self.pid, &mut status, libc::WNOHANG)
|
||||
}) {
|
||||
Ok(0) => None,
|
||||
Ok(n) if n == self.pid => Some(ExitStatus(status)),
|
||||
|
@ -459,7 +459,7 @@ mod tests {
|
|||
use ptr;
|
||||
use libc;
|
||||
use slice;
|
||||
use sys::{self, c, cvt, pipe};
|
||||
use sys::{self, cvt, pipe};
|
||||
|
||||
macro_rules! t {
|
||||
($e:expr) => {
|
||||
|
@ -473,12 +473,12 @@ mod tests {
|
|||
#[cfg(not(target_os = "android"))]
|
||||
extern {
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")]
|
||||
fn sigaddset(set: *mut c::sigset_t, signum: libc::c_int) -> libc::c_int;
|
||||
fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
unsafe fn sigaddset(set: *mut c::sigset_t, signum: libc::c_int) -> libc::c_int {
|
||||
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<c::sigset_t>());
|
||||
unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
|
||||
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
|
||||
let bit = (signum - 1) as usize;
|
||||
raw[bit / 8] |= 1 << (bit % 8);
|
||||
return 0;
|
||||
|
@ -497,11 +497,11 @@ mod tests {
|
|||
let (stdin_read, stdin_write) = t!(sys::pipe::anon_pipe());
|
||||
let (stdout_read, stdout_write) = t!(sys::pipe::anon_pipe());
|
||||
|
||||
let mut set: c::sigset_t = mem::uninitialized();
|
||||
let mut old_set: c::sigset_t = mem::uninitialized();
|
||||
t!(cvt(c::sigemptyset(&mut set)));
|
||||
let mut set: libc::sigset_t = mem::uninitialized();
|
||||
let mut old_set: libc::sigset_t = mem::uninitialized();
|
||||
t!(cvt(libc::sigemptyset(&mut set)));
|
||||
t!(cvt(sigaddset(&mut set, libc::SIGINT)));
|
||||
t!(cvt(c::pthread_sigmask(c::SIG_SETMASK, &set, &mut old_set)));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &set, &mut old_set)));
|
||||
|
||||
let cat = t!(Process::spawn(&cmd, Stdio::Raw(stdin_read.raw()),
|
||||
Stdio::Raw(stdout_write.raw()),
|
||||
|
@ -509,11 +509,10 @@ mod tests {
|
|||
drop(stdin_read);
|
||||
drop(stdout_write);
|
||||
|
||||
t!(cvt(c::pthread_sigmask(c::SIG_SETMASK, &old_set,
|
||||
ptr::null_mut())));
|
||||
t!(cvt(libc::pthread_sigmask(libc::SIG_SETMASK, &old_set,
|
||||
ptr::null_mut())));
|
||||
|
||||
t!(cvt(libc::funcs::posix88::signal::kill(cat.id() as libc::pid_t,
|
||||
libc::SIGINT)));
|
||||
t!(cvt(libc::kill(cat.id() as libc::pid_t, libc::SIGINT)));
|
||||
// We need to wait until SIGINT is definitely delivered. The
|
||||
// easiest way is to write something to cat, and try to read it
|
||||
// back: if SIGINT is unmasked, it'll get delivered when cat is
|
||||
|
|
|
@ -10,20 +10,19 @@
|
|||
|
||||
use libc;
|
||||
use cell::UnsafeCell;
|
||||
use sys::sync as ffi;
|
||||
|
||||
pub struct RWLock { inner: UnsafeCell<ffi::pthread_rwlock_t> }
|
||||
pub struct RWLock { inner: UnsafeCell<libc::pthread_rwlock_t> }
|
||||
|
||||
unsafe impl Send for RWLock {}
|
||||
unsafe impl Sync for RWLock {}
|
||||
|
||||
impl RWLock {
|
||||
pub const fn new() -> RWLock {
|
||||
RWLock { inner: UnsafeCell::new(ffi::PTHREAD_RWLOCK_INITIALIZER) }
|
||||
RWLock { inner: UnsafeCell::new(libc::PTHREAD_RWLOCK_INITIALIZER) }
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn read(&self) {
|
||||
let r = ffi::pthread_rwlock_rdlock(self.inner.get());
|
||||
let r = libc::pthread_rwlock_rdlock(self.inner.get());
|
||||
|
||||
// According to the pthread_rwlock_rdlock spec, this function **may**
|
||||
// fail with EDEADLK if a deadlock is detected. On the other hand
|
||||
|
@ -44,11 +43,11 @@ impl RWLock {
|
|||
}
|
||||
#[inline]
|
||||
pub unsafe fn try_read(&self) -> bool {
|
||||
ffi::pthread_rwlock_tryrdlock(self.inner.get()) == 0
|
||||
libc::pthread_rwlock_tryrdlock(self.inner.get()) == 0
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn write(&self) {
|
||||
let r = ffi::pthread_rwlock_wrlock(self.inner.get());
|
||||
let r = libc::pthread_rwlock_wrlock(self.inner.get());
|
||||
// see comments above for why we check for EDEADLK
|
||||
if r == libc::EDEADLK {
|
||||
panic!("rwlock write lock would result in deadlock");
|
||||
|
@ -58,21 +57,21 @@ impl RWLock {
|
|||
}
|
||||
#[inline]
|
||||
pub unsafe fn try_write(&self) -> bool {
|
||||
ffi::pthread_rwlock_trywrlock(self.inner.get()) == 0
|
||||
libc::pthread_rwlock_trywrlock(self.inner.get()) == 0
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn read_unlock(&self) {
|
||||
let r = ffi::pthread_rwlock_unlock(self.inner.get());
|
||||
let r = libc::pthread_rwlock_unlock(self.inner.get());
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub unsafe fn write_unlock(&self) { self.read_unlock() }
|
||||
#[inline]
|
||||
pub unsafe fn destroy(&self) {
|
||||
let r = ffi::pthread_rwlock_destroy(self.inner.get());
|
||||
let r = libc::pthread_rwlock_destroy(self.inner.get());
|
||||
// On DragonFly pthread_rwlock_destroy() returns EINVAL if called on a
|
||||
// rwlock that was just initialized with
|
||||
// ffi::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
|
||||
// libc::PTHREAD_RWLOCK_INITIALIZER. Once it is used (locked/unlocked)
|
||||
// or pthread_rwlock_init() is called, this behaviour no longer occurs.
|
||||
if cfg!(target_os = "dragonfly") {
|
||||
debug_assert!(r == 0 || r == libc::EINVAL);
|
||||
|
|
|
@ -43,11 +43,11 @@ mod imp {
|
|||
use sys_common::util::report_overflow;
|
||||
use mem;
|
||||
use ptr;
|
||||
use sys::c::{siginfo, sigaction, SIGBUS, SIG_DFL,
|
||||
SA_SIGINFO, SA_ONSTACK, sigaltstack,
|
||||
SIGSTKSZ, sighandler_t};
|
||||
use libc::{sigaction, SIGBUS, SIG_DFL,
|
||||
SA_SIGINFO, SA_ONSTACK, sigaltstack,
|
||||
SIGSTKSZ, sighandler_t};
|
||||
use libc;
|
||||
use libc::funcs::posix88::mman::{mmap, munmap};
|
||||
use libc::{mmap, munmap};
|
||||
use libc::{SIGSEGV, PROT_READ, PROT_WRITE, MAP_PRIVATE, MAP_ANON};
|
||||
use libc::MAP_FAILED;
|
||||
|
||||
|
@ -57,6 +57,22 @@ mod imp {
|
|||
// This is initialized in init() and only read from after
|
||||
static mut PAGE_SIZE: usize = 0;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void {
|
||||
#[repr(C)]
|
||||
struct siginfo_t {
|
||||
a: [libc::c_int; 3], // si_signo, si_code, si_errno,
|
||||
si_addr: *mut libc::c_void,
|
||||
}
|
||||
|
||||
(*(info as *const siginfo_t)).si_addr
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "linux", target_os = "android")))]
|
||||
unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> *mut libc::c_void {
|
||||
(*info).si_addr
|
||||
}
|
||||
|
||||
// Signal handler for the SIGSEGV and SIGBUS handlers. We've got guard pages
|
||||
// (unmapped pages) at the end of every thread's stack, so if a thread ends
|
||||
// up running into the guard page it'll trigger this handler. We want to
|
||||
|
@ -76,10 +92,10 @@ mod imp {
|
|||
// handler to work. For a more detailed explanation see the comments on
|
||||
// #26458.
|
||||
unsafe extern fn signal_handler(signum: libc::c_int,
|
||||
info: *mut siginfo,
|
||||
info: *mut libc::siginfo_t,
|
||||
_data: *mut libc::c_void) {
|
||||
let guard = thread_info::stack_guard().unwrap_or(0);
|
||||
let addr = (*info).si_addr as usize;
|
||||
let addr = siginfo_si_addr(info) as usize;
|
||||
|
||||
// If the faulting address is within the guard page, then we print a
|
||||
// message saying so.
|
||||
|
@ -126,7 +142,7 @@ mod imp {
|
|||
panic!("failed to allocate an alternative stack");
|
||||
}
|
||||
|
||||
let mut stack: sigaltstack = mem::zeroed();
|
||||
let mut stack: libc::stack_t = mem::zeroed();
|
||||
|
||||
stack.ss_sp = alt_stack;
|
||||
stack.ss_flags = 0;
|
||||
|
|
|
@ -1,374 +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.
|
||||
|
||||
#![allow(bad_style)]
|
||||
|
||||
use libc;
|
||||
|
||||
pub use self::os::{PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_RECURSIVE, pthread_mutex_t,
|
||||
pthread_mutexattr_t};
|
||||
pub use self::os::{PTHREAD_COND_INITIALIZER, pthread_cond_t};
|
||||
pub use self::os::{PTHREAD_RWLOCK_INITIALIZER, pthread_rwlock_t};
|
||||
|
||||
extern {
|
||||
// mutexes
|
||||
pub fn pthread_mutex_init(lock: *mut pthread_mutex_t, attr: *const pthread_mutexattr_t)
|
||||
-> libc::c_int;
|
||||
pub fn pthread_mutex_destroy(lock: *mut pthread_mutex_t) -> libc::c_int;
|
||||
pub fn pthread_mutex_lock(lock: *mut pthread_mutex_t) -> libc::c_int;
|
||||
pub fn pthread_mutex_trylock(lock: *mut pthread_mutex_t) -> libc::c_int;
|
||||
pub fn pthread_mutex_unlock(lock: *mut pthread_mutex_t) -> libc::c_int;
|
||||
|
||||
pub fn pthread_mutexattr_init(attr: *mut pthread_mutexattr_t) -> libc::c_int;
|
||||
pub fn pthread_mutexattr_destroy(attr: *mut pthread_mutexattr_t) -> libc::c_int;
|
||||
pub fn pthread_mutexattr_settype(attr: *mut pthread_mutexattr_t, _type: libc::c_int)
|
||||
-> libc::c_int;
|
||||
|
||||
// cvars
|
||||
pub fn pthread_cond_wait(cond: *mut pthread_cond_t,
|
||||
lock: *mut pthread_mutex_t) -> libc::c_int;
|
||||
#[cfg_attr(target_os = "nacl", link_name = "pthread_cond_timedwait_abs")]
|
||||
pub fn pthread_cond_timedwait(cond: *mut pthread_cond_t,
|
||||
lock: *mut pthread_mutex_t,
|
||||
abstime: *const libc::timespec) -> libc::c_int;
|
||||
pub fn pthread_cond_signal(cond: *mut pthread_cond_t) -> libc::c_int;
|
||||
pub fn pthread_cond_broadcast(cond: *mut pthread_cond_t) -> libc::c_int;
|
||||
pub fn pthread_cond_destroy(cond: *mut pthread_cond_t) -> libc::c_int;
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__gettimeofday50")]
|
||||
pub fn gettimeofday(tp: *mut libc::timeval,
|
||||
tz: *mut libc::c_void) -> libc::c_int;
|
||||
|
||||
// rwlocks
|
||||
pub fn pthread_rwlock_destroy(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
pub fn pthread_rwlock_rdlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
pub fn pthread_rwlock_tryrdlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
pub fn pthread_rwlock_wrlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
pub fn pthread_rwlock_trywrlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
pub fn pthread_rwlock_unlock(lock: *mut pthread_rwlock_t) -> libc::c_int;
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "openbsd"))]
|
||||
mod os {
|
||||
use libc;
|
||||
use ptr;
|
||||
|
||||
pub type pthread_mutex_t = *mut libc::c_void;
|
||||
pub type pthread_mutexattr_t = *mut libc::c_void;
|
||||
pub type pthread_cond_t = *mut libc::c_void;
|
||||
pub type pthread_rwlock_t = *mut libc::c_void;
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = ptr::null_mut();
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = ptr::null_mut();
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = ptr::null_mut();
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
const __PTHREAD_MUTEX_SIZE__: usize = 56;
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm"))]
|
||||
const __PTHREAD_MUTEX_SIZE__: usize = 40;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
const __PTHREAD_COND_SIZE__: usize = 40;
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm"))]
|
||||
const __PTHREAD_COND_SIZE__: usize = 24;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
const __PTHREAD_RWLOCK_SIZE__: usize = 192;
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm"))]
|
||||
const __PTHREAD_RWLOCK_SIZE__: usize = 124;
|
||||
|
||||
const _PTHREAD_MUTEX_SIG_INIT: libc::c_long = 0x32AAABA7;
|
||||
const _PTHREAD_COND_SIG_INIT: libc::c_long = 0x3CB0B1BB;
|
||||
const _PTHREAD_RWLOCK_SIG_INIT: libc::c_long = 0x2DA8B3B4;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
__sig: libc::c_long,
|
||||
__opaque: [u8; __PTHREAD_MUTEX_SIZE__],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutexattr_t {
|
||||
__sig: libc::c_long,
|
||||
// note, that this is 16 bytes just to be safe, the actual struct might be smaller.
|
||||
__opaque: [u8; 16],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
__sig: libc::c_long,
|
||||
__opaque: [u8; __PTHREAD_COND_SIZE__],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
__sig: libc::c_long,
|
||||
__opaque: [u8; __PTHREAD_RWLOCK_SIZE__],
|
||||
}
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
__sig: _PTHREAD_MUTEX_SIG_INIT,
|
||||
__opaque: [0; __PTHREAD_MUTEX_SIZE__],
|
||||
};
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
__sig: _PTHREAD_COND_SIG_INIT,
|
||||
__opaque: [0; __PTHREAD_COND_SIZE__],
|
||||
};
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
|
||||
__sig: _PTHREAD_RWLOCK_SIG_INIT,
|
||||
__opaque: [0; __PTHREAD_RWLOCK_SIZE__],
|
||||
};
|
||||
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
// minus 8 because we have an 'align' field
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: usize = 40 - 8;
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: usize = 24 - 8;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
const __SIZEOF_PTHREAD_MUTEX_T: usize = 48 - 8;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "aarch64",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_COND_T: usize = 48 - 8;
|
||||
|
||||
#[cfg(any(target_arch = "x86_64",
|
||||
target_arch = "aarch64"))]
|
||||
const __SIZEOF_PTHREAD_RWLOCK_T: usize = 56 - 8;
|
||||
|
||||
#[cfg(any(target_arch = "x86",
|
||||
target_arch = "arm",
|
||||
target_arch = "mips",
|
||||
target_arch = "mipsel",
|
||||
target_arch = "powerpc"))]
|
||||
const __SIZEOF_PTHREAD_RWLOCK_T: usize = 32 - 8;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
__align: libc::c_longlong,
|
||||
size: [u8; __SIZEOF_PTHREAD_MUTEX_T],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutexattr_t {
|
||||
__align: libc::c_longlong,
|
||||
// note, that this is 16 bytes just to be safe, the actual struct might be smaller.
|
||||
size: [u8; 16],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
__align: libc::c_longlong,
|
||||
size: [u8; __SIZEOF_PTHREAD_COND_T],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
__align: libc::c_longlong,
|
||||
size: [u8; __SIZEOF_PTHREAD_RWLOCK_T],
|
||||
}
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
__align: 0,
|
||||
size: [0; __SIZEOF_PTHREAD_MUTEX_T],
|
||||
};
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
__align: 0,
|
||||
size: [0; __SIZEOF_PTHREAD_COND_T],
|
||||
};
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
|
||||
__align: 0,
|
||||
size: [0; __SIZEOF_PTHREAD_RWLOCK_T],
|
||||
};
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
|
||||
}
|
||||
#[cfg(target_os = "android")]
|
||||
mod os {
|
||||
use libc;
|
||||
use ptr;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t { value: libc::c_int }
|
||||
pub type pthread_mutexattr_t = libc::c_long;
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t { value: libc::c_int }
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
lock: pthread_mutex_t,
|
||||
cond: pthread_cond_t,
|
||||
numLocks: libc::c_int,
|
||||
writerThreadId: libc::c_int,
|
||||
pendingReaders: libc::c_int,
|
||||
pendingWriters: libc::c_int,
|
||||
reserved: [*mut libc::c_void; 4],
|
||||
}
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
value: 0,
|
||||
};
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
value: 0,
|
||||
};
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
|
||||
lock: PTHREAD_MUTEX_INITIALIZER,
|
||||
cond: PTHREAD_COND_INITIALIZER,
|
||||
numLocks: 0,
|
||||
writerThreadId: 0,
|
||||
pendingReaders: 0,
|
||||
pendingWriters: 0,
|
||||
reserved: [ptr::null_mut(); 4],
|
||||
};
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
|
||||
}
|
||||
|
||||
#[cfg(target_os = "netbsd")]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
// size of the type minus width of the magic and alignment field
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const __PTHREAD_MUTEX_SIZE__: usize = 48 - 4 - 8;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const __PTHREAD_MUTEXATTR_SIZE__: usize = 16 - 8; // no magic field
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const __PTHREAD_COND_SIZE__: usize = 40 - 4 - 8;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const __PTHREAD_RWLOCK_SIZE__: usize = 64 - 4 - 8;
|
||||
|
||||
const _PTHREAD_MUTEX_MAGIC_INIT: libc::c_uint = 0x33330003;
|
||||
const _PTHREAD_COND_MAGIC_INIT: libc::c_uint = 0x55550005;
|
||||
const _PTHREAD_RWLOCK_MAGIC_INIT: libc::c_uint = 0x99990009;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
__magic: libc::c_uint,
|
||||
__opaque: [u8; __PTHREAD_MUTEX_SIZE__],
|
||||
__align: libc::c_longlong,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutexattr_t {
|
||||
__opaque: [u8; __PTHREAD_MUTEXATTR_SIZE__],
|
||||
__align: libc::c_longlong,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
__magic: libc::c_uint,
|
||||
__opaque: [u8; __PTHREAD_COND_SIZE__],
|
||||
__align: libc::c_longlong,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
__magic: libc::c_uint,
|
||||
__opaque: [u8; __PTHREAD_RWLOCK_SIZE__],
|
||||
__align: libc::c_longlong,
|
||||
}
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
__magic: _PTHREAD_MUTEX_MAGIC_INIT,
|
||||
__opaque: [0; __PTHREAD_MUTEX_SIZE__],
|
||||
__align: 0,
|
||||
};
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
__magic: _PTHREAD_COND_MAGIC_INIT,
|
||||
__opaque: [0; __PTHREAD_COND_SIZE__],
|
||||
__align: 0,
|
||||
};
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
|
||||
__magic: _PTHREAD_RWLOCK_MAGIC_INIT,
|
||||
__opaque: [0; __PTHREAD_RWLOCK_SIZE__],
|
||||
__align: 0,
|
||||
};
|
||||
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 2;
|
||||
}
|
||||
#[cfg(target_os = "nacl")]
|
||||
mod os {
|
||||
use libc;
|
||||
|
||||
pub type __nc_basic_thread_data = libc::c_void;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutex_t {
|
||||
mutex_state: libc::c_int,
|
||||
mutex_type: libc::c_int,
|
||||
owner_thread_id: *mut __nc_basic_thread_data,
|
||||
recursion_counter: libc::uint32_t,
|
||||
_unused: libc::c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_mutexattr_t {
|
||||
kind: libc::c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_cond_t {
|
||||
sequence_number: libc::c_int,
|
||||
_unused: libc::c_int,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct pthread_rwlock_t {
|
||||
mutex: pthread_mutex_t,
|
||||
reader_count: libc::c_int,
|
||||
writers_waiting: libc::c_int,
|
||||
writer_thread_id: *mut __nc_basic_thread_data,
|
||||
read_possible: pthread_cond_t,
|
||||
write_possible: pthread_cond_t,
|
||||
}
|
||||
|
||||
const NC_INVALID_HANDLE: libc::c_int = -1;
|
||||
const NACL_PTHREAD_ILLEGAL_THREAD_ID: *mut __nc_basic_thread_data
|
||||
= 0 as *mut __nc_basic_thread_data;
|
||||
|
||||
pub const PTHREAD_MUTEX_INITIALIZER: pthread_mutex_t = pthread_mutex_t {
|
||||
mutex_state: 0,
|
||||
mutex_type: 0,
|
||||
owner_thread_id: NACL_PTHREAD_ILLEGAL_THREAD_ID,
|
||||
recursion_counter: 0,
|
||||
_unused: NC_INVALID_HANDLE,
|
||||
};
|
||||
pub const PTHREAD_COND_INITIALIZER: pthread_cond_t = pthread_cond_t {
|
||||
sequence_number: 0,
|
||||
_unused: NC_INVALID_HANDLE,
|
||||
};
|
||||
pub const PTHREAD_RWLOCK_INITIALIZER: pthread_rwlock_t = pthread_rwlock_t {
|
||||
mutex: PTHREAD_MUTEX_INITIALIZER,
|
||||
reader_count: 0,
|
||||
writers_waiting: 0,
|
||||
writer_thread_id: NACL_PTHREAD_ILLEGAL_THREAD_ID,
|
||||
read_possible: PTHREAD_COND_INITIALIZER,
|
||||
write_possible: PTHREAD_COND_INITIALIZER,
|
||||
};
|
||||
pub const PTHREAD_MUTEX_RECURSIVE: libc::c_int = 1;
|
||||
}
|
|
@ -17,7 +17,7 @@ use cmp;
|
|||
#[cfg(not(target_env = "newlib"))]
|
||||
use ffi::CString;
|
||||
use io;
|
||||
use libc::consts::os::posix01::PTHREAD_STACK_MIN;
|
||||
use libc::PTHREAD_STACK_MIN;
|
||||
use libc;
|
||||
use mem;
|
||||
use ptr;
|
||||
|
@ -41,10 +41,11 @@ impl Thread {
|
|||
let p = box p;
|
||||
let mut native: libc::pthread_t = mem::zeroed();
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
|
||||
|
||||
let stack_size = cmp::max(stack, min_stack_size(&attr));
|
||||
match pthread_attr_setstacksize(&mut attr, stack_size as libc::size_t) {
|
||||
match libc::pthread_attr_setstacksize(&mut attr,
|
||||
stack_size as libc::size_t) {
|
||||
0 => {}
|
||||
n => {
|
||||
assert_eq!(n, libc::EINVAL);
|
||||
|
@ -56,13 +57,14 @@ impl Thread {
|
|||
let stack_size = (stack_size + page_size - 1) &
|
||||
(-(page_size as isize - 1) as usize - 1);
|
||||
let stack_size = stack_size as libc::size_t;
|
||||
assert_eq!(pthread_attr_setstacksize(&mut attr, stack_size), 0);
|
||||
assert_eq!(libc::pthread_attr_setstacksize(&mut attr,
|
||||
stack_size), 0);
|
||||
}
|
||||
};
|
||||
|
||||
let ret = pthread_create(&mut native, &attr, thread_start,
|
||||
&*p as *const _ as *mut _);
|
||||
assert_eq!(pthread_attr_destroy(&mut attr), 0);
|
||||
let ret = libc::pthread_create(&mut native, &attr, thread_start,
|
||||
&*p as *const _ as *mut _);
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
|
||||
return if ret != 0 {
|
||||
Err(io::Error::from_raw_os_error(ret))
|
||||
|
@ -78,25 +80,20 @@ impl Thread {
|
|||
}
|
||||
|
||||
pub fn yield_now() {
|
||||
let ret = unsafe { sched_yield() };
|
||||
let ret = unsafe { libc::sched_yield() };
|
||||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub fn set_name(name: &str) {
|
||||
// pthread wrapper only appeared in glibc 2.12, so we use syscall
|
||||
// directly.
|
||||
extern {
|
||||
fn prctl(option: libc::c_int, arg2: libc::c_ulong,
|
||||
arg3: libc::c_ulong, arg4: libc::c_ulong,
|
||||
arg5: libc::c_ulong) -> libc::c_int;
|
||||
}
|
||||
const PR_SET_NAME: libc::c_int = 15;
|
||||
let cname = CString::new(name).unwrap_or_else(|_| {
|
||||
panic!("thread name may not contain interior null bytes")
|
||||
});
|
||||
// pthread wrapper only appeared in glibc 2.12, so we use syscall
|
||||
// directly.
|
||||
unsafe {
|
||||
prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0);
|
||||
libc::prctl(PR_SET_NAME, cname.as_ptr() as libc::c_ulong, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,39 +102,27 @@ impl Thread {
|
|||
target_os = "bitrig",
|
||||
target_os = "openbsd"))]
|
||||
pub fn set_name(name: &str) {
|
||||
extern {
|
||||
fn pthread_set_name_np(tid: libc::pthread_t,
|
||||
name: *const libc::c_char);
|
||||
}
|
||||
let cname = CString::new(name).unwrap();
|
||||
unsafe {
|
||||
pthread_set_name_np(pthread_self(), cname.as_ptr());
|
||||
libc::pthread_set_name_np(libc::pthread_self(), cname.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||
pub fn set_name(name: &str) {
|
||||
extern {
|
||||
fn pthread_setname_np(name: *const libc::c_char) -> libc::c_int;
|
||||
}
|
||||
let cname = CString::new(name).unwrap();
|
||||
unsafe {
|
||||
pthread_setname_np(cname.as_ptr());
|
||||
libc::pthread_setname_np(cname.as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "netbsd")]
|
||||
pub fn set_name(name: &str) {
|
||||
extern {
|
||||
fn pthread_setname_np(thread: libc::pthread_t,
|
||||
name: *const libc::c_char,
|
||||
arg: *mut libc::c_void) -> libc::c_int;
|
||||
}
|
||||
let cname = CString::new(&b"%s"[..]).unwrap();
|
||||
let carg = CString::new(name).unwrap();
|
||||
unsafe {
|
||||
pthread_setname_np(pthread_self(), cname.as_ptr(),
|
||||
carg.as_ptr() as *mut libc::c_void);
|
||||
libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(),
|
||||
carg.as_ptr() as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
#[cfg(target_env = "newlib")]
|
||||
|
@ -162,7 +147,7 @@ impl Thread {
|
|||
|
||||
pub fn join(self) {
|
||||
unsafe {
|
||||
let ret = pthread_join(self.id, ptr::null_mut());
|
||||
let ret = libc::pthread_join(self.id, ptr::null_mut());
|
||||
mem::forget(self);
|
||||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
|
@ -171,7 +156,7 @@ impl Thread {
|
|||
|
||||
impl Drop for Thread {
|
||||
fn drop(&mut self) {
|
||||
let ret = unsafe { pthread_detach(self.id) };
|
||||
let ret = unsafe { libc::pthread_detach(self.id) };
|
||||
debug_assert_eq!(ret, 0);
|
||||
}
|
||||
}
|
||||
|
@ -197,15 +182,10 @@ pub mod guard {
|
|||
use prelude::v1::*;
|
||||
|
||||
use libc::{self, pthread_t};
|
||||
use libc::funcs::posix88::mman::mmap;
|
||||
use libc::consts::os::posix88::{PROT_NONE,
|
||||
MAP_PRIVATE,
|
||||
MAP_ANON,
|
||||
MAP_FAILED,
|
||||
MAP_FIXED};
|
||||
use libc::mmap;
|
||||
use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
|
||||
use mem;
|
||||
use ptr;
|
||||
use super::{pthread_self, pthread_attr_destroy};
|
||||
use sys::os;
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
|
@ -217,19 +197,17 @@ pub mod guard {
|
|||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
|
||||
unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
|
||||
use super::pthread_attr_init;
|
||||
|
||||
let mut ret = None;
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||
if pthread_getattr_np(pthread_self(), &mut attr) == 0 {
|
||||
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
|
||||
if libc::pthread_getattr_np(libc::pthread_self(), &mut attr) == 0 {
|
||||
let mut stackaddr = ptr::null_mut();
|
||||
let mut stacksize = 0;
|
||||
assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr,
|
||||
&mut stacksize), 0);
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
||||
&mut stacksize), 0);
|
||||
ret = Some(stackaddr);
|
||||
}
|
||||
assert_eq!(pthread_attr_destroy(&mut attr), 0);
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
ret
|
||||
}
|
||||
|
||||
|
@ -273,33 +251,18 @@ pub mod guard {
|
|||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub unsafe fn current() -> Option<usize> {
|
||||
extern {
|
||||
fn pthread_get_stackaddr_np(thread: pthread_t) -> *mut libc::c_void;
|
||||
fn pthread_get_stacksize_np(thread: pthread_t) -> libc::size_t;
|
||||
}
|
||||
Some((pthread_get_stackaddr_np(pthread_self()) as libc::size_t -
|
||||
pthread_get_stacksize_np(pthread_self())) as usize)
|
||||
Some((libc::pthread_get_stackaddr_np(libc::pthread_self()) as libc::size_t -
|
||||
libc::pthread_get_stacksize_np(libc::pthread_self())) as usize)
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
|
||||
pub unsafe fn current() -> Option<usize> {
|
||||
#[repr(C)]
|
||||
struct stack_t {
|
||||
ss_sp: *mut libc::c_void,
|
||||
ss_size: libc::size_t,
|
||||
ss_flags: libc::c_int,
|
||||
}
|
||||
extern {
|
||||
fn pthread_main_np() -> libc::c_uint;
|
||||
fn pthread_stackseg_np(thread: pthread_t,
|
||||
sinfo: *mut stack_t) -> libc::c_uint;
|
||||
}
|
||||
|
||||
let mut current_stack: stack_t = mem::zeroed();
|
||||
assert_eq!(pthread_stackseg_np(pthread_self(), &mut current_stack), 0);
|
||||
let mut current_stack: libc::stack_t = mem::zeroed();
|
||||
assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
|
||||
&mut current_stack), 0);
|
||||
|
||||
let extra = if cfg!(target_os = "bitrig") {3} else {1} * os::page_size();
|
||||
Some(if pthread_main_np() == 1 {
|
||||
Some(if libc::pthread_main_np() == 1 {
|
||||
// main thread
|
||||
current_stack.ss_sp as usize - current_stack.ss_size as usize + extra
|
||||
} else {
|
||||
|
@ -310,20 +273,19 @@ pub mod guard {
|
|||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
|
||||
pub unsafe fn current() -> Option<usize> {
|
||||
use super::pthread_attr_init;
|
||||
|
||||
let mut ret = None;
|
||||
let mut attr: libc::pthread_attr_t = mem::zeroed();
|
||||
assert_eq!(pthread_attr_init(&mut attr), 0);
|
||||
if pthread_getattr_np(pthread_self(), &mut attr) == 0 {
|
||||
assert_eq!(libc::pthread_attr_init(&mut attr), 0);
|
||||
if libc::pthread_getattr_np(libc::pthread_self(), &mut attr) == 0 {
|
||||
let mut guardsize = 0;
|
||||
assert_eq!(pthread_attr_getguardsize(&attr, &mut guardsize), 0);
|
||||
assert_eq!(libc::pthread_attr_getguardsize(&attr, &mut guardsize), 0);
|
||||
if guardsize == 0 {
|
||||
panic!("there is no guard page");
|
||||
}
|
||||
let mut stackaddr = ptr::null_mut();
|
||||
let mut size = 0;
|
||||
assert_eq!(pthread_attr_getstack(&attr, &mut stackaddr, &mut size), 0);
|
||||
assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
|
||||
&mut size), 0);
|
||||
|
||||
ret = if cfg!(target_os = "netbsd") {
|
||||
Some(stackaddr as usize)
|
||||
|
@ -331,20 +293,9 @@ pub mod guard {
|
|||
Some(stackaddr as usize + guardsize as usize)
|
||||
};
|
||||
}
|
||||
assert_eq!(pthread_attr_destroy(&mut attr), 0);
|
||||
assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
|
||||
ret
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android", target_os = "netbsd"))]
|
||||
extern {
|
||||
fn pthread_getattr_np(native: libc::pthread_t,
|
||||
attr: *mut libc::pthread_attr_t) -> libc::c_int;
|
||||
fn pthread_attr_getguardsize(attr: *const libc::pthread_attr_t,
|
||||
guardsize: *mut libc::size_t) -> libc::c_int;
|
||||
fn pthread_attr_getstack(attr: *const libc::pthread_attr_t,
|
||||
stackaddr: *mut *mut libc::c_void,
|
||||
stacksize: *mut libc::size_t) -> libc::c_int;
|
||||
}
|
||||
}
|
||||
|
||||
// glibc >= 2.15 has a __pthread_get_minstack() function that returns
|
||||
|
@ -394,21 +345,3 @@ fn min_stack_size(attr: *const libc::pthread_attr_t) -> usize {
|
|||
fn min_stack_size(_: *const libc::pthread_attr_t) -> usize {
|
||||
PTHREAD_STACK_MIN as usize
|
||||
}
|
||||
|
||||
extern {
|
||||
fn pthread_self() -> libc::pthread_t;
|
||||
fn pthread_create(native: *mut libc::pthread_t,
|
||||
attr: *const libc::pthread_attr_t,
|
||||
f: extern fn(*mut libc::c_void) -> *mut libc::c_void,
|
||||
value: *mut libc::c_void) -> libc::c_int;
|
||||
fn pthread_join(native: libc::pthread_t,
|
||||
value: *mut *mut libc::c_void) -> libc::c_int;
|
||||
fn pthread_attr_init(attr: *mut libc::pthread_attr_t) -> libc::c_int;
|
||||
fn pthread_attr_destroy(attr: *mut libc::pthread_attr_t) -> libc::c_int;
|
||||
fn pthread_attr_setstacksize(attr: *mut libc::pthread_attr_t,
|
||||
stack_size: libc::size_t) -> libc::c_int;
|
||||
fn pthread_attr_setdetachstate(attr: *mut libc::pthread_attr_t,
|
||||
state: libc::c_int) -> libc::c_int;
|
||||
fn pthread_detach(thread: libc::pthread_t) -> libc::c_int;
|
||||
fn sched_yield() -> libc::c_int;
|
||||
}
|
||||
|
|
|
@ -8,62 +8,33 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(dead_code)] // sys isn't exported yet
|
||||
#![allow(dead_code)] // not used on all platforms
|
||||
|
||||
use libc::c_int;
|
||||
use mem;
|
||||
use libc;
|
||||
|
||||
pub type Key = pthread_key_t;
|
||||
pub type Key = libc::pthread_key_t;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
|
||||
let mut key = 0;
|
||||
assert_eq!(pthread_key_create(&mut key, dtor), 0);
|
||||
assert_eq!(libc::pthread_key_create(&mut key, mem::transmute(dtor)), 0);
|
||||
key
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn set(key: Key, value: *mut u8) {
|
||||
let r = pthread_setspecific(key, value);
|
||||
let r = libc::pthread_setspecific(key, value as *mut _);
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn get(key: Key) -> *mut u8 {
|
||||
pthread_getspecific(key)
|
||||
libc::pthread_getspecific(key) as *mut u8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn destroy(key: Key) {
|
||||
let r = pthread_key_delete(key);
|
||||
let r = libc::pthread_key_delete(key);
|
||||
debug_assert_eq!(r, 0);
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos",
|
||||
target_os = "ios"))]
|
||||
type pthread_key_t = ::libc::c_ulong;
|
||||
|
||||
#[cfg(any(target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "nacl"))]
|
||||
type pthread_key_t = ::libc::c_int;
|
||||
|
||||
#[cfg(not(any(target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "freebsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "bitrig",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "nacl")))]
|
||||
type pthread_key_t = ::libc::c_uint;
|
||||
|
||||
extern {
|
||||
fn pthread_key_create(key: *mut pthread_key_t,
|
||||
dtor: Option<unsafe extern fn(*mut u8)>) -> c_int;
|
||||
fn pthread_key_delete(key: pthread_key_t) -> c_int;
|
||||
fn pthread_getspecific(key: pthread_key_t) -> *mut u8;
|
||||
fn pthread_setspecific(key: pthread_key_t, value: *mut u8) -> c_int;
|
||||
}
|
||||
|
|
|
@ -24,15 +24,10 @@ mod inner {
|
|||
t: u64
|
||||
}
|
||||
|
||||
extern {
|
||||
pub fn mach_absolute_time() -> u64;
|
||||
pub fn mach_timebase_info(info: *mut libc::mach_timebase_info) -> libc::c_int;
|
||||
}
|
||||
|
||||
impl SteadyTime {
|
||||
pub fn now() -> SteadyTime {
|
||||
SteadyTime {
|
||||
t: unsafe { mach_absolute_time() },
|
||||
t: unsafe { libc::mach_absolute_time() },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +41,7 @@ mod inner {
|
|||
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
mach_timebase_info(&mut INFO);
|
||||
libc::mach_timebase_info(&mut INFO);
|
||||
});
|
||||
&INFO
|
||||
}
|
||||
|
@ -87,11 +82,6 @@ mod inner {
|
|||
#[link(name = "rt")]
|
||||
extern {}
|
||||
|
||||
extern {
|
||||
#[cfg_attr(target_os = "netbsd", link_name = "__clock_gettime50")]
|
||||
fn clock_gettime(clk_id: libc::c_int, tp: *mut libc::timespec) -> libc::c_int;
|
||||
}
|
||||
|
||||
impl SteadyTime {
|
||||
pub fn now() -> SteadyTime {
|
||||
let mut t = SteadyTime {
|
||||
|
@ -101,7 +91,8 @@ mod inner {
|
|||
}
|
||||
};
|
||||
unsafe {
|
||||
assert_eq!(0, clock_gettime(libc::CLOCK_MONOTONIC, &mut t.t));
|
||||
assert_eq!(0, libc::clock_gettime(libc::CLOCK_MONOTONIC,
|
||||
&mut t.t));
|
||||
}
|
||||
t
|
||||
}
|
||||
|
|
|
@ -27,12 +27,13 @@
|
|||
use io::prelude::*;
|
||||
|
||||
use dynamic_lib::DynamicLibrary;
|
||||
use intrinsics;
|
||||
use io;
|
||||
use libc;
|
||||
use libc::c_void;
|
||||
use mem;
|
||||
use path::Path;
|
||||
use ptr;
|
||||
use sync::StaticMutex;
|
||||
use sys::c;
|
||||
|
||||
macro_rules! sym{ ($lib:expr, $e:expr, $t:ident) => (unsafe {
|
||||
let lib = $lib;
|
||||
|
@ -50,264 +51,50 @@ mod printing;
|
|||
#[path = "printing/gnu.rs"]
|
||||
mod printing;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
extern "system" {
|
||||
fn GetCurrentProcess() -> libc::HANDLE;
|
||||
fn GetCurrentThread() -> libc::HANDLE;
|
||||
fn RtlCaptureContext(ctx: *mut arch::CONTEXT);
|
||||
}
|
||||
|
||||
type SymFromAddrFn =
|
||||
extern "system" fn(libc::HANDLE, u64, *mut u64,
|
||||
*mut SYMBOL_INFO) -> libc::BOOL;
|
||||
extern "system" fn(c::HANDLE, u64, *mut u64,
|
||||
*mut c::SYMBOL_INFO) -> c::BOOL;
|
||||
type SymGetLineFromAddr64Fn =
|
||||
extern "system" fn(libc::HANDLE, u64, *mut u32,
|
||||
*mut IMAGEHLP_LINE64) -> libc::BOOL;
|
||||
extern "system" fn(c::HANDLE, u64, *mut u32,
|
||||
*mut c::IMAGEHLP_LINE64) -> c::BOOL;
|
||||
type SymInitializeFn =
|
||||
extern "system" fn(libc::HANDLE, *mut libc::c_void,
|
||||
libc::BOOL) -> libc::BOOL;
|
||||
extern "system" fn(c::HANDLE, *mut c_void,
|
||||
c::BOOL) -> c::BOOL;
|
||||
type SymCleanupFn =
|
||||
extern "system" fn(libc::HANDLE) -> libc::BOOL;
|
||||
extern "system" fn(c::HANDLE) -> c::BOOL;
|
||||
|
||||
type StackWalk64Fn =
|
||||
extern "system" fn(libc::DWORD, libc::HANDLE, libc::HANDLE,
|
||||
*mut STACKFRAME64, *mut arch::CONTEXT,
|
||||
*mut libc::c_void, *mut libc::c_void,
|
||||
*mut libc::c_void, *mut libc::c_void) -> libc::BOOL;
|
||||
|
||||
const MAX_SYM_NAME: usize = 2000;
|
||||
const IMAGE_FILE_MACHINE_I386: libc::DWORD = 0x014c;
|
||||
const IMAGE_FILE_MACHINE_IA64: libc::DWORD = 0x0200;
|
||||
const IMAGE_FILE_MACHINE_AMD64: libc::DWORD = 0x8664;
|
||||
|
||||
#[repr(C)]
|
||||
struct SYMBOL_INFO {
|
||||
SizeOfStruct: libc::c_ulong,
|
||||
TypeIndex: libc::c_ulong,
|
||||
Reserved: [u64; 2],
|
||||
Index: libc::c_ulong,
|
||||
Size: libc::c_ulong,
|
||||
ModBase: u64,
|
||||
Flags: libc::c_ulong,
|
||||
Value: u64,
|
||||
Address: u64,
|
||||
Register: libc::c_ulong,
|
||||
Scope: libc::c_ulong,
|
||||
Tag: libc::c_ulong,
|
||||
NameLen: libc::c_ulong,
|
||||
MaxNameLen: libc::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.
|
||||
Name: [libc::c_char; MAX_SYM_NAME],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
struct IMAGEHLP_LINE64 {
|
||||
SizeOfStruct: u32,
|
||||
Key: *const libc::c_void,
|
||||
LineNumber: u32,
|
||||
Filename: *const libc::c_char,
|
||||
Address: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
enum ADDRESS_MODE {
|
||||
AddrMode1616,
|
||||
AddrMode1632,
|
||||
AddrModeReal,
|
||||
AddrModeFlat,
|
||||
}
|
||||
|
||||
struct ADDRESS64 {
|
||||
Offset: u64,
|
||||
Segment: u16,
|
||||
Mode: ADDRESS_MODE,
|
||||
}
|
||||
|
||||
pub struct STACKFRAME64 {
|
||||
AddrPC: ADDRESS64,
|
||||
AddrReturn: ADDRESS64,
|
||||
AddrFrame: ADDRESS64,
|
||||
AddrStack: ADDRESS64,
|
||||
AddrBStore: ADDRESS64,
|
||||
FuncTableEntry: *mut libc::c_void,
|
||||
Params: [u64; 4],
|
||||
Far: libc::BOOL,
|
||||
Virtual: libc::BOOL,
|
||||
Reserved: [u64; 3],
|
||||
KdHelp: KDHELP64,
|
||||
}
|
||||
|
||||
struct KDHELP64 {
|
||||
Thread: u64,
|
||||
ThCallbackStack: libc::DWORD,
|
||||
ThCallbackBStore: libc::DWORD,
|
||||
NextCallback: libc::DWORD,
|
||||
FramePointer: libc::DWORD,
|
||||
KiCallUserMode: u64,
|
||||
KeUserCallbackDispatcher: u64,
|
||||
SystemRangeStart: u64,
|
||||
KiUserExceptionDispatcher: u64,
|
||||
StackBase: u64,
|
||||
StackLimit: u64,
|
||||
Reserved: [u64; 5],
|
||||
}
|
||||
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;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
mod arch {
|
||||
use libc;
|
||||
|
||||
const MAXIMUM_SUPPORTED_EXTENSION: usize = 512;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CONTEXT {
|
||||
ContextFlags: libc::DWORD,
|
||||
Dr0: libc::DWORD,
|
||||
Dr1: libc::DWORD,
|
||||
Dr2: libc::DWORD,
|
||||
Dr3: libc::DWORD,
|
||||
Dr6: libc::DWORD,
|
||||
Dr7: libc::DWORD,
|
||||
FloatSave: FLOATING_SAVE_AREA,
|
||||
SegGs: libc::DWORD,
|
||||
SegFs: libc::DWORD,
|
||||
SegEs: libc::DWORD,
|
||||
SegDs: libc::DWORD,
|
||||
Edi: libc::DWORD,
|
||||
Esi: libc::DWORD,
|
||||
Ebx: libc::DWORD,
|
||||
Edx: libc::DWORD,
|
||||
Ecx: libc::DWORD,
|
||||
Eax: libc::DWORD,
|
||||
Ebp: libc::DWORD,
|
||||
Eip: libc::DWORD,
|
||||
SegCs: libc::DWORD,
|
||||
EFlags: libc::DWORD,
|
||||
Esp: libc::DWORD,
|
||||
SegSs: libc::DWORD,
|
||||
ExtendedRegisters: [u8; MAXIMUM_SUPPORTED_EXTENSION],
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FLOATING_SAVE_AREA {
|
||||
ControlWord: libc::DWORD,
|
||||
StatusWord: libc::DWORD,
|
||||
TagWord: libc::DWORD,
|
||||
ErrorOffset: libc::DWORD,
|
||||
ErrorSelector: libc::DWORD,
|
||||
DataOffset: libc::DWORD,
|
||||
DataSelector: libc::DWORD,
|
||||
RegisterArea: [u8; 80],
|
||||
Cr0NpxState: libc::DWORD,
|
||||
}
|
||||
|
||||
pub fn init_frame(frame: &mut super::STACKFRAME64,
|
||||
ctx: &CONTEXT) -> libc::DWORD {
|
||||
frame.AddrPC.Offset = ctx.Eip as u64;
|
||||
frame.AddrPC.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrStack.Offset = ctx.Esp as u64;
|
||||
frame.AddrStack.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrFrame.Offset = ctx.Ebp as u64;
|
||||
frame.AddrFrame.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
super::IMAGE_FILE_MACHINE_I386
|
||||
}
|
||||
pub fn init_frame(frame: &mut c::STACKFRAME64,
|
||||
ctx: &c::CONTEXT) -> c::DWORD {
|
||||
frame.AddrPC.Offset = ctx.Eip as u64;
|
||||
frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrStack.Offset = ctx.Esp as u64;
|
||||
frame.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrFrame.Offset = ctx.Ebp as u64;
|
||||
frame.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
c::IMAGE_FILE_MACHINE_I386
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod arch {
|
||||
#![allow(deprecated)]
|
||||
|
||||
use libc::{c_longlong, c_ulonglong};
|
||||
use libc::types::os::arch::extra::{WORD, DWORD, DWORDLONG};
|
||||
use simd;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct CONTEXT {
|
||||
_align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
|
||||
P1Home: DWORDLONG,
|
||||
P2Home: DWORDLONG,
|
||||
P3Home: DWORDLONG,
|
||||
P4Home: DWORDLONG,
|
||||
P5Home: DWORDLONG,
|
||||
P6Home: DWORDLONG,
|
||||
|
||||
ContextFlags: DWORD,
|
||||
MxCsr: DWORD,
|
||||
|
||||
SegCs: WORD,
|
||||
SegDs: WORD,
|
||||
SegEs: WORD,
|
||||
SegFs: WORD,
|
||||
SegGs: WORD,
|
||||
SegSs: WORD,
|
||||
EFlags: DWORD,
|
||||
|
||||
Dr0: DWORDLONG,
|
||||
Dr1: DWORDLONG,
|
||||
Dr2: DWORDLONG,
|
||||
Dr3: DWORDLONG,
|
||||
Dr6: DWORDLONG,
|
||||
Dr7: DWORDLONG,
|
||||
|
||||
Rax: DWORDLONG,
|
||||
Rcx: DWORDLONG,
|
||||
Rdx: DWORDLONG,
|
||||
Rbx: DWORDLONG,
|
||||
Rsp: DWORDLONG,
|
||||
Rbp: DWORDLONG,
|
||||
Rsi: DWORDLONG,
|
||||
Rdi: DWORDLONG,
|
||||
R8: DWORDLONG,
|
||||
R9: DWORDLONG,
|
||||
R10: DWORDLONG,
|
||||
R11: DWORDLONG,
|
||||
R12: DWORDLONG,
|
||||
R13: DWORDLONG,
|
||||
R14: DWORDLONG,
|
||||
R15: DWORDLONG,
|
||||
|
||||
Rip: DWORDLONG,
|
||||
|
||||
FltSave: FLOATING_SAVE_AREA,
|
||||
|
||||
VectorRegister: [M128A; 26],
|
||||
VectorControl: DWORDLONG,
|
||||
|
||||
DebugControl: DWORDLONG,
|
||||
LastBranchToRip: DWORDLONG,
|
||||
LastBranchFromRip: DWORDLONG,
|
||||
LastExceptionToRip: DWORDLONG,
|
||||
LastExceptionFromRip: DWORDLONG,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct M128A {
|
||||
_align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
|
||||
Low: c_ulonglong,
|
||||
High: c_longlong
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct FLOATING_SAVE_AREA {
|
||||
_align_hack: [simd::u64x2; 0], // FIXME align on 16-byte
|
||||
_Dummy: [u8; 512] // FIXME: Fill this out
|
||||
}
|
||||
|
||||
pub fn init_frame(frame: &mut super::STACKFRAME64,
|
||||
ctx: &CONTEXT) -> DWORD {
|
||||
frame.AddrPC.Offset = ctx.Rip as u64;
|
||||
frame.AddrPC.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrStack.Offset = ctx.Rsp as u64;
|
||||
frame.AddrStack.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrFrame.Offset = ctx.Rbp as u64;
|
||||
frame.AddrFrame.Mode = super::ADDRESS_MODE::AddrModeFlat;
|
||||
super::IMAGE_FILE_MACHINE_AMD64
|
||||
}
|
||||
pub fn init_frame(frame: &mut c::STACKFRAME64,
|
||||
ctx: &c::CONTEXT) -> c::DWORD {
|
||||
frame.AddrPC.Offset = ctx.Rip as u64;
|
||||
frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrStack.Offset = ctx.Rsp as u64;
|
||||
frame.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
frame.AddrFrame.Offset = ctx.Rbp as u64;
|
||||
frame.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
|
||||
c::IMAGE_FILE_MACHINE_AMD64
|
||||
}
|
||||
|
||||
struct Cleanup {
|
||||
handle: libc::HANDLE,
|
||||
handle: c::HANDLE,
|
||||
SymCleanup: SymCleanupFn,
|
||||
}
|
||||
|
||||
|
@ -335,16 +122,16 @@ pub fn write(w: &mut Write) -> io::Result<()> {
|
|||
let StackWalk64 = sym!(&dbghelp, "StackWalk64", StackWalk64Fn);
|
||||
|
||||
// Allocate necessary structures for doing the stack walk
|
||||
let process = unsafe { GetCurrentProcess() };
|
||||
let thread = unsafe { GetCurrentThread() };
|
||||
let mut context: arch::CONTEXT = unsafe { intrinsics::init() };
|
||||
unsafe { RtlCaptureContext(&mut context); }
|
||||
let mut frame: STACKFRAME64 = unsafe { intrinsics::init() };
|
||||
let image = arch::init_frame(&mut frame, &context);
|
||||
let process = unsafe { c::GetCurrentProcess() };
|
||||
let thread = unsafe { c::GetCurrentThread() };
|
||||
let mut context: c::CONTEXT = unsafe { mem::zeroed() };
|
||||
unsafe { c::RtlCaptureContext(&mut context); }
|
||||
let mut frame: c::STACKFRAME64 = unsafe { mem::zeroed() };
|
||||
let image = init_frame(&mut frame, &context);
|
||||
|
||||
// Initialize this process's symbols
|
||||
let ret = SymInitialize(process, ptr::null_mut(), libc::TRUE);
|
||||
if ret != libc::TRUE { return Ok(()) }
|
||||
let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
|
||||
if ret != c::TRUE { return Ok(()) }
|
||||
let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
|
||||
|
||||
// And now that we're done with all the setup, do the stack walking!
|
||||
|
@ -356,7 +143,7 @@ pub fn write(w: &mut Write) -> io::Result<()> {
|
|||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut()) == libc::TRUE{
|
||||
ptr::null_mut()) == c::TRUE {
|
||||
let addr = frame.AddrPC.Offset;
|
||||
if addr == frame.AddrReturn.Offset || addr == 0 ||
|
||||
frame.AddrReturn.Offset == 0 { break }
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -24,21 +24,16 @@
|
|||
use prelude::v1::*;
|
||||
|
||||
use ffi::CString;
|
||||
use libc::{LPVOID, LPCWSTR, HMODULE, LPCSTR};
|
||||
use sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
extern "system" {
|
||||
fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
|
||||
fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
|
||||
}
|
||||
use sys::c;
|
||||
|
||||
pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
|
||||
let mut module: Vec<u16> = module.utf16_units().collect();
|
||||
module.push(0);
|
||||
let symbol = CString::new(symbol).unwrap();
|
||||
unsafe {
|
||||
let handle = GetModuleHandleW(module.as_ptr());
|
||||
match GetProcAddress(handle, symbol.as_ptr()) as usize {
|
||||
let handle = c::GetModuleHandleW(module.as_ptr());
|
||||
match c::GetProcAddress(handle, symbol.as_ptr()) as usize {
|
||||
0 => None,
|
||||
n => Some(n),
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
use cell::UnsafeCell;
|
||||
use libc::{self, DWORD};
|
||||
use sys::c;
|
||||
use sys::mutex::{self, Mutex};
|
||||
use sys::os;
|
||||
|
@ -29,7 +28,7 @@ impl Condvar {
|
|||
pub unsafe fn wait(&self, mutex: &Mutex) {
|
||||
let r = c::SleepConditionVariableSRW(self.inner.get(),
|
||||
mutex::raw(mutex),
|
||||
libc::INFINITE,
|
||||
c::INFINITE,
|
||||
0);
|
||||
debug_assert!(r != 0);
|
||||
}
|
||||
|
@ -40,8 +39,7 @@ impl Condvar {
|
|||
super::dur2timeout(dur),
|
||||
0);
|
||||
if r == 0 {
|
||||
const ERROR_TIMEOUT: DWORD = 0x5B4;
|
||||
debug_assert_eq!(os::errno() as usize, ERROR_TIMEOUT as usize);
|
||||
debug_assert_eq!(os::errno() as usize, c::ERROR_TIMEOUT as usize);
|
||||
false
|
||||
} else {
|
||||
true
|
||||
|
|
|
@ -15,6 +15,7 @@ use os::windows::raw;
|
|||
use net;
|
||||
use sys_common::{self, AsInner, FromInner, IntoInner};
|
||||
use sys;
|
||||
use sys::c;
|
||||
|
||||
/// Raw HANDLEs.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -73,7 +74,7 @@ impl AsRawHandle for fs::File {
|
|||
#[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 ::libc::HANDLE;
|
||||
let handle = handle as c::HANDLE;
|
||||
fs::File::from_inner(sys::fs::File::from_inner(handle))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ use os::windows::prelude::*;
|
|||
use ffi::OsString;
|
||||
use fmt;
|
||||
use io::{self, Error, SeekFrom};
|
||||
use libc::{self, HANDLE};
|
||||
use mem;
|
||||
use path::{Path, PathBuf};
|
||||
use ptr;
|
||||
|
@ -30,7 +29,7 @@ pub struct File { handle: Handle }
|
|||
#[derive(Clone)]
|
||||
pub struct FileAttr {
|
||||
data: c::WIN32_FILE_ATTRIBUTE_DATA,
|
||||
reparse_tag: libc::DWORD,
|
||||
reparse_tag: c::DWORD,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
@ -41,17 +40,17 @@ pub enum FileType {
|
|||
pub struct ReadDir {
|
||||
handle: FindNextFileHandle,
|
||||
root: Arc<PathBuf>,
|
||||
first: Option<libc::WIN32_FIND_DATAW>,
|
||||
first: Option<c::WIN32_FIND_DATAW>,
|
||||
}
|
||||
|
||||
struct FindNextFileHandle(libc::HANDLE);
|
||||
struct FindNextFileHandle(c::HANDLE);
|
||||
|
||||
unsafe impl Send for FindNextFileHandle {}
|
||||
unsafe impl Sync for FindNextFileHandle {}
|
||||
|
||||
pub struct DirEntry {
|
||||
root: Arc<PathBuf>,
|
||||
data: libc::WIN32_FIND_DATAW,
|
||||
data: c::WIN32_FIND_DATAW,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
|
@ -61,15 +60,15 @@ pub struct OpenOptions {
|
|||
read: bool,
|
||||
write: bool,
|
||||
truncate: bool,
|
||||
desired_access: Option<libc::DWORD>,
|
||||
share_mode: Option<libc::DWORD>,
|
||||
creation_disposition: Option<libc::DWORD>,
|
||||
flags_and_attributes: Option<libc::DWORD>,
|
||||
desired_access: Option<c::DWORD>,
|
||||
share_mode: Option<c::DWORD>,
|
||||
creation_disposition: Option<c::DWORD>,
|
||||
flags_and_attributes: Option<c::DWORD>,
|
||||
security_attributes: usize, // *mut T doesn't have a Default impl
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct FilePermissions { attrs: libc::DWORD }
|
||||
pub struct FilePermissions { attrs: c::DWORD }
|
||||
|
||||
pub struct DirBuilder;
|
||||
|
||||
|
@ -84,9 +83,8 @@ impl Iterator for ReadDir {
|
|||
unsafe {
|
||||
let mut wfd = mem::zeroed();
|
||||
loop {
|
||||
if libc::FindNextFileW(self.handle.0, &mut wfd) == 0 {
|
||||
if libc::GetLastError() ==
|
||||
c::ERROR_NO_MORE_FILES as libc::DWORD {
|
||||
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()))
|
||||
|
@ -102,13 +100,13 @@ impl Iterator for ReadDir {
|
|||
|
||||
impl Drop for FindNextFileHandle {
|
||||
fn drop(&mut self) {
|
||||
let r = unsafe { libc::FindClose(self.0) };
|
||||
let r = unsafe { c::FindClose(self.0) };
|
||||
debug_assert!(r != 0);
|
||||
}
|
||||
}
|
||||
|
||||
impl DirEntry {
|
||||
fn new(root: &Arc<PathBuf>, wfd: &libc::WIN32_FIND_DATAW) -> Option<DirEntry> {
|
||||
fn new(root: &Arc<PathBuf>, wfd: &c::WIN32_FIND_DATAW) -> Option<DirEntry> {
|
||||
match &wfd.cFileName[0..3] {
|
||||
// check for '.' and '..'
|
||||
[46, 0, ..] |
|
||||
|
@ -170,50 +168,50 @@ impl OpenOptions {
|
|||
pub fn share_mode(&mut self, val: u32) {
|
||||
self.share_mode = Some(val);
|
||||
}
|
||||
pub fn security_attributes(&mut self, attrs: libc::LPSECURITY_ATTRIBUTES) {
|
||||
pub fn security_attributes(&mut self, attrs: c::LPSECURITY_ATTRIBUTES) {
|
||||
self.security_attributes = attrs as usize;
|
||||
}
|
||||
|
||||
fn get_desired_access(&self) -> libc::DWORD {
|
||||
fn get_desired_access(&self) -> c::DWORD {
|
||||
self.desired_access.unwrap_or({
|
||||
let mut base = if self.read {libc::FILE_GENERIC_READ} else {0} |
|
||||
if self.write {libc::FILE_GENERIC_WRITE} else {0};
|
||||
let mut base = if self.read {c::FILE_GENERIC_READ} else {0} |
|
||||
if self.write {c::FILE_GENERIC_WRITE} else {0};
|
||||
if self.append {
|
||||
base &= !libc::FILE_WRITE_DATA;
|
||||
base |= libc::FILE_APPEND_DATA;
|
||||
base &= !c::FILE_WRITE_DATA;
|
||||
base |= c::FILE_APPEND_DATA;
|
||||
}
|
||||
base
|
||||
})
|
||||
}
|
||||
|
||||
fn get_share_mode(&self) -> libc::DWORD {
|
||||
fn get_share_mode(&self) -> c::DWORD {
|
||||
// libuv has a good comment about this, but the basic idea is that
|
||||
// we try to emulate unix semantics by enabling all sharing by
|
||||
// allowing things such as deleting a file while it's still open.
|
||||
self.share_mode.unwrap_or(libc::FILE_SHARE_READ |
|
||||
libc::FILE_SHARE_WRITE |
|
||||
libc::FILE_SHARE_DELETE)
|
||||
self.share_mode.unwrap_or(c::FILE_SHARE_READ |
|
||||
c::FILE_SHARE_WRITE |
|
||||
c::FILE_SHARE_DELETE)
|
||||
}
|
||||
|
||||
fn get_creation_disposition(&self) -> libc::DWORD {
|
||||
fn get_creation_disposition(&self) -> c::DWORD {
|
||||
self.creation_disposition.unwrap_or({
|
||||
match (self.create, self.truncate) {
|
||||
(true, true) => libc::CREATE_ALWAYS,
|
||||
(true, false) => libc::OPEN_ALWAYS,
|
||||
(false, false) => libc::OPEN_EXISTING,
|
||||
(true, true) => c::CREATE_ALWAYS,
|
||||
(true, false) => c::OPEN_ALWAYS,
|
||||
(false, false) => c::OPEN_EXISTING,
|
||||
(false, true) => {
|
||||
if self.write && !self.append {
|
||||
libc::CREATE_ALWAYS
|
||||
c::CREATE_ALWAYS
|
||||
} else {
|
||||
libc::TRUNCATE_EXISTING
|
||||
c::TRUNCATE_EXISTING
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn get_flags_and_attributes(&self) -> libc::DWORD {
|
||||
self.flags_and_attributes.unwrap_or(libc::FILE_ATTRIBUTE_NORMAL)
|
||||
fn get_flags_and_attributes(&self) -> c::DWORD {
|
||||
self.flags_and_attributes.unwrap_or(c::FILE_ATTRIBUTE_NORMAL)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,15 +228,15 @@ impl File {
|
|||
pub fn open(path: &Path, opts: &OpenOptions) -> io::Result<File> {
|
||||
let path = to_utf16(path);
|
||||
let handle = unsafe {
|
||||
libc::CreateFileW(path.as_ptr(),
|
||||
opts.get_desired_access(),
|
||||
opts.get_share_mode(),
|
||||
opts.security_attributes as *mut _,
|
||||
opts.get_creation_disposition(),
|
||||
opts.get_flags_and_attributes(),
|
||||
ptr::null_mut())
|
||||
c::CreateFileW(path.as_ptr(),
|
||||
opts.get_desired_access(),
|
||||
opts.get_share_mode(),
|
||||
opts.security_attributes as *mut _,
|
||||
opts.get_creation_disposition(),
|
||||
opts.get_flags_and_attributes(),
|
||||
ptr::null_mut())
|
||||
};
|
||||
if handle == libc::INVALID_HANDLE_VALUE {
|
||||
if handle == c::INVALID_HANDLE_VALUE {
|
||||
Err(Error::last_os_error())
|
||||
} else {
|
||||
Ok(File { handle: Handle::new(handle) })
|
||||
|
@ -246,7 +244,7 @@ impl File {
|
|||
}
|
||||
|
||||
pub fn fsync(&self) -> io::Result<()> {
|
||||
try!(cvt(unsafe { libc::FlushFileBuffers(self.handle.raw()) }));
|
||||
try!(cvt(unsafe { c::FlushFileBuffers(self.handle.raw()) }));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -254,14 +252,14 @@ impl File {
|
|||
|
||||
pub fn truncate(&self, size: u64) -> io::Result<()> {
|
||||
let mut info = c::FILE_END_OF_FILE_INFO {
|
||||
EndOfFile: size as libc::LARGE_INTEGER,
|
||||
EndOfFile: size as c::LARGE_INTEGER,
|
||||
};
|
||||
let size = mem::size_of_val(&info);
|
||||
try!(cvt(unsafe {
|
||||
c::SetFileInformationByHandle(self.handle.raw(),
|
||||
c::FileEndOfFileInfo,
|
||||
&mut info as *mut _ as *mut _,
|
||||
size as libc::DWORD)
|
||||
size as c::DWORD)
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -304,15 +302,15 @@ impl File {
|
|||
|
||||
pub fn seek(&self, pos: SeekFrom) -> io::Result<u64> {
|
||||
let (whence, pos) = match pos {
|
||||
SeekFrom::Start(n) => (libc::FILE_BEGIN, n as i64),
|
||||
SeekFrom::End(n) => (libc::FILE_END, n),
|
||||
SeekFrom::Current(n) => (libc::FILE_CURRENT, n),
|
||||
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 libc::LARGE_INTEGER;
|
||||
let pos = pos as c::LARGE_INTEGER;
|
||||
let mut newpos = 0;
|
||||
try!(cvt(unsafe {
|
||||
libc::SetFilePointerEx(self.handle.raw(), pos,
|
||||
&mut newpos, whence)
|
||||
c::SetFilePointerEx(self.handle.raw(), pos,
|
||||
&mut newpos, whence)
|
||||
}));
|
||||
Ok(newpos as u64)
|
||||
}
|
||||
|
@ -323,7 +321,7 @@ impl File {
|
|||
|
||||
fn reparse_point<'a>(&self,
|
||||
space: &'a mut [u8; c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE])
|
||||
-> io::Result<(libc::DWORD, &'a c::REPARSE_DATA_BUFFER)> {
|
||||
-> io::Result<(c::DWORD, &'a c::REPARSE_DATA_BUFFER)> {
|
||||
unsafe {
|
||||
let mut bytes = 0;
|
||||
try!(cvt({
|
||||
|
@ -332,7 +330,7 @@ impl File {
|
|||
ptr::null_mut(),
|
||||
0,
|
||||
space.as_mut_ptr() as *mut _,
|
||||
space.len() as libc::DWORD,
|
||||
space.len() as c::DWORD,
|
||||
&mut bytes,
|
||||
ptr::null_mut())
|
||||
}));
|
||||
|
@ -361,8 +359,8 @@ impl File {
|
|||
}
|
||||
}
|
||||
|
||||
impl FromInner<libc::HANDLE> for File {
|
||||
fn from_inner(handle: libc::HANDLE) -> File {
|
||||
impl FromInner<c::HANDLE> for File {
|
||||
fn from_inner(handle: c::HANDLE) -> File {
|
||||
File { handle: Handle::new(handle) }
|
||||
}
|
||||
}
|
||||
|
@ -402,12 +400,12 @@ impl FileAttr {
|
|||
pub fn accessed(&self) -> u64 { self.to_u64(&self.data.ftLastAccessTime) }
|
||||
pub fn modified(&self) -> u64 { self.to_u64(&self.data.ftLastWriteTime) }
|
||||
|
||||
fn to_u64(&self, ft: &libc::FILETIME) -> u64 {
|
||||
fn to_u64(&self, ft: &c::FILETIME) -> u64 {
|
||||
(ft.dwLowDateTime as u64) | ((ft.dwHighDateTime as u64) << 32)
|
||||
}
|
||||
|
||||
fn is_reparse_point(&self) -> bool {
|
||||
self.data.dwFileAttributes & libc::FILE_ATTRIBUTE_REPARSE_POINT != 0
|
||||
self.data.dwFileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -426,8 +424,8 @@ impl FilePermissions {
|
|||
}
|
||||
|
||||
impl FileType {
|
||||
fn new(attrs: libc::DWORD, reparse_tag: libc::DWORD) -> FileType {
|
||||
if attrs & libc::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType {
|
||||
if attrs & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
|
||||
match reparse_tag {
|
||||
c::IO_REPARSE_TAG_SYMLINK => FileType::Symlink,
|
||||
c::IO_REPARSE_TAG_MOUNT_POINT => FileType::MountPoint,
|
||||
|
@ -453,7 +451,7 @@ impl DirBuilder {
|
|||
pub fn mkdir(&self, p: &Path) -> io::Result<()> {
|
||||
let p = to_utf16(p);
|
||||
try!(cvt(unsafe {
|
||||
libc::CreateDirectoryW(p.as_ptr(), ptr::null_mut())
|
||||
c::CreateDirectoryW(p.as_ptr(), ptr::null_mut())
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -466,8 +464,8 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
|
|||
|
||||
unsafe {
|
||||
let mut wfd = mem::zeroed();
|
||||
let find_handle = libc::FindFirstFileW(path.as_ptr(), &mut wfd);
|
||||
if find_handle != libc::INVALID_HANDLE_VALUE {
|
||||
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),
|
||||
|
@ -481,7 +479,7 @@ pub fn readdir(p: &Path) -> io::Result<ReadDir> {
|
|||
|
||||
pub fn unlink(p: &Path) -> io::Result<()> {
|
||||
let p_utf16 = to_utf16(p);
|
||||
try!(cvt(unsafe { libc::DeleteFileW(p_utf16.as_ptr()) }));
|
||||
try!(cvt(unsafe { c::DeleteFileW(p_utf16.as_ptr()) }));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -489,8 +487,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
|
|||
let old = to_utf16(old);
|
||||
let new = to_utf16(new);
|
||||
try!(cvt(unsafe {
|
||||
libc::MoveFileExW(old.as_ptr(), new.as_ptr(),
|
||||
libc::MOVEFILE_REPLACE_EXISTING)
|
||||
c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING)
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -515,7 +512,7 @@ pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
|
|||
let dst = to_utf16(dst);
|
||||
let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 };
|
||||
try!(cvt(unsafe {
|
||||
c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL
|
||||
c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as c::BOOL
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -524,7 +521,7 @@ pub fn link(src: &Path, dst: &Path) -> io::Result<()> {
|
|||
let src = to_utf16(src);
|
||||
let dst = to_utf16(dst);
|
||||
try!(cvt(unsafe {
|
||||
libc::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::null_mut())
|
||||
c::CreateHardLinkW(dst.as_ptr(), src.as_ptr(), ptr::null_mut())
|
||||
}));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -575,7 +572,7 @@ pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> {
|
|||
fn get_path(f: &File) -> io::Result<PathBuf> {
|
||||
super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
|
||||
libc::VOLUME_NAME_DOS)
|
||||
c::VOLUME_NAME_DOS)
|
||||
}, |buf| {
|
||||
PathBuf::from(OsString::from_wide(buf))
|
||||
})
|
||||
|
@ -592,16 +589,16 @@ pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
|
|||
|
||||
pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
|
||||
unsafe extern "system" fn callback(
|
||||
_TotalFileSize: libc::LARGE_INTEGER,
|
||||
TotalBytesTransferred: libc::LARGE_INTEGER,
|
||||
_StreamSize: libc::LARGE_INTEGER,
|
||||
_StreamBytesTransferred: libc::LARGE_INTEGER,
|
||||
_dwStreamNumber: libc::DWORD,
|
||||
_dwCallbackReason: libc::DWORD,
|
||||
_hSourceFile: HANDLE,
|
||||
_hDestinationFile: HANDLE,
|
||||
lpData: libc::LPVOID,
|
||||
) -> libc::DWORD {
|
||||
_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 {
|
||||
*(lpData as *mut i64) = TotalBytesTransferred;
|
||||
c::PROGRESS_CONTINUE
|
||||
}
|
||||
|
@ -673,10 +670,10 @@ fn directory_junctions_are_directories() {
|
|||
*buf.offset(i) = 0;
|
||||
i += 1;
|
||||
(*db).ReparseTag = c::IO_REPARSE_TAG_MOUNT_POINT;
|
||||
(*db).ReparseTargetMaximumLength = (i * 2) as libc::WORD;
|
||||
(*db).ReparseTargetLength = ((i - 1) * 2) as libc::WORD;
|
||||
(*db).ReparseTargetMaximumLength = (i * 2) as c::WORD;
|
||||
(*db).ReparseTargetLength = ((i - 1) * 2) as c::WORD;
|
||||
(*db).ReparseDataLength =
|
||||
(*db).ReparseTargetLength as libc::DWORD + 12;
|
||||
(*db).ReparseTargetLength as c::DWORD + 12;
|
||||
|
||||
let mut ret = 0;
|
||||
cvt(c::DeviceIoControl(h as *mut _,
|
||||
|
@ -707,10 +704,10 @@ fn directory_junctions_are_directories() {
|
|||
&mut tp.Privileges[0].Luid)));
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Attributes = c::SE_PRIVILEGE_ENABLED;
|
||||
let size = mem::size_of::<c::TOKEN_PRIVILEGES>() as libc::DWORD;
|
||||
try!(cvt(c::AdjustTokenPrivileges(token, libc::FALSE, &mut tp, size,
|
||||
let size = mem::size_of::<c::TOKEN_PRIVILEGES>() as c::DWORD;
|
||||
try!(cvt(c::AdjustTokenPrivileges(token, c::FALSE, &mut tp, size,
|
||||
ptr::null_mut(), ptr::null_mut())));
|
||||
try!(cvt(libc::CloseHandle(token)));
|
||||
try!(cvt(c::CloseHandle(token)));
|
||||
|
||||
File::open_reparse_point(p, write)
|
||||
}
|
||||
|
|
|
@ -10,11 +10,10 @@
|
|||
|
||||
use io::ErrorKind;
|
||||
use io;
|
||||
use libc::funcs::extra::kernel32::{GetCurrentProcess, DuplicateHandle};
|
||||
use libc::{self, HANDLE};
|
||||
use mem;
|
||||
use ops::Deref;
|
||||
use ptr;
|
||||
use sys::c;
|
||||
use sys::cvt;
|
||||
|
||||
/// An owned container for `HANDLE` object, closing them on Drop.
|
||||
|
@ -28,17 +27,17 @@ pub struct Handle(RawHandle);
|
|||
/// This does **not** drop the handle when it goes out of scope, use `Handle`
|
||||
/// instead for that.
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct RawHandle(HANDLE);
|
||||
pub struct RawHandle(c::HANDLE);
|
||||
|
||||
unsafe impl Send for RawHandle {}
|
||||
unsafe impl Sync for RawHandle {}
|
||||
|
||||
impl Handle {
|
||||
pub fn new(handle: HANDLE) -> Handle {
|
||||
pub fn new(handle: c::HANDLE) -> Handle {
|
||||
Handle(RawHandle::new(handle))
|
||||
}
|
||||
|
||||
pub fn into_raw(self) -> HANDLE {
|
||||
pub fn into_raw(self) -> c::HANDLE {
|
||||
let ret = self.raw();
|
||||
mem::forget(self);
|
||||
return ret;
|
||||
|
@ -52,22 +51,22 @@ impl Deref for Handle {
|
|||
|
||||
impl Drop for Handle {
|
||||
fn drop(&mut self) {
|
||||
unsafe { let _ = libc::CloseHandle(self.raw()); }
|
||||
unsafe { let _ = c::CloseHandle(self.raw()); }
|
||||
}
|
||||
}
|
||||
|
||||
impl RawHandle {
|
||||
pub fn new(handle: HANDLE) -> RawHandle {
|
||||
pub fn new(handle: c::HANDLE) -> RawHandle {
|
||||
RawHandle(handle)
|
||||
}
|
||||
|
||||
pub fn raw(&self) -> HANDLE { self.0 }
|
||||
pub fn raw(&self) -> c::HANDLE { self.0 }
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let mut read = 0;
|
||||
let res = cvt(unsafe {
|
||||
libc::ReadFile(self.0, buf.as_ptr() as libc::LPVOID,
|
||||
buf.len() as libc::DWORD, &mut read,
|
||||
c::ReadFile(self.0, buf.as_ptr() as c::LPVOID,
|
||||
buf.len() as c::DWORD, &mut read,
|
||||
ptr::null_mut())
|
||||
});
|
||||
|
||||
|
@ -87,20 +86,20 @@ impl RawHandle {
|
|||
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
|
||||
let mut amt = 0;
|
||||
try!(cvt(unsafe {
|
||||
libc::WriteFile(self.0, buf.as_ptr() as libc::LPVOID,
|
||||
buf.len() as libc::DWORD, &mut amt,
|
||||
c::WriteFile(self.0, buf.as_ptr() as c::LPVOID,
|
||||
buf.len() as c::DWORD, &mut amt,
|
||||
ptr::null_mut())
|
||||
}));
|
||||
Ok(amt as usize)
|
||||
}
|
||||
|
||||
pub fn duplicate(&self, access: libc::DWORD, inherit: bool,
|
||||
options: libc::DWORD) -> io::Result<Handle> {
|
||||
let mut ret = 0 as libc::HANDLE;
|
||||
pub fn duplicate(&self, access: c::DWORD, inherit: bool,
|
||||
options: c::DWORD) -> io::Result<Handle> {
|
||||
let mut ret = 0 as c::HANDLE;
|
||||
try!(cvt(unsafe {
|
||||
let cur_proc = GetCurrentProcess();
|
||||
DuplicateHandle(cur_proc, self.0, cur_proc, &mut ret,
|
||||
access, inherit as libc::BOOL,
|
||||
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))
|
||||
|
|
|
@ -16,7 +16,6 @@ use prelude::v1::*;
|
|||
|
||||
use ffi::{OsStr, OsString};
|
||||
use io::{self, ErrorKind};
|
||||
use libc;
|
||||
use num::Zero;
|
||||
use os::windows::ffi::{OsStrExt, OsStringExt};
|
||||
use path::PathBuf;
|
||||
|
@ -46,25 +45,28 @@ pub mod stdio;
|
|||
pub fn init() {}
|
||||
|
||||
pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
||||
match errno as libc::c_int {
|
||||
libc::ERROR_ACCESS_DENIED => ErrorKind::PermissionDenied,
|
||||
libc::ERROR_ALREADY_EXISTS => ErrorKind::AlreadyExists,
|
||||
libc::ERROR_BROKEN_PIPE => ErrorKind::BrokenPipe,
|
||||
libc::ERROR_FILE_NOT_FOUND => ErrorKind::NotFound,
|
||||
c::ERROR_PATH_NOT_FOUND => ErrorKind::NotFound,
|
||||
libc::ERROR_NO_DATA => ErrorKind::BrokenPipe,
|
||||
libc::ERROR_OPERATION_ABORTED => ErrorKind::TimedOut,
|
||||
match errno as c::DWORD {
|
||||
c::ERROR_ACCESS_DENIED => return ErrorKind::PermissionDenied,
|
||||
c::ERROR_ALREADY_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,
|
||||
_ => {}
|
||||
}
|
||||
|
||||
libc::WSAEACCES => ErrorKind::PermissionDenied,
|
||||
libc::WSAEADDRINUSE => ErrorKind::AddrInUse,
|
||||
libc::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable,
|
||||
libc::WSAECONNABORTED => ErrorKind::ConnectionAborted,
|
||||
libc::WSAECONNREFUSED => ErrorKind::ConnectionRefused,
|
||||
libc::WSAECONNRESET => ErrorKind::ConnectionReset,
|
||||
libc::WSAEINVAL => ErrorKind::InvalidInput,
|
||||
libc::WSAENOTCONN => ErrorKind::NotConnected,
|
||||
libc::WSAEWOULDBLOCK => ErrorKind::WouldBlock,
|
||||
libc::WSAETIMEDOUT => 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,
|
||||
}
|
||||
|
@ -91,7 +93,7 @@ fn to_utf16_os(s: &OsStr) -> Vec<u16> {
|
|||
// 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, libc::DWORD) -> libc::DWORD,
|
||||
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
|
||||
|
@ -120,13 +122,12 @@ fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> io::Result<T>
|
|||
// 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 libc::DWORD) {
|
||||
0 if libc::GetLastError() == 0 => 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 && libc::GetLastError() ==
|
||||
libc::ERROR_INSUFFICIENT_BUFFER as libc::DWORD {
|
||||
if k == n && c::GetLastError() == c::ERROR_INSUFFICIENT_BUFFER {
|
||||
n *= 2;
|
||||
} else if k >= n {
|
||||
n = k;
|
||||
|
@ -157,7 +158,7 @@ fn cvt<I: PartialEq + Zero>(i: I) -> io::Result<I> {
|
|||
}
|
||||
}
|
||||
|
||||
fn dur2timeout(dur: Duration) -> libc::DWORD {
|
||||
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:
|
||||
|
@ -170,10 +171,10 @@ fn dur2timeout(dur: Duration) -> libc::DWORD {
|
|||
}).and_then(|ms| {
|
||||
ms.checked_add(if dur.subsec_nanos() % 1_000_000 > 0 {1} else {0})
|
||||
}).map(|ms| {
|
||||
if ms > <libc::DWORD>::max_value() as u64 {
|
||||
libc::INFINITE
|
||||
if ms > <c::DWORD>::max_value() as u64 {
|
||||
c::INFINITE
|
||||
} else {
|
||||
ms as libc::DWORD
|
||||
ms as c::DWORD
|
||||
}
|
||||
}).unwrap_or(libc::INFINITE)
|
||||
}).unwrap_or(c::INFINITE)
|
||||
}
|
||||
|
|
|
@ -9,23 +9,30 @@
|
|||
// except according to those terms.
|
||||
|
||||
use io;
|
||||
use libc::consts::os::extra::INVALID_SOCKET;
|
||||
use libc::{self, c_int, c_void};
|
||||
use libc::{c_int, c_void};
|
||||
use mem;
|
||||
use net::SocketAddr;
|
||||
use net::{SocketAddr, Shutdown};
|
||||
use num::One;
|
||||
use ops::Neg;
|
||||
use ptr;
|
||||
use sync::Once;
|
||||
use sys;
|
||||
use sys::c;
|
||||
use sys;
|
||||
use sys_common::{self, AsInner, FromInner, IntoInner};
|
||||
use sys_common::net::{setsockopt, getsockopt};
|
||||
use sys_common::net;
|
||||
use time::Duration;
|
||||
|
||||
pub type wrlen_t = i32;
|
||||
|
||||
pub struct Socket(libc::SOCKET);
|
||||
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.
|
||||
|
@ -76,13 +83,13 @@ pub fn cvt_r<T, F>(mut f: F) -> io::Result<T>
|
|||
impl Socket {
|
||||
pub fn new(addr: &SocketAddr, ty: c_int) -> io::Result<Socket> {
|
||||
let fam = match *addr {
|
||||
SocketAddr::V4(..) => libc::AF_INET,
|
||||
SocketAddr::V6(..) => libc::AF_INET6,
|
||||
SocketAddr::V4(..) => c::AF_INET,
|
||||
SocketAddr::V6(..) => c::AF_INET6,
|
||||
};
|
||||
let socket = try!(unsafe {
|
||||
match c::WSASocketW(fam, ty, 0, ptr::null_mut(), 0,
|
||||
c::WSA_FLAG_OVERLAPPED) {
|
||||
INVALID_SOCKET => Err(last_error()),
|
||||
c::INVALID_SOCKET => Err(last_error()),
|
||||
n => Ok(Socket(n)),
|
||||
}
|
||||
});
|
||||
|
@ -90,11 +97,11 @@ impl Socket {
|
|||
Ok(socket)
|
||||
}
|
||||
|
||||
pub fn accept(&self, storage: *mut libc::sockaddr,
|
||||
len: *mut libc::socklen_t) -> io::Result<Socket> {
|
||||
pub fn accept(&self, storage: *mut c::SOCKADDR,
|
||||
len: *mut c_int) -> io::Result<Socket> {
|
||||
let socket = try!(unsafe {
|
||||
match libc::accept(self.0, storage, len) {
|
||||
INVALID_SOCKET => Err(last_error()),
|
||||
match c::accept(self.0, storage, len) {
|
||||
c::INVALID_SOCKET => Err(last_error()),
|
||||
n => Ok(Socket(n)),
|
||||
}
|
||||
});
|
||||
|
@ -113,7 +120,7 @@ impl Socket {
|
|||
info.iProtocol,
|
||||
&mut info, 0,
|
||||
c::WSA_FLAG_OVERLAPPED) {
|
||||
INVALID_SOCKET => Err(last_error()),
|
||||
c::INVALID_SOCKET => Err(last_error()),
|
||||
n => Ok(Socket(n)),
|
||||
}
|
||||
});
|
||||
|
@ -125,7 +132,7 @@ impl Socket {
|
|||
// 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 libc::recv(self.0, buf.as_mut_ptr() as *mut c_void,
|
||||
match c::recv(self.0, buf.as_mut_ptr() as *mut c_void,
|
||||
buf.len() as i32, 0) {
|
||||
-1 if c::WSAGetLastError() == c::WSAESHUTDOWN => Ok(0),
|
||||
-1 => Err(last_error()),
|
||||
|
@ -134,7 +141,8 @@ impl Socket {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_timeout(&self, dur: Option<Duration>, kind: libc::c_int) -> io::Result<()> {
|
||||
pub fn set_timeout(&self, dur: Option<Duration>,
|
||||
kind: c_int) -> io::Result<()> {
|
||||
let timeout = match dur {
|
||||
Some(dur) => {
|
||||
let timeout = sys::dur2timeout(dur);
|
||||
|
@ -146,11 +154,11 @@ impl Socket {
|
|||
}
|
||||
None => 0
|
||||
};
|
||||
setsockopt(self, libc::SOL_SOCKET, kind, timeout)
|
||||
net::setsockopt(self, c::SOL_SOCKET, kind, timeout)
|
||||
}
|
||||
|
||||
pub fn timeout(&self, kind: libc::c_int) -> io::Result<Option<Duration>> {
|
||||
let raw: libc::DWORD = try!(getsockopt(self, libc::SOL_SOCKET, kind));
|
||||
pub fn timeout(&self, kind: c_int) -> io::Result<Option<Duration>> {
|
||||
let raw: c::DWORD = try!(net::getsockopt(self, c::SOL_SOCKET, kind));
|
||||
if raw == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
|
@ -162,28 +170,38 @@ impl Socket {
|
|||
|
||||
fn set_no_inherit(&self) -> io::Result<()> {
|
||||
sys::cvt(unsafe {
|
||||
c::SetHandleInformation(self.0 as libc::HANDLE,
|
||||
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,
|
||||
};
|
||||
try!(cvt(unsafe { c::shutdown(self.0, how) }));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Socket {
|
||||
fn drop(&mut self) {
|
||||
let _ = unsafe { libc::closesocket(self.0) };
|
||||
let _ = unsafe { c::closesocket(self.0) };
|
||||
}
|
||||
}
|
||||
|
||||
impl AsInner<libc::SOCKET> for Socket {
|
||||
fn as_inner(&self) -> &libc::SOCKET { &self.0 }
|
||||
impl AsInner<c::SOCKET> for Socket {
|
||||
fn as_inner(&self) -> &c::SOCKET { &self.0 }
|
||||
}
|
||||
|
||||
impl FromInner<libc::SOCKET> for Socket {
|
||||
fn from_inner(sock: libc::SOCKET) -> Socket { Socket(sock) }
|
||||
impl FromInner<c::SOCKET> for Socket {
|
||||
fn from_inner(sock: c::SOCKET) -> Socket { Socket(sock) }
|
||||
}
|
||||
|
||||
impl IntoInner<libc::SOCKET> for Socket {
|
||||
fn into_inner(self) -> libc::SOCKET {
|
||||
impl IntoInner<c::SOCKET> for Socket {
|
||||
fn into_inner(self) -> c::SOCKET {
|
||||
let ret = self.0;
|
||||
mem::forget(self);
|
||||
ret
|
||||
|
|
|
@ -19,8 +19,7 @@ use error::Error as StdError;
|
|||
use ffi::{OsString, OsStr};
|
||||
use fmt;
|
||||
use io;
|
||||
use libc::types::os::arch::extra::LPWCH;
|
||||
use libc::{self, c_int, c_void};
|
||||
use libc::{c_int, c_void};
|
||||
use ops::Range;
|
||||
use os::windows::ffi::EncodeWide;
|
||||
use path::{self, PathBuf};
|
||||
|
@ -29,52 +28,27 @@ use slice;
|
|||
use sys::{c, cvt};
|
||||
use sys::handle::Handle;
|
||||
|
||||
use libc::funcs::extra::kernel32::{
|
||||
GetEnvironmentStringsW,
|
||||
FreeEnvironmentStringsW
|
||||
};
|
||||
|
||||
pub fn errno() -> i32 {
|
||||
unsafe { libc::GetLastError() as i32 }
|
||||
unsafe { c::GetLastError() as i32 }
|
||||
}
|
||||
|
||||
/// Gets a detailed string description for the given error number.
|
||||
pub fn error_string(errnum: i32) -> String {
|
||||
use libc::types::os::arch::extra::DWORD;
|
||||
use libc::types::os::arch::extra::LPWSTR;
|
||||
use libc::types::os::arch::extra::LPVOID;
|
||||
use libc::types::os::arch::extra::WCHAR;
|
||||
|
||||
#[link_name = "kernel32"]
|
||||
extern "system" {
|
||||
fn FormatMessageW(flags: DWORD,
|
||||
lpSrc: LPVOID,
|
||||
msgId: DWORD,
|
||||
langId: DWORD,
|
||||
buf: LPWSTR,
|
||||
nsize: DWORD,
|
||||
args: *const c_void)
|
||||
-> DWORD;
|
||||
}
|
||||
|
||||
const FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
|
||||
const FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
|
||||
|
||||
// This value is calculated from the macro
|
||||
// MAKELANGID(LANG_SYSTEM_DEFAULT, SUBLANG_SYS_DEFAULT)
|
||||
let langId = 0x0800 as DWORD;
|
||||
let langId = 0x0800 as c::DWORD;
|
||||
|
||||
let mut buf = [0 as WCHAR; 2048];
|
||||
let mut buf = [0 as c::WCHAR; 2048];
|
||||
|
||||
unsafe {
|
||||
let res = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
ptr::null_mut(),
|
||||
errnum as DWORD,
|
||||
langId,
|
||||
buf.as_mut_ptr(),
|
||||
buf.len() as DWORD,
|
||||
ptr::null()) as usize;
|
||||
let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
c::FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
ptr::null_mut(),
|
||||
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();
|
||||
|
@ -96,8 +70,8 @@ pub fn error_string(errnum: i32) -> String {
|
|||
}
|
||||
|
||||
pub struct Env {
|
||||
base: LPWCH,
|
||||
cur: LPWCH,
|
||||
base: c::LPWCH,
|
||||
cur: c::LPWCH,
|
||||
}
|
||||
|
||||
impl Iterator for Env {
|
||||
|
@ -126,13 +100,13 @@ impl Iterator for Env {
|
|||
|
||||
impl Drop for Env {
|
||||
fn drop(&mut self) {
|
||||
unsafe { FreeEnvironmentStringsW(self.base); }
|
||||
unsafe { c::FreeEnvironmentStringsW(self.base); }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn env() -> Env {
|
||||
unsafe {
|
||||
let ch = GetEnvironmentStringsW();
|
||||
let ch = c::GetEnvironmentStringsW();
|
||||
if ch as usize == 0 {
|
||||
panic!("failure getting env string from OS: {}",
|
||||
io::Error::last_os_error());
|
||||
|
@ -233,13 +207,13 @@ impl StdError for JoinPathsError {
|
|||
|
||||
pub fn current_exe() -> io::Result<PathBuf> {
|
||||
super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
libc::GetModuleFileNameW(ptr::null_mut(), buf, sz)
|
||||
c::GetModuleFileNameW(ptr::null_mut(), buf, sz)
|
||||
}, super::os2path)
|
||||
}
|
||||
|
||||
pub fn getcwd() -> io::Result<PathBuf> {
|
||||
super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
libc::GetCurrentDirectoryW(sz, buf)
|
||||
c::GetCurrentDirectoryW(sz, buf)
|
||||
}, super::os2path)
|
||||
}
|
||||
|
||||
|
@ -249,23 +223,26 @@ pub fn chdir(p: &path::Path) -> io::Result<()> {
|
|||
p.push(0);
|
||||
|
||||
cvt(unsafe {
|
||||
libc::SetCurrentDirectoryW(p.as_ptr())
|
||||
c::SetCurrentDirectoryW(p.as_ptr())
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
|
||||
let k = super::to_utf16_os(k);
|
||||
let res = super::fill_utf16_buf(|buf, sz| unsafe {
|
||||
libc::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
|
||||
c::GetEnvironmentVariableW(k.as_ptr(), buf, sz)
|
||||
}, |buf| {
|
||||
OsStringExt::from_wide(buf)
|
||||
});
|
||||
match res {
|
||||
Ok(value) => Ok(Some(value)),
|
||||
Err(ref e) if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND) => {
|
||||
Ok(None)
|
||||
Err(e) => {
|
||||
if e.raw_os_error() == Some(c::ERROR_ENVVAR_NOT_FOUND as i32) {
|
||||
Ok(None)
|
||||
} else {
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -274,14 +251,14 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
|
|||
let v = super::to_utf16_os(v);
|
||||
|
||||
cvt(unsafe {
|
||||
libc::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
|
||||
c::SetEnvironmentVariableW(k.as_ptr(), v.as_ptr())
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
pub fn unsetenv(n: &OsStr) -> io::Result<()> {
|
||||
let v = super::to_utf16_os(n);
|
||||
cvt(unsafe {
|
||||
libc::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
|
||||
c::SetEnvironmentVariableW(v.as_ptr(), ptr::null())
|
||||
}).map(|_| ())
|
||||
}
|
||||
|
||||
|
@ -350,14 +327,14 @@ pub fn home_dir() -> Option<PathBuf> {
|
|||
let _handle = Handle::new(token);
|
||||
super::fill_utf16_buf(|buf, mut sz| {
|
||||
match c::GetUserProfileDirectoryW(token, buf, &mut sz) {
|
||||
0 if libc::GetLastError() != 0 => 0,
|
||||
0 if c::GetLastError() != 0 => 0,
|
||||
0 => sz,
|
||||
n => n as libc::DWORD,
|
||||
n => n as c::DWORD,
|
||||
}
|
||||
}, super::os2path).ok()
|
||||
})
|
||||
}
|
||||
|
||||
pub fn exit(code: i32) -> ! {
|
||||
unsafe { c::ExitProcess(code as libc::c_uint) }
|
||||
unsafe { c::ExitProcess(code as c::UINT) }
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
use io;
|
||||
use libc;
|
||||
use ptr;
|
||||
use sys::cvt;
|
||||
use sys::c;
|
||||
|
@ -24,8 +23,8 @@ pub struct AnonPipe {
|
|||
}
|
||||
|
||||
pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
let mut reader = libc::INVALID_HANDLE_VALUE;
|
||||
let mut writer = libc::INVALID_HANDLE_VALUE;
|
||||
let mut reader = c::INVALID_HANDLE_VALUE;
|
||||
let mut writer = c::INVALID_HANDLE_VALUE;
|
||||
try!(cvt(unsafe {
|
||||
c::CreatePipe(&mut reader, &mut writer, ptr::null_mut(), 0)
|
||||
}));
|
||||
|
@ -38,7 +37,7 @@ impl AnonPipe {
|
|||
pub fn handle(&self) -> &Handle { &self.inner }
|
||||
pub fn into_handle(self) -> Handle { self.inner }
|
||||
|
||||
pub fn raw(&self) -> libc::HANDLE { self.inner.raw() }
|
||||
pub fn raw(&self) -> c::HANDLE { self.inner.raw() }
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.inner.read(buf)
|
||||
|
|
|
@ -11,14 +11,15 @@
|
|||
#![allow(deprecated)]
|
||||
|
||||
use dynamic_lib::DynamicLibrary;
|
||||
use io;
|
||||
use io::prelude::*;
|
||||
use libc;
|
||||
use io;
|
||||
use sys::c;
|
||||
use libc::c_void;
|
||||
|
||||
use sys_common::gnu::libbacktrace;
|
||||
|
||||
pub fn print(w: &mut Write, i: isize, addr: u64, _: &DynamicLibrary, _: libc::HANDLE)
|
||||
pub fn print(w: &mut Write, i: isize, addr: u64, _: &DynamicLibrary, _: c::HANDLE)
|
||||
-> io::Result<()> {
|
||||
let addr = addr as usize as *mut libc::c_void;
|
||||
let addr = addr as usize as *mut c_void;
|
||||
libbacktrace::print(w, i, addr, addr)
|
||||
}
|
||||
|
|
|
@ -10,22 +10,23 @@
|
|||
|
||||
#![allow(deprecated)]
|
||||
|
||||
use sys_common::backtrace::{output, output_fileline};
|
||||
use ffi::CStr;
|
||||
use dynamic_lib::DynamicLibrary;
|
||||
use super::{SymFromAddrFn, SymGetLineFromAddr64Fn, SYMBOL_INFO, MAX_SYM_NAME, IMAGEHLP_LINE64};
|
||||
use io;
|
||||
use ffi::CStr;
|
||||
use io::prelude::*;
|
||||
use intrinsics;
|
||||
use libc;
|
||||
use io;
|
||||
use libc::{c_ulong, c_int, c_char, c_void};
|
||||
use mem;
|
||||
use super::{SymFromAddrFn, SymGetLineFromAddr64Fn};
|
||||
use sys::c;
|
||||
use sys_common::backtrace::{output, output_fileline};
|
||||
|
||||
pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, process: libc::HANDLE)
|
||||
-> io::Result<()> {
|
||||
pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary,
|
||||
process: c::HANDLE) -> io::Result<()> {
|
||||
let SymFromAddr = sym!(dbghelp, "SymFromAddr", SymFromAddrFn);
|
||||
let SymGetLineFromAddr64 = sym!(dbghelp, "SymGetLineFromAddr64", SymGetLineFromAddr64Fn);
|
||||
|
||||
let mut info: SYMBOL_INFO = unsafe { intrinsics::init() };
|
||||
info.MaxNameLen = MAX_SYM_NAME as libc::c_ulong;
|
||||
let mut info: c::SYMBOL_INFO = unsafe { 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.
|
||||
|
@ -34,25 +35,25 @@ pub fn print(w: &mut Write, i: isize, addr: u64, dbghelp: &DynamicLibrary, proce
|
|||
let mut displacement = 0u64;
|
||||
let ret = SymFromAddr(process, addr, &mut displacement, &mut info);
|
||||
|
||||
let name = if ret == libc::TRUE {
|
||||
let ptr = info.Name.as_ptr() as *const libc::c_char;
|
||||
let name = if ret == c::TRUE {
|
||||
let ptr = info.Name.as_ptr() as *const c_char;
|
||||
Some(unsafe { CStr::from_ptr(ptr).to_bytes() })
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
try!(output(w, i, addr as usize as *mut libc::c_void, name));
|
||||
try!(output(w, i, addr as usize as *mut c_void, name));
|
||||
|
||||
// Now find out the filename and line number
|
||||
let mut line: IMAGEHLP_LINE64 = unsafe { intrinsics::init() };
|
||||
line.SizeOfStruct = ::mem::size_of::<IMAGEHLP_LINE64>() as u32;
|
||||
let mut line: c::IMAGEHLP_LINE64 = unsafe { mem::zeroed() };
|
||||
line.SizeOfStruct = ::mem::size_of::<c::IMAGEHLP_LINE64>() as u32;
|
||||
|
||||
let mut displacement = 0u32;
|
||||
let ret = SymGetLineFromAddr64(process, addr, &mut displacement, &mut line);
|
||||
if ret == libc::TRUE {
|
||||
if ret == c::TRUE {
|
||||
output_fileline(w,
|
||||
unsafe { CStr::from_ptr(line.Filename).to_bytes() },
|
||||
line.LineNumber as libc::c_int,
|
||||
line.LineNumber as c_int,
|
||||
false)
|
||||
} else {
|
||||
Ok(())
|
||||
|
|
|
@ -19,13 +19,14 @@ use ffi::{OsString, OsStr};
|
|||
use fmt;
|
||||
use fs;
|
||||
use io::{self, Error};
|
||||
use libc::{self, c_void};
|
||||
use libc::c_void;
|
||||
use mem;
|
||||
use os::windows::ffi::OsStrExt;
|
||||
use path::Path;
|
||||
use ptr;
|
||||
use sync::StaticMutex;
|
||||
use sys::c;
|
||||
|
||||
use sys::fs::{OpenOptions, File};
|
||||
use sys::handle::{Handle, RawHandle};
|
||||
use sys::stdio;
|
||||
|
@ -107,7 +108,7 @@ pub struct Process {
|
|||
pub enum Stdio {
|
||||
Inherit,
|
||||
None,
|
||||
Raw(libc::HANDLE),
|
||||
Raw(c::HANDLE),
|
||||
}
|
||||
|
||||
pub type RawStdio = Handle;
|
||||
|
@ -118,9 +119,6 @@ impl Process {
|
|||
out_handle: Stdio,
|
||||
err_handle: Stdio) -> io::Result<Process>
|
||||
{
|
||||
use libc::{TRUE, STARTF_USESTDHANDLES};
|
||||
use libc::{DWORD, STARTUPINFO, CreateProcessW};
|
||||
|
||||
// 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.
|
||||
|
@ -143,8 +141,8 @@ impl Process {
|
|||
});
|
||||
|
||||
let mut si = zeroed_startupinfo();
|
||||
si.cb = mem::size_of::<STARTUPINFO>() as DWORD;
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.cb = mem::size_of::<c::STARTUPINFO>() as c::DWORD;
|
||||
si.dwFlags = c::STARTF_USESTDHANDLES;
|
||||
|
||||
let stdin = try!(in_handle.to_handle(c::STD_INPUT_HANDLE));
|
||||
let stdout = try!(out_handle.to_handle(c::STD_OUTPUT_HANDLE));
|
||||
|
@ -159,9 +157,9 @@ impl Process {
|
|||
cmd_str.push(0); // add null terminator
|
||||
|
||||
// stolen from the libuv code.
|
||||
let mut flags = libc::CREATE_UNICODE_ENVIRONMENT;
|
||||
let mut flags = c::CREATE_UNICODE_ENVIRONMENT;
|
||||
if cfg.detach {
|
||||
flags |= libc::DETACHED_PROCESS | libc::CREATE_NEW_PROCESS_GROUP;
|
||||
flags |= c::DETACHED_PROCESS | c::CREATE_NEW_PROCESS_GROUP;
|
||||
}
|
||||
|
||||
let (envp, _data) = make_envp(cfg.env.as_ref());
|
||||
|
@ -173,12 +171,12 @@ impl Process {
|
|||
static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
|
||||
let _lock = CREATE_PROCESS_LOCK.lock();
|
||||
|
||||
cvt(CreateProcessW(ptr::null(),
|
||||
cmd_str.as_mut_ptr(),
|
||||
ptr::null_mut(),
|
||||
ptr::null_mut(),
|
||||
TRUE, flags, envp, dirp,
|
||||
&mut si, &mut pi))
|
||||
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
|
||||
|
@ -190,7 +188,7 @@ impl Process {
|
|||
}
|
||||
|
||||
pub unsafe fn kill(&self) -> io::Result<()> {
|
||||
try!(cvt(libc::TerminateProcess(self.handle.raw(), 1)));
|
||||
try!(cvt(c::TerminateProcess(self.handle.raw(), 1)));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -201,15 +199,13 @@ impl Process {
|
|||
}
|
||||
|
||||
pub fn wait(&self) -> io::Result<ExitStatus> {
|
||||
use libc::{INFINITE, WAIT_OBJECT_0};
|
||||
use libc::{GetExitCodeProcess, WaitForSingleObject};
|
||||
|
||||
unsafe {
|
||||
if WaitForSingleObject(self.handle.raw(), INFINITE) != WAIT_OBJECT_0 {
|
||||
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;
|
||||
try!(cvt(GetExitCodeProcess(self.handle.raw(), &mut status)));
|
||||
try!(cvt(c::GetExitCodeProcess(self.handle.raw(), &mut status)));
|
||||
Ok(ExitStatus(status))
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +216,7 @@ impl Process {
|
|||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
||||
pub struct ExitStatus(libc::DWORD);
|
||||
pub struct ExitStatus(c::DWORD);
|
||||
|
||||
impl ExitStatus {
|
||||
pub fn success(&self) -> bool {
|
||||
|
@ -237,8 +233,8 @@ impl fmt::Display for ExitStatus {
|
|||
}
|
||||
}
|
||||
|
||||
fn zeroed_startupinfo() -> libc::types::os::arch::extra::STARTUPINFO {
|
||||
libc::types::os::arch::extra::STARTUPINFO {
|
||||
fn zeroed_startupinfo() -> c::STARTUPINFO {
|
||||
c::STARTUPINFO {
|
||||
cb: 0,
|
||||
lpReserved: ptr::null_mut(),
|
||||
lpDesktop: ptr::null_mut(),
|
||||
|
@ -254,14 +250,14 @@ fn zeroed_startupinfo() -> libc::types::os::arch::extra::STARTUPINFO {
|
|||
wShowWindow: 0,
|
||||
cbReserved2: 0,
|
||||
lpReserved2: ptr::null_mut(),
|
||||
hStdInput: libc::INVALID_HANDLE_VALUE,
|
||||
hStdOutput: libc::INVALID_HANDLE_VALUE,
|
||||
hStdError: libc::INVALID_HANDLE_VALUE,
|
||||
hStdInput: c::INVALID_HANDLE_VALUE,
|
||||
hStdOutput: c::INVALID_HANDLE_VALUE,
|
||||
hStdError: c::INVALID_HANDLE_VALUE,
|
||||
}
|
||||
}
|
||||
|
||||
fn zeroed_process_information() -> libc::types::os::arch::extra::PROCESS_INFORMATION {
|
||||
libc::types::os::arch::extra::PROCESS_INFORMATION {
|
||||
fn zeroed_process_information() -> c::PROCESS_INFORMATION {
|
||||
c::PROCESS_INFORMATION {
|
||||
hProcess: ptr::null_mut(),
|
||||
hThread: ptr::null_mut(),
|
||||
dwProcessId: 0,
|
||||
|
@ -353,17 +349,15 @@ fn make_dirp(d: Option<&OsString>) -> (*const u16, Vec<u16>) {
|
|||
}
|
||||
|
||||
impl Stdio {
|
||||
fn to_handle(&self, stdio_id: libc::DWORD) -> io::Result<Handle> {
|
||||
use libc::DUPLICATE_SAME_ACCESS;
|
||||
|
||||
fn to_handle(&self, stdio_id: c::DWORD) -> io::Result<Handle> {
|
||||
match *self {
|
||||
Stdio::Inherit => {
|
||||
stdio::get(stdio_id).and_then(|io| {
|
||||
io.handle().duplicate(0, true, DUPLICATE_SAME_ACCESS)
|
||||
io.handle().duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
|
||||
})
|
||||
}
|
||||
Stdio::Raw(handle) => {
|
||||
RawHandle::new(handle).duplicate(0, true, DUPLICATE_SAME_ACCESS)
|
||||
RawHandle::new(handle).duplicate(0, true, c::DUPLICATE_SAME_ACCESS)
|
||||
}
|
||||
|
||||
// Similarly to unix, we don't actually leave holes for the
|
||||
|
@ -371,9 +365,9 @@ impl Stdio {
|
|||
// equivalents. These equivalents are drawn from libuv's
|
||||
// windows process spawning.
|
||||
Stdio::None => {
|
||||
let size = mem::size_of::<libc::SECURITY_ATTRIBUTES>();
|
||||
let mut sa = libc::SECURITY_ATTRIBUTES {
|
||||
nLength: size as libc::DWORD,
|
||||
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,
|
||||
};
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use libc::{self, LONG};
|
||||
use sys_common::util::report_overflow;
|
||||
use sys::c;
|
||||
|
||||
|
@ -19,7 +18,7 @@ impl 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 libc::GetLastError() as u32 != libc::ERROR_CALL_NOT_IMPLEMENTED as u32 {
|
||||
if c::GetLastError() as u32 != c::ERROR_CALL_NOT_IMPLEMENTED as u32 {
|
||||
panic!("failed to reserve stack space for exception handling");
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +27,7 @@ impl Handler {
|
|||
}
|
||||
|
||||
extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS)
|
||||
-> LONG {
|
||||
-> c::LONG {
|
||||
unsafe {
|
||||
let rec = &(*(*ExceptionInfo).ExceptionRecord);
|
||||
let code = rec.ExceptionCode;
|
||||
|
|
|
@ -12,7 +12,6 @@ use prelude::v1::*;
|
|||
use io::prelude::*;
|
||||
|
||||
use io::{self, Cursor};
|
||||
use libc;
|
||||
use ptr;
|
||||
use str;
|
||||
use sync::Mutex;
|
||||
|
@ -34,9 +33,9 @@ pub struct Stdin {
|
|||
pub struct Stdout(Output);
|
||||
pub struct Stderr(Output);
|
||||
|
||||
pub fn get(handle: libc::DWORD) -> io::Result<Output> {
|
||||
pub fn get(handle: c::DWORD) -> io::Result<Output> {
|
||||
let handle = unsafe { c::GetStdHandle(handle) };
|
||||
if handle == libc::INVALID_HANDLE_VALUE {
|
||||
if handle == c::INVALID_HANDLE_VALUE {
|
||||
Err(io::Error::last_os_error())
|
||||
} else if handle.is_null() {
|
||||
Err(io::Error::new(io::ErrorKind::Other,
|
||||
|
@ -63,7 +62,7 @@ fn write(out: &Output, data: &[u8]) -> io::Result<usize> {
|
|||
let mut written = 0;
|
||||
try!(cvt(unsafe {
|
||||
c::WriteConsoleW(handle,
|
||||
utf16.as_ptr() as libc::LPCVOID,
|
||||
utf16.as_ptr() as c::LPCVOID,
|
||||
utf16.len() as u32,
|
||||
&mut written,
|
||||
ptr::null_mut())
|
||||
|
@ -97,7 +96,7 @@ impl Stdin {
|
|||
let mut num = 0;
|
||||
try!(cvt(unsafe {
|
||||
c::ReadConsoleW(handle,
|
||||
utf16.as_mut_ptr() as libc::LPVOID,
|
||||
utf16.as_mut_ptr() as c::LPVOID,
|
||||
utf16.len() as u32,
|
||||
&mut num,
|
||||
ptr::null_mut())
|
||||
|
@ -147,7 +146,7 @@ impl io::Write for Stderr {
|
|||
}
|
||||
|
||||
impl NoClose {
|
||||
fn new(handle: libc::HANDLE) -> NoClose {
|
||||
fn new(handle: c::HANDLE) -> NoClose {
|
||||
NoClose(Some(Handle::new(handle)))
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ use prelude::v1::*;
|
|||
|
||||
use alloc::boxed::FnBox;
|
||||
use io;
|
||||
use libc::{self, c_void, DWORD};
|
||||
use mem;
|
||||
use libc::c_void;
|
||||
use ptr;
|
||||
use sys::c;
|
||||
use sys::handle::Handle;
|
||||
|
@ -37,7 +37,7 @@ impl Thread {
|
|||
// 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 as libc::size_t,
|
||||
let ret = c::CreateThread(ptr::null_mut(), stack_size,
|
||||
thread_start, &*p as *const _ as *mut _,
|
||||
0, ptr::null_mut());
|
||||
|
||||
|
@ -48,7 +48,7 @@ impl Thread {
|
|||
Ok(Thread { handle: Handle::new(ret) })
|
||||
};
|
||||
|
||||
extern "system" fn thread_start(main: *mut libc::c_void) -> DWORD {
|
||||
extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
|
||||
unsafe { start_thread(main); }
|
||||
0
|
||||
}
|
||||
|
@ -62,8 +62,7 @@ impl Thread {
|
|||
}
|
||||
|
||||
pub fn join(self) {
|
||||
use libc::consts::os::extra::INFINITE;
|
||||
unsafe { c::WaitForSingleObject(self.handle.raw(), INFINITE); }
|
||||
unsafe { c::WaitForSingleObject(self.handle.raw(), c::INFINITE); }
|
||||
}
|
||||
|
||||
pub fn yield_now() {
|
||||
|
|
|
@ -10,13 +10,12 @@
|
|||
|
||||
use prelude::v1::*;
|
||||
|
||||
use libc::types::os::arch::extra::{DWORD, LPVOID, BOOL};
|
||||
|
||||
use ptr;
|
||||
use sys_common;
|
||||
use sys::c;
|
||||
use sys_common::mutex::Mutex;
|
||||
use sys_common;
|
||||
|
||||
pub type Key = DWORD;
|
||||
pub type Key = c::DWORD;
|
||||
pub type Dtor = unsafe extern fn(*mut u8);
|
||||
|
||||
// Turns out, like pretty much everything, Windows is pretty close the
|
||||
|
@ -68,9 +67,8 @@ static mut DTORS: *mut Vec<(Key, Dtor)> = ptr::null_mut();
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn create(dtor: Option<Dtor>) -> Key {
|
||||
const TLS_OUT_OF_INDEXES: DWORD = 0xFFFFFFFF;
|
||||
let key = TlsAlloc();
|
||||
assert!(key != TLS_OUT_OF_INDEXES);
|
||||
let key = c::TlsAlloc();
|
||||
assert!(key != c::TLS_OUT_OF_INDEXES);
|
||||
match dtor {
|
||||
Some(f) => register_dtor(key, f),
|
||||
None => {}
|
||||
|
@ -80,13 +78,13 @@ pub unsafe fn create(dtor: Option<Dtor>) -> Key {
|
|||
|
||||
#[inline]
|
||||
pub unsafe fn set(key: Key, value: *mut u8) {
|
||||
let r = TlsSetValue(key, value as LPVOID);
|
||||
let r = c::TlsSetValue(key, value as c::LPVOID);
|
||||
debug_assert!(r != 0);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn get(key: Key) -> *mut u8 {
|
||||
TlsGetValue(key) as *mut u8
|
||||
c::TlsGetValue(key) as *mut u8
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -107,18 +105,11 @@ pub unsafe fn destroy(key: Key) {
|
|||
// Note that source [2] above shows precedent for this sort
|
||||
// of strategy.
|
||||
} else {
|
||||
let r = TlsFree(key);
|
||||
let r = c::TlsFree(key);
|
||||
debug_assert!(r != 0);
|
||||
}
|
||||
}
|
||||
|
||||
extern "system" {
|
||||
fn TlsAlloc() -> DWORD;
|
||||
fn TlsFree(dwTlsIndex: DWORD) -> BOOL;
|
||||
fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
|
||||
fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Dtor registration
|
||||
//
|
||||
|
@ -243,17 +234,15 @@ unsafe fn unregister_dtor(key: Key) -> bool {
|
|||
#[link_section = ".CRT$XLB"]
|
||||
#[linkage = "external"]
|
||||
#[allow(warnings)]
|
||||
pub static p_thread_callback: unsafe extern "system" fn(LPVOID, DWORD,
|
||||
LPVOID) =
|
||||
pub static p_thread_callback: unsafe extern "system" fn(c::LPVOID, c::DWORD,
|
||||
c::LPVOID) =
|
||||
on_tls_callback;
|
||||
|
||||
#[allow(warnings)]
|
||||
unsafe extern "system" fn on_tls_callback(h: LPVOID,
|
||||
dwReason: DWORD,
|
||||
pv: LPVOID) {
|
||||
const DLL_THREAD_DETACH: DWORD = 3;
|
||||
const DLL_PROCESS_DETACH: DWORD = 0;
|
||||
if dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -286,9 +275,9 @@ unsafe fn run_dtors() {
|
|||
ret
|
||||
};
|
||||
for &(key, dtor) in &dtors {
|
||||
let ptr = TlsGetValue(key);
|
||||
let ptr = c::TlsGetValue(key);
|
||||
if !ptr.is_null() {
|
||||
TlsSetValue(key, ptr::null_mut());
|
||||
c::TlsSetValue(key, ptr::null_mut());
|
||||
dtor(ptr as *mut _);
|
||||
any_run = true;
|
||||
}
|
||||
|
|
|
@ -7,32 +7,33 @@
|
|||
// <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 libc;
|
||||
|
||||
use ops::Sub;
|
||||
use time::Duration;
|
||||
use sync::Once;
|
||||
use sys::c;
|
||||
use time::Duration;
|
||||
|
||||
const NANOS_PER_SEC: u64 = 1_000_000_000;
|
||||
|
||||
pub struct SteadyTime {
|
||||
t: libc::LARGE_INTEGER,
|
||||
t: c::LARGE_INTEGER,
|
||||
}
|
||||
|
||||
impl SteadyTime {
|
||||
pub fn now() -> SteadyTime {
|
||||
let mut t = SteadyTime { t: 0 };
|
||||
unsafe { libc::QueryPerformanceCounter(&mut t.t); }
|
||||
unsafe { c::QueryPerformanceCounter(&mut t.t); }
|
||||
t
|
||||
}
|
||||
}
|
||||
|
||||
fn frequency() -> libc::LARGE_INTEGER {
|
||||
static mut FREQUENCY: libc::LARGE_INTEGER = 0;
|
||||
fn frequency() -> c::LARGE_INTEGER {
|
||||
static mut FREQUENCY: c::LARGE_INTEGER = 0;
|
||||
static ONCE: Once = Once::new();
|
||||
|
||||
unsafe {
|
||||
ONCE.call_once(|| {
|
||||
libc::QueryPerformanceFrequency(&mut FREQUENCY);
|
||||
c::QueryPerformanceFrequency(&mut FREQUENCY);
|
||||
});
|
||||
FREQUENCY
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ use std::{cmp, error, fmt};
|
|||
use std::io::prelude::*;
|
||||
use std::io;
|
||||
use term::{self, WriterWrapper};
|
||||
use libc;
|
||||
|
||||
/// maximum number of lines we will print for each error; arbitrary.
|
||||
const MAX_LINES: usize = 6;
|
||||
|
@ -767,15 +766,19 @@ impl EmitterWriter {
|
|||
|
||||
#[cfg(unix)]
|
||||
fn stderr_isatty() -> bool {
|
||||
use libc;
|
||||
unsafe { libc::isatty(libc::STDERR_FILENO) != 0 }
|
||||
}
|
||||
#[cfg(windows)]
|
||||
fn stderr_isatty() -> bool {
|
||||
const STD_ERROR_HANDLE: libc::DWORD = -12i32 as libc::DWORD;
|
||||
type DWORD = u32;
|
||||
type BOOL = i32;
|
||||
type HANDLE = *mut u8;
|
||||
const STD_ERROR_HANDLE: DWORD = -12i32 as DWORD;
|
||||
extern "system" {
|
||||
fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
||||
fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
|
||||
lpMode: libc::LPDWORD) -> libc::BOOL;
|
||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||
fn GetConsoleMode(hConsoleHandle: HANDLE,
|
||||
lpMode: *mut DWORD) -> BOOL;
|
||||
}
|
||||
unsafe {
|
||||
let handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
|
|
|
@ -30,12 +30,17 @@ pub struct WinConsole<T> {
|
|||
background: color::Color,
|
||||
}
|
||||
|
||||
type WORD = u16;
|
||||
type DWORD = u32;
|
||||
type BOOL = i32;
|
||||
type HANDLE = *mut u8;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[repr(C)]
|
||||
struct CONSOLE_SCREEN_BUFFER_INFO {
|
||||
dwSize: [libc::c_short; 2],
|
||||
dwCursorPosition: [libc::c_short; 2],
|
||||
wAttributes: libc::WORD,
|
||||
wAttributes: WORD,
|
||||
srWindow: [libc::c_short; 4],
|
||||
dwMaximumWindowSize: [libc::c_short; 2],
|
||||
}
|
||||
|
@ -43,10 +48,10 @@ struct CONSOLE_SCREEN_BUFFER_INFO {
|
|||
#[allow(non_snake_case)]
|
||||
#[link(name = "kernel32")]
|
||||
extern "system" {
|
||||
fn SetConsoleTextAttribute(handle: libc::HANDLE, attr: libc::WORD) -> libc::BOOL;
|
||||
fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
||||
fn GetConsoleScreenBufferInfo(handle: libc::HANDLE,
|
||||
info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> libc::BOOL;
|
||||
fn SetConsoleTextAttribute(handle: HANDLE, attr: WORD) -> BOOL;
|
||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||
fn GetConsoleScreenBufferInfo(handle: HANDLE,
|
||||
info: *mut CONSOLE_SCREEN_BUFFER_INFO) -> BOOL;
|
||||
}
|
||||
|
||||
fn color_to_bits(color: color::Color) -> u16 {
|
||||
|
@ -90,7 +95,7 @@ fn bits_to_color(bits: u16) -> color::Color {
|
|||
impl<T: Write+Send+'static> WinConsole<T> {
|
||||
fn apply(&mut self) {
|
||||
let _unused = self.buf.flush();
|
||||
let mut accum: libc::WORD = 0;
|
||||
let mut accum: WORD = 0;
|
||||
accum |= color_to_bits(self.foreground);
|
||||
accum |= color_to_bits(self.background) << 4;
|
||||
|
||||
|
@ -104,7 +109,7 @@ impl<T: Write+Send+'static> WinConsole<T> {
|
|||
// terminal! Admittedly, this is fragile, since stderr could be
|
||||
// redirected to a different console. This is good enough for
|
||||
// rustc though. See #13400.
|
||||
let out = GetStdHandle(-11i32 as libc::DWORD);
|
||||
let out = GetStdHandle(-11i32 as DWORD);
|
||||
SetConsoleTextAttribute(out, accum);
|
||||
}
|
||||
}
|
||||
|
@ -116,7 +121,7 @@ impl<T: Write+Send+'static> WinConsole<T> {
|
|||
let bg;
|
||||
unsafe {
|
||||
let mut buffer_info = ::std::mem::uninitialized();
|
||||
if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as libc::DWORD),
|
||||
if GetConsoleScreenBufferInfo(GetStdHandle(-11i32 as DWORD),
|
||||
&mut buffer_info) != 0 {
|
||||
fg = bits_to_color(buffer_info.wAttributes);
|
||||
bg = bits_to_color(buffer_info.wAttributes >> 4);
|
||||
|
|
|
@ -777,11 +777,14 @@ fn stdout_isatty() -> bool {
|
|||
}
|
||||
#[cfg(windows)]
|
||||
fn stdout_isatty() -> bool {
|
||||
const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
|
||||
type DWORD = u32;
|
||||
type BOOL = i32;
|
||||
type HANDLE = *mut u8;
|
||||
type LPDWORD = *mut u32;
|
||||
const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
|
||||
extern "system" {
|
||||
fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
||||
fn GetConsoleMode(hConsoleHandle: libc::HANDLE,
|
||||
lpMode: libc::LPDWORD) -> libc::BOOL;
|
||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||
fn GetConsoleMode(hConsoleHandle: HANDLE, lpMode: LPDWORD) -> BOOL;
|
||||
}
|
||||
unsafe {
|
||||
let handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
@ -882,10 +885,28 @@ fn get_concurrency() -> usize {
|
|||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
#[allow(bad_style)]
|
||||
fn num_cpus() -> usize {
|
||||
#[repr(C)]
|
||||
struct SYSTEM_INFO {
|
||||
wProcessorArchitecture: u16,
|
||||
wReserved: u16,
|
||||
dwPageSize: u32,
|
||||
lpMinimumApplicationAddress: *mut u8,
|
||||
lpMaximumApplicationAddress: *mut u8,
|
||||
dwActiveProcessorMask: *mut u8,
|
||||
dwNumberOfProcessors: u32,
|
||||
dwProcessorType: u32,
|
||||
dwAllocationGranularity: u32,
|
||||
wProcessorLevel: u16,
|
||||
wProcessorRevision: u16,
|
||||
}
|
||||
extern "system" {
|
||||
fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32;
|
||||
}
|
||||
unsafe {
|
||||
let mut sysinfo = std::mem::zeroed();
|
||||
libc::GetSystemInfo(&mut sysinfo);
|
||||
GetSystemInfo(&mut sysinfo);
|
||||
sysinfo.dwNumberOfProcessors as usize
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,9 @@ extern crate libc;
|
|||
|
||||
#[cfg(windows)]
|
||||
mod imp {
|
||||
use libc::{c_void, LPVOID, DWORD};
|
||||
use libc::types::os::arch::extra::LPWSTR;
|
||||
type LPVOID = *mut u8;
|
||||
type DWORD = u32;
|
||||
type LPWSTR = *mut u16;
|
||||
|
||||
extern "system" {
|
||||
fn FormatMessageW(flags: DWORD,
|
||||
|
@ -24,15 +25,15 @@ mod imp {
|
|||
langId: DWORD,
|
||||
buf: LPWSTR,
|
||||
nsize: DWORD,
|
||||
args: *const c_void)
|
||||
args: *const u8)
|
||||
-> DWORD;
|
||||
}
|
||||
|
||||
pub fn test() {
|
||||
let mut buf: [u16; 50] = [0; 50];
|
||||
let ret = unsafe {
|
||||
FormatMessageW(0x1000, 0 as *mut c_void, 1, 0x400,
|
||||
buf.as_mut_ptr(), buf.len() as u32, 0 as *const c_void)
|
||||
FormatMessageW(0x1000, 0 as *mut _, 1, 0x400,
|
||||
buf.as_mut_ptr(), buf.len() as u32, 0 as *const _)
|
||||
};
|
||||
// On some 32-bit Windowses (Win7-8 at least) this will panic with segmented
|
||||
// stacks taking control of pvArbitrary
|
||||
|
|
|
@ -11,15 +11,19 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
type DWORD = u32;
|
||||
type HANDLE = *mut u8;
|
||||
type BOOL = i32;
|
||||
|
||||
#[cfg(windows)]
|
||||
extern "system" {
|
||||
fn SetStdHandle(nStdHandle: libc::DWORD, nHandle: libc::HANDLE) -> libc::BOOL;
|
||||
fn SetStdHandle(nStdHandle: DWORD, nHandle: HANDLE) -> BOOL;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn close_stdout() {
|
||||
const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
|
||||
unsafe { SetStdHandle(STD_OUTPUT_HANDLE, 0 as libc::HANDLE); }
|
||||
const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
|
||||
unsafe { SetStdHandle(STD_OUTPUT_HANDLE, 0 as HANDLE); }
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
|
|
|
@ -11,20 +11,24 @@
|
|||
|
||||
extern crate libc;
|
||||
|
||||
type DWORD = u32;
|
||||
type HANDLE = *mut u8;
|
||||
|
||||
#[cfg(windows)]
|
||||
extern "system" {
|
||||
pub fn GetStdHandle(which: libc::DWORD) -> libc::HANDLE;
|
||||
fn GetStdHandle(which: DWORD) -> HANDLE;
|
||||
fn CloseHandle(handle: HANDLE) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn close_stdout() {
|
||||
const STD_OUTPUT_HANDLE: libc::DWORD = -11i32 as libc::DWORD;
|
||||
unsafe { libc::CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)); }
|
||||
const STD_OUTPUT_HANDLE: DWORD = -11i32 as DWORD;
|
||||
unsafe { CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE)); }
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn close_stdout() {
|
||||
unsafe { libc::close(libc::STDOUT_FILENO); }
|
||||
unsafe { libc::close(1); }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -15,8 +15,6 @@ extern crate libc;
|
|||
|
||||
use std::process::Command;
|
||||
|
||||
use libc::funcs::posix88::unistd;
|
||||
|
||||
// The output from "ps -A -o pid,ppid,args" should look like this:
|
||||
// PID PPID COMMAND
|
||||
// 1 0 /sbin/init
|
||||
|
@ -34,7 +32,7 @@ use libc::funcs::posix88::unistd;
|
|||
|
||||
#[cfg(unix)]
|
||||
fn find_zombies() {
|
||||
let my_pid = unsafe { unistd::getpid() };
|
||||
let my_pid = unsafe { libc::getpid() };
|
||||
|
||||
// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
|
||||
let ps_cmd_output = Command::new("ps").args(&["-A", "-o", "pid,ppid,args"]).output().unwrap();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue