1
Fork 0

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:
Alex Crichton 2015-11-02 16:23:22 -08:00
parent c8a29c2092
commit 3d28b8b98e
62 changed files with 1889 additions and 2431 deletions

View file

@ -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

View file

@ -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

View file

@ -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):

View file

@ -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",

View file

@ -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;

View file

@ -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]

View file

@ -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;

View file

@ -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]

View file

@ -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__ {}

View file

@ -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 }
}
}
}

View file

@ -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);
}
}

View file

@ -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),

View file

@ -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;

View file

@ -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)
}
}
}

View file

@ -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 }
}
}

View file

@ -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;

View file

@ -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,7 +299,7 @@ mod imp {
}
fn fill_bytes(&mut self, v: &mut [u8]) {
let ret = unsafe {
CryptGenRandom(self.hcryptprov, v.len() as DWORD,
c::CryptGenRandom(self.hcryptprov, v.len() as c::DWORD,
v.as_mut_ptr())
};
if ret == 0 {
@ -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: {}",

View file

@ -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

View file

@ -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,7 +119,7 @@ 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(),
try!(cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
&mut res)));
Ok(LookupHost { original: res, cur: res })
}
@ -136,25 +129,17 @@ 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,
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,7 +197,7 @@ impl TcpStream {
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
let ret = try!(cvt(unsafe {
libc::send(*self.inner.as_inner(),
c::send(*self.inner.as_inner(),
buf.as_ptr() as *const c_void,
buf.len() as wrlen_t,
0)
@ -222,26 +207,18 @@ impl TcpStream {
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,16 +349,16 @@ 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(),
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)
@ -392,7 +369,7 @@ 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(),
c::sendto(*self.inner.as_inner(),
buf.as_ptr() as *const c_void, buf.len() as wrlen_t,
0, dstp, dstlen)
}));
@ -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)
}
}

View file

@ -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;
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

View file

@ -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,
&params 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,
&params 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,
c::RtlUnwindEx(establisherFrame,
lpad as c::LPVOID,
exceptionRecord,
er.ExceptionInformation[0] as LPVOID, // pointer to PanicData
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,
&params 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,
&params 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,

View file

@ -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,
}
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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())
}

View file

@ -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

View file

@ -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);
}
}

View file

@ -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 {

View file

@ -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,16 +468,16 @@ 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(),
match libc::getpwuid_r(me, &mut passwd, buf.as_mut_ptr(),
buf.capacity() as libc::size_t,
&mut result) {
0 if !result.is_null() => {}

View file

@ -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,
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

View file

@ -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);

View file

@ -43,11 +43,11 @@ mod imp {
use sys_common::util::report_overflow;
use mem;
use ptr;
use sys::c::{siginfo, sigaction, SIGBUS, SIG_DFL,
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;

View file

@ -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;
}

View file

@ -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,
let ret = libc::pthread_create(&mut native, &attr, thread_start,
&*p as *const _ as *mut _);
assert_eq!(pthread_attr_destroy(&mut attr), 0);
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,38 +102,26 @@ 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(),
libc::pthread_setname_np(libc::pthread_self(), cname.as_ptr(),
carg.as_ptr() as *mut libc::c_void);
}
}
@ -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,
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;
}

View file

@ -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;
}

View file

@ -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
}

View file

@ -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 {
pub fn init_frame(frame: &mut c::STACKFRAME64,
ctx: &c::CONTEXT) -> c::DWORD {
frame.AddrPC.Offset = ctx.Eip as u64;
frame.AddrPC.Mode = super::ADDRESS_MODE::AddrModeFlat;
frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
frame.AddrStack.Offset = ctx.Esp as u64;
frame.AddrStack.Mode = super::ADDRESS_MODE::AddrModeFlat;
frame.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
frame.AddrFrame.Offset = ctx.Ebp as u64;
frame.AddrFrame.Mode = super::ADDRESS_MODE::AddrModeFlat;
super::IMAGE_FILE_MACHINE_I386
}
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 {
pub fn init_frame(frame: &mut c::STACKFRAME64,
ctx: &c::CONTEXT) -> c::DWORD {
frame.AddrPC.Offset = ctx.Rip as u64;
frame.AddrPC.Mode = super::ADDRESS_MODE::AddrModeFlat;
frame.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
frame.AddrStack.Offset = ctx.Rsp as u64;
frame.AddrStack.Mode = super::ADDRESS_MODE::AddrModeFlat;
frame.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
frame.AddrFrame.Offset = ctx.Rbp as u64;
frame.AddrFrame.Mode = super::ADDRESS_MODE::AddrModeFlat;
super::IMAGE_FILE_MACHINE_AMD64
}
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

View file

@ -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),
}

View file

@ -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

View file

@ -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))
}
}

View file

@ -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,7 +228,7 @@ 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(),
c::CreateFileW(path.as_ptr(),
opts.get_desired_access(),
opts.get_share_mode(),
opts.security_attributes as *mut _,
@ -238,7 +236,7 @@ impl File {
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,14 +302,14 @@ 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,
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)
}

View file

@ -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))

View file

@ -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)
}

View file

@ -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

View file

@ -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,51 +28,26 @@ 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,
let res = c::FormatMessageW(c::FORMAT_MESSAGE_FROM_SYSTEM |
c::FORMAT_MESSAGE_IGNORE_INSERTS,
ptr::null_mut(),
errnum as DWORD,
errnum as c::DWORD,
langId,
buf.as_mut_ptr(),
buf.len() as DWORD,
buf.len() as c::DWORD,
ptr::null()) as usize;
if res == 0 {
// Sometimes FormatMessageW can fail e.g. system doesn't like langId,
@ -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) => {
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) }
}

View file

@ -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)

View file

@ -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)
}

View file

@ -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(())

View file

@ -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,11 +171,11 @@ impl Process {
static CREATE_PROCESS_LOCK: StaticMutex = StaticMutex::new();
let _lock = CREATE_PROCESS_LOCK.lock();
cvt(CreateProcessW(ptr::null(),
cvt(c::CreateProcessW(ptr::null(),
cmd_str.as_mut_ptr(),
ptr::null_mut(),
ptr::null_mut(),
TRUE, flags, envp, dirp,
c::TRUE, flags, envp, dirp,
&mut si, &mut pi))
});
@ -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,
};

View file

@ -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;

View file

@ -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)))
}

View file

@ -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() {

View file

@ -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;
}

View file

@ -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
}

View file

@ -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);

View file

@ -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);

View file

@ -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
}
}

View file

@ -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

View file

@ -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)]

View file

@ -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() {

View file

@ -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();