Large diffs are not rendered by default.

Oops, something went wrong.
@@ -57,6 +57,8 @@

#![unstable(feature = "rand", issue = "0")]

use sys::rand as sys;

use cell::RefCell;
use io;
use mem;
@@ -70,7 +72,6 @@ use core_rand::Isaac64Rng as IsaacWordRng;
pub use core_rand::{Rand, Rng, SeedableRng};
pub use core_rand::{XorShiftRng, IsaacRng, Isaac64Rng};
pub use core_rand::reseeding;
pub use rand::os::OsRng;

pub mod os;
pub mod reader;
@@ -95,7 +96,7 @@ impl StdRng {
/// Reading the randomness from the OS may fail, and any error is
/// propagated via the `io::Result` return value.
pub fn new() -> io::Result<StdRng> {
OsRng::new().map(|mut r| StdRng { rng: r.gen() })
sys::OsRng::new().map(|mut r| StdRng { rng: r.gen() }).map_err(From::from)
}
}

@@ -11,337 +11,7 @@
//! Interfaces to the operating system provided random number
//! generators.

pub use self::imp::OsRng;

#[cfg(all(unix, not(target_os = "ios")))]
mod imp {
use self::OsRngInner::*;

use fs::File;
use io;
use libc;
use mem;
use rand::Rng;
use rand::reader::ReaderRng;
use sys::os::errno;

#[cfg(all(target_os = "linux",
any(target_arch = "x86_64",
target_arch = "x86",
target_arch = "arm",
target_arch = "aarch64",
target_arch = "powerpc")))]
fn getrandom(buf: &mut [u8]) -> libc::c_long {
extern "C" {
fn syscall(number: libc::c_long, ...) -> libc::c_long;
}

#[cfg(target_arch = "x86_64")]
const NR_GETRANDOM: libc::c_long = 318;
#[cfg(target_arch = "x86")]
const NR_GETRANDOM: libc::c_long = 355;
#[cfg(any(target_arch = "arm", target_arch = "powerpc"))]
const NR_GETRANDOM: libc::c_long = 384;
#[cfg(any(target_arch = "aarch64"))]
const NR_GETRANDOM: libc::c_long = 278;

unsafe {
syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), 0)
}
}

#[cfg(not(all(target_os = "linux",
any(target_arch = "x86_64",
target_arch = "x86",
target_arch = "arm",
target_arch = "aarch64",
target_arch = "powerpc"))))]
fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }

fn getrandom_fill_bytes(v: &mut [u8]) {
let mut read = 0;
let len = v.len();
while read < len {
let result = getrandom(&mut v[read..]);
if result == -1 {
let err = errno() as libc::c_int;
if err == libc::EINTR {
continue;
} else {
panic!("unexpected getrandom error: {}", err);
}
} else {
read += result as usize;
}
}
}

fn getrandom_next_u32() -> u32 {
let mut buf: [u8; 4] = [0; 4];
getrandom_fill_bytes(&mut buf);
unsafe { mem::transmute::<[u8; 4], u32>(buf) }
}

fn getrandom_next_u64() -> u64 {
let mut buf: [u8; 8] = [0; 8];
getrandom_fill_bytes(&mut buf);
unsafe { mem::transmute::<[u8; 8], u64>(buf) }
}

#[cfg(all(target_os = "linux",
any(target_arch = "x86_64",
target_arch = "x86",
target_arch = "arm",
target_arch = "aarch64",
target_arch = "powerpc")))]
fn is_getrandom_available() -> bool {
use sync::atomic::{AtomicBool, Ordering};
use sync::Once;

static CHECKER: Once = Once::new();
static AVAILABLE: AtomicBool = AtomicBool::new(false);

CHECKER.call_once(|| {
let mut buf: [u8; 0] = [];
let result = getrandom(&mut buf);
let available = if result == -1 {
let err = io::Error::last_os_error().raw_os_error();
err != Some(libc::ENOSYS)
} else {
true
};
AVAILABLE.store(available, Ordering::Relaxed);
});

AVAILABLE.load(Ordering::Relaxed)
}

#[cfg(not(all(target_os = "linux",
any(target_arch = "x86_64",
target_arch = "x86",
target_arch = "arm",
target_arch = "aarch64",
target_arch = "powerpc"))))]
fn is_getrandom_available() -> bool { false }

/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
///
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
/// `/dev/urandom`, or from `getrandom(2)` system call if available.
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
/// service provider with the `PROV_RSA_FULL` type.
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
///
/// This does not block.
pub struct OsRng {
inner: OsRngInner,
}

enum OsRngInner {
OsGetrandomRng,
OsReaderRng(ReaderRng<File>),
}

impl OsRng {
/// Create a new `OsRng`.
pub fn new() -> io::Result<OsRng> {
if is_getrandom_available() {
return Ok(OsRng { inner: OsGetrandomRng });
}

let reader = try!(File::open("/dev/urandom"));
let reader_rng = ReaderRng::new(reader);

Ok(OsRng { inner: OsReaderRng(reader_rng) })
}
}

impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
match self.inner {
OsGetrandomRng => getrandom_next_u32(),
OsReaderRng(ref mut rng) => rng.next_u32(),
}
}
fn next_u64(&mut self) -> u64 {
match self.inner {
OsGetrandomRng => getrandom_next_u64(),
OsReaderRng(ref mut rng) => rng.next_u64(),
}
}
fn fill_bytes(&mut self, v: &mut [u8]) {
match self.inner {
OsGetrandomRng => getrandom_fill_bytes(v),
OsReaderRng(ref mut rng) => rng.fill_bytes(v)
}
}
}
}

#[cfg(target_os = "ios")]
mod imp {
#[cfg(stage0)] use prelude::v1::*;

use io;
use mem;
use ptr;
use rand::Rng;
use libc::{c_int, size_t};

/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
///
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
/// `/dev/urandom`, or from `getrandom(2)` system call if available.
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
/// service provider with the `PROV_RSA_FULL` type.
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
///
/// This does not block.
pub struct OsRng {
// dummy field to ensure that this struct cannot be constructed outside
// of this module
_dummy: (),
}

enum SecRandom {}

#[allow(non_upper_case_globals)]
const kSecRandomDefault: *const SecRandom = ptr::null();

#[link(name = "Security", kind = "framework")]
extern "C" {
fn SecRandomCopyBytes(rnd: *const SecRandom,
count: size_t, bytes: *mut u8) -> c_int;
}

impl OsRng {
/// Create a new `OsRng`.
pub fn new() -> io::Result<OsRng> {
Ok(OsRng { _dummy: () })
}
}

impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
let mut v = [0; 4];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn next_u64(&mut self) -> u64 {
let mut v = [0; 8];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn fill_bytes(&mut self, v: &mut [u8]) {
let ret = unsafe {
SecRandomCopyBytes(kSecRandomDefault, v.len() as size_t,
v.as_mut_ptr())
};
if ret == -1 {
panic!("couldn't generate random bytes: {}",
io::Error::last_os_error());
}
}
}
}

#[cfg(windows)]
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;

/// A random number generator that retrieves randomness straight from
/// the operating system. Platform sources:
///
/// - Unix-like systems (Linux, Android, Mac OSX): read directly from
/// `/dev/urandom`, or from `getrandom(2)` system call if available.
/// - Windows: calls `CryptGenRandom`, using the default cryptographic
/// service provider with the `PROV_RSA_FULL` type.
/// - iOS: calls SecRandomCopyBytes as /dev/(u)random is sandboxed.
///
/// 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;
}

impl OsRng {
/// Create a new `OsRng`.
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)
};

if ret == 0 {
Err(io::Error::last_os_error())
} else {
Ok(OsRng { hcryptprov: hcp })
}
}
}

impl Rng for OsRng {
fn next_u32(&mut self) -> u32 {
let mut v = [0; 4];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn next_u64(&mut self) -> u64 {
let mut v = [0; 8];
self.fill_bytes(&mut v);
unsafe { mem::transmute(v) }
}
fn fill_bytes(&mut self, v: &mut [u8]) {
let ret = unsafe {
CryptGenRandom(self.hcryptprov, v.len() as DWORD,
v.as_mut_ptr())
};
if ret == 0 {
panic!("couldn't generate random bytes: {}",
io::Error::last_os_error());
}
}
}

impl Drop for OsRng {
fn drop(&mut self) {
let ret = unsafe {
CryptReleaseContext(self.hcryptprov, 0)
};
if ret == 0 {
panic!("couldn't release context: {}",
io::Error::last_os_error());
}
}
}
}
pub use sys::rand::OsRng;

#[cfg(test)]
mod tests {

This file was deleted.

Oops, something went wrong.
@@ -10,12 +10,12 @@

use prelude::v1::*;

use sys::sync as sys;

use sys::time::*;
use sync::atomic::{AtomicUsize, Ordering};
use sync::{mutex, MutexGuard, PoisonError};
use sys_common::condvar as sys;
use sys_common::mutex as sys_mutex;
use sys_common::poison::{self, LockResult};
use sys::time::SteadyTime;
use sync::poison::{self, LockResult};
use time::Duration;

/// A type indicating whether a timed wait on a condition variable returned
@@ -228,7 +228,7 @@ impl Condvar {
///
/// To wake up all threads, see `notify_all()`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
pub fn notify_one(&self) { unsafe { sys::Condvar::notify_one(&self.inner.inner) } }

/// Wakes up all blocked threads on this condvar.
///
@@ -238,13 +238,13 @@ impl Condvar {
///
/// To wake up only one thread, see `notify_one()`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
pub fn notify_all(&self) { unsafe { sys::Condvar::notify_all(&self.inner.inner) } }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Drop for Condvar {
fn drop(&mut self) {
unsafe { self.inner.inner.destroy() }
unsafe { sys::Condvar::destroy(&self.inner.inner) }
}
}

@@ -272,7 +272,7 @@ impl StaticCondvar {
let poisoned = unsafe {
let lock = mutex::guard_lock(&guard);
self.verify(lock);
self.inner.wait(lock);
sys::Condvar::wait(&self.inner, &lock);
mutex::guard_poison(&guard).get()
};
if poisoned {
@@ -314,7 +314,7 @@ impl StaticCondvar {
let (poisoned, result) = unsafe {
let lock = mutex::guard_lock(&guard);
self.verify(lock);
let success = self.inner.wait_timeout(lock, timeout);
let success = sys::Condvar::wait_timeout(&self.inner, lock, timeout);
(mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
};
if poisoned {
@@ -342,14 +342,14 @@ impl StaticCondvar {
where F: FnMut(LockResult<&mut T>) -> bool {
// This could be made more efficient by pushing the implementation into
// sys::condvar
let start = SteadyTime::now();
let start = SteadyTime::now().unwrap();
let mut guard_result: LockResult<MutexGuard<'a, T>> = Ok(guard);
while !f(guard_result
.as_mut()
.map(|g| &mut **g)
.map_err(|e| PoisonError::new(&mut **e.get_mut()))) {
let now = SteadyTime::now();
let consumed = &now - &start;
let now = SteadyTime::now().unwrap();
let consumed = now.delta(&start);
let guard = guard_result.unwrap_or_else(|e| e.into_inner());
let (new_guard_result, timed_out) = if consumed > dur {
(Ok(guard), WaitTimeoutResult(true))
@@ -382,15 +382,15 @@ impl StaticCondvar {
#[unstable(feature = "static_condvar",
reason = "may be merged with Condvar in the future",
issue = "27717")]
pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
pub fn notify_one(&'static self) { unsafe { sys::Condvar::notify_one(&self.inner) } }

/// Wakes up all blocked threads on this condvar.
///
/// See `Condvar::notify_all`.
#[unstable(feature = "static_condvar",
reason = "may be merged with Condvar in the future",
issue = "27717")]
pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
pub fn notify_all(&'static self) { unsafe { sys::Condvar::notify_all(&self.inner) } }

/// Deallocates all resources associated with this static condvar.
///
@@ -402,10 +402,10 @@ impl StaticCondvar {
reason = "may be merged with Condvar in the future",
issue = "27717")]
pub unsafe fn destroy(&'static self) {
self.inner.destroy()
sys::Condvar::destroy(&self.inner)
}

fn verify(&self, mutex: &sys_mutex::Mutex) {
fn verify(&self, mutex: &sys::Mutex) {
let addr = mutex as *const _ as usize;
match self.mutex.compare_and_swap(0, addr, Ordering::SeqCst) {
// If we got out 0, then we have successfully bound the mutex to
@@ -19,13 +19,13 @@

pub use alloc::arc::{Arc, Weak};
pub use core::sync::atomic;

pub use self::barrier::{Barrier, BarrierWaitResult};
pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
pub use self::mutex::MUTEX_INIT;
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
pub use self::remutex::{ReentrantMutex, ReentrantMutexGuard};
pub use self::once::{Once, ONCE_INIT};
pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
pub use self::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
pub use self::semaphore::{Semaphore, SemaphoreGuard};
@@ -35,6 +35,8 @@ pub mod mpsc;
mod barrier;
mod condvar;
mod mutex;
mod remutex;
mod once;
mod poison;
mod rwlock;
mod semaphore;
@@ -10,14 +10,15 @@

use prelude::v1::*;

use sys::sync as sys;

use cell::UnsafeCell;
use fmt;
use marker;
use mem;
use ops::{Deref, DerefMut};
use ptr;
use sys_common::mutex as sys;
use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
use sync::poison::{self, TryLockError, TryLockResult, LockResult};

/// A mutual exclusion primitive useful for protecting shared data
///
@@ -8,11 +8,11 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use sys::unwind;
use cell::Cell;
use error::{Error};
use fmt;
use marker::Reflect;
use thread;

pub struct Flag { failed: Cell<bool> }

@@ -28,7 +28,7 @@ impl Flag {

#[inline]
pub fn borrow(&self) -> LockResult<Guard> {
let ret = Guard { panicking: thread::panicking() };
let ret = Guard { panicking: unwind::is_panicking() };
if self.get() {
Err(PoisonError::new(ret))
} else {
@@ -38,7 +38,7 @@ impl Flag {

#[inline]
pub fn done(&self, guard: &Guard) {
if !guard.panicking && thread::panicking() {
if !guard.panicking && unwind::is_panicking() {
self.failed.set(true);
}
}
@@ -13,11 +13,12 @@

use prelude::v1::*;

use sys::sync as sys;

use fmt;
use marker;
use ops::Deref;
use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
use sys::mutex as sys;
use sync::poison::{self, TryLockError, TryLockResult, LockResult};

/// A re-entrant mutual exclusion
///
@@ -62,7 +63,7 @@ impl<T> ReentrantMutex<T> {
pub fn new(t: T) -> ReentrantMutex<T> {
unsafe {
let mut mutex = ReentrantMutex {
inner: box sys::ReentrantMutex::uninitialized(),
inner: Box::new(sys::ReentrantMutex::uninitialized()),
poison: poison::Flag::new(),
data: t,
};
@@ -164,7 +165,7 @@ impl<'a, T> Drop for ReentrantMutexGuard<'a, T> {
#[cfg(test)]
mod tests {
use prelude::v1::*;
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use sync::remutex::{ReentrantMutex, ReentrantMutexGuard};
use cell::RefCell;
use sync::Arc;
use boxed;
@@ -10,14 +10,15 @@

use prelude::v1::*;

use sys::sync as sys;

use cell::UnsafeCell;
use fmt;
use marker;
use mem;
use ops::{Deref, DerefMut};
use ptr;
use sys_common::poison::{self, LockResult, TryLockError, TryLockResult};
use sys_common::rwlock as sys;
use sync::poison::{self, LockResult, TryLockError, TryLockResult};

/// A reader-writer lock
///
@@ -103,7 +104,7 @@ unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
reason = "may be merged with RwLock in the future",
issue = "27717")]
pub struct StaticRwLock {
lock: sys::RWLock,
lock: sys::RwLock,
poison: poison::Flag,
}

@@ -345,7 +346,7 @@ impl StaticRwLock {
/// Creates a new rwlock.
pub const fn new() -> StaticRwLock {
StaticRwLock {
lock: sys::RWLock::new(),
lock: sys::RwLock::new(),
poison: poison::Flag::new(),
}
}
@@ -0,0 +1,5 @@
pub use sys::imp::c::{
EINVAL, EIO,
EBADF,
strlen
};
@@ -0,0 +1,19 @@
use num::{Zero, One};
use ops::Neg;
use sys::error;

pub fn cvt_zero<T: PartialEq + Zero>(t: T) -> error::Result<T> {
if t == T::zero() {
error::expect_last_result()
} else {
Ok(t)
}
}

pub fn cvt_neg1<T: One + PartialEq + Neg<Output=T>>(t: T) -> error::Result<T> {
if t == -T::one() {
error::expect_last_result()
} else {
Ok(t)
}
}

This file was deleted.

Oops, something went wrong.
@@ -22,7 +22,7 @@
#![allow(unused)]

use prelude::v1::*;
use sys_common::dwarf::DwarfReader;
use sys::common::dwarf::DwarfReader;
use core::mem;

pub const DW_EH_PE_omit : u8 = 0xFF;
@@ -0,0 +1,41 @@
use fmt;
use sys::env;

pub struct JoinPathsError(());

impl fmt::Display for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
env::join_paths_error().fmt(f)
}
}

impl fmt::Debug for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
env::join_paths_error().fmt(f)
}
}

impl JoinPathsError {
pub const fn new() -> Self { JoinPathsError(()) }
}

#[cfg(target_arch = "x86")]
pub const ARCH: &'static str = "x86";

#[cfg(target_arch = "x86_64")]
pub const ARCH: &'static str = "x86_64";

#[cfg(target_arch = "arm")]
pub const ARCH: &'static str = "arm";

#[cfg(target_arch = "aarch64")]
pub const ARCH: &'static str = "aarch64";

#[cfg(target_arch = "mips")]
pub const ARCH: &'static str = "mips";

#[cfg(target_arch = "mipsel")]
pub const ARCH: &'static str = "mipsel";

#[cfg(target_arch = "powerpc")]
pub const ARCH: &'static str = "powerpc";
@@ -0,0 +1,24 @@
use fmt;
use sys::error::Error;

pub type Result<T> = ::result::Result<T, Error>;

pub fn expect_last_result<T>() -> Result<T> {
Err(expect_last_error())
}

pub fn expect_last_error() -> Error {
Error::last_error().unwrap_or_else(|| Error::from_code(0))
}

impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Debug::fmt(&(self.code(), self.description().to_string_lossy()), f)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
fmt::Display::fmt(&self.description().to_string_lossy(), f)
}
}
@@ -8,14 +8,14 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io;
use io::prelude::*;
use sys::error::Result;
use backtrace;
use libc;
use sys_common::backtrace::{output, output_fileline};
use io;

pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
symaddr: *mut libc::c_void) -> io::Result<()> {
use env;
pub fn print(w: &mut io::Write, idx: isize, addr: *mut (),
symaddr: *mut ()) -> Result<()> {
use sys::env;
use ffi::CStr;
use ptr;

@@ -39,9 +39,6 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
msg: *const libc::c_char,
errnum: libc::c_int);
enum backtrace_state {}
#[link(name = "backtrace", kind = "static")]
#[cfg(not(test))]
extern {}

extern {
fn backtrace_create_state(filename: *const libc::c_char,
@@ -134,7 +131,7 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
} else {
None
};
let filename = match selfname.as_ref().and_then(|s| s.as_os_str().to_bytes()) {
let filename = match selfname.as_ref().and_then(|s| s.to_bytes()) {
Some(path) => {
let bytes = path;
if bytes.len() < LAST_FILENAME.len() {
@@ -162,7 +159,7 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
// errors are reported
let state = unsafe { init_state() };
if state.is_null() {
return output(w, idx, addr, None)
return backtrace::output(w, idx, addr, None)
}
let mut data = ptr::null();
let data_addr = &mut data as *mut *const libc::c_char;
@@ -172,9 +169,9 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
data_addr as *mut libc::c_void)
};
if ret == 0 || data.is_null() {
try!(output(w, idx, addr, None));
try!(backtrace::output(w, idx, addr, None));
} else {
try!(output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() })));
try!(backtrace::output(w, idx, addr, Some(unsafe { CStr::from_ptr(data).to_bytes() })));
}

// pcinfo may return an arbitrary number of file:line pairs,
@@ -198,7 +195,7 @@ pub fn print(w: &mut Write, idx: isize, addr: *mut libc::c_void,
for (i, &(file, line)) in fileline_buf[..fileline_count].iter().enumerate() {
if file.is_null() { continue; } // just to be sure
let file = unsafe { CStr::from_ptr(file).to_bytes() };
try!(output_fileline(w, file, line, i == FILELINE_SIZE - 1));
try!(backtrace::output_fileline(w, file, line, i == FILELINE_SIZE - 1));
}
}

@@ -120,12 +120,10 @@ extern "C" {
// iOS on armv7 uses SjLj exceptions and requires to link
// against corresponding routine (..._SjLj_...)
#[cfg(not(all(target_os = "ios", target_arch = "arm")))]
#[unwind]
pub fn _Unwind_RaiseException(exception: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;

#[cfg(all(target_os = "ios", target_arch = "arm"))]
#[unwind]
fn _Unwind_SjLj_RaiseException(e: *mut _Unwind_Exception)
-> _Unwind_Reason_Code;

@@ -10,91 +10,23 @@

#![allow(missing_docs)]

use boxed::Box;
use sync::Once;
use sys;
#[macro_use]
pub mod rt;

macro_rules! rtabort {
($($t:tt)*) => (::sys_common::util::abort(format_args!($($t)*)))
}

macro_rules! rtassert {
($e:expr) => ({
if !$e {
rtabort!(concat!("assertion failed: ", stringify!($e)))
}
})
}

pub mod args;
pub mod at_exit_imp;
pub mod backtrace;
pub mod condvar;
pub mod dwarf;
pub mod io;
pub mod libunwind;
pub mod mutex;
pub mod net;
pub mod poison;
pub mod remutex;
pub mod rwlock;
pub mod thread;
pub mod thread_info;
pub mod thread_local;
pub mod unwind;
pub mod util;
pub mod wtf8;
#[cfg(any(target_family = "unix", target_family = "windows"))] pub mod thread_local;
#[cfg(any(target_family = "unix", target_family = "windows"))] pub mod net_bsd;
#[cfg(any(target_family = "unix", target_family = "windows"))] pub mod unwind;
#[cfg(any(target_family = "unix", target_family = "windows"))] pub mod libunwind;
#[cfg(target_family = "windows")] pub mod dwarf;

#[cfg(any(all(unix, not(any(target_os = "macos", target_os = "ios"))),
all(windows, target_env = "gnu")))]
pub mod gnu;

// common error constructors

/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInner<Inner: ?Sized> {
fn as_inner(&self) -> &Inner;
}

/// A trait for viewing representations from std types
#[doc(hidden)]
pub trait AsInnerMut<Inner: ?Sized> {
fn as_inner_mut(&mut self) -> &mut Inner;
}

/// A trait for extracting representations from std types
#[doc(hidden)]
pub trait IntoInner<Inner> {
fn into_inner(self) -> Inner;
}

/// A trait for creating std types from internal representations
#[doc(hidden)]
pub trait FromInner<Inner> {
fn from_inner(inner: Inner) -> Self;
}

/// Enqueues a procedure to run when the main thread exits.
///
/// Currently these closures are only run once the main *Rust* thread exits.
/// Once the `at_exit` handlers begin running, more may be enqueued, but not
/// infinitely so. Eventually a handler registration will be forced to fail.
///
/// Returns `Ok` if the handler was successfully registered, meaning that the
/// closure will be run once the main thread exits. Returns `Err` to indicate
/// that the closure could not be registered, meaning that it is not scheduled
/// to be run.
pub fn at_exit<F: FnOnce() + Send + 'static>(f: F) -> Result<(), ()> {
if at_exit_imp::push(Box::new(f)) {Ok(())} else {Err(())}
}

/// One-time runtime cleanup.
pub fn cleanup() {
static CLEANUP: Once = Once::new();
CLEANUP.call_once(|| unsafe {
args::cleanup();
sys::stack_overflow::cleanup();
at_exit_imp::cleanup();
});
}
pub mod stdio;
pub mod env;
pub mod net;
pub mod process;
pub mod os_str;
pub mod error;
pub mod c;

This file was deleted.

Oops, something went wrong.

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -0,0 +1,135 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use sys::inner::*;

use hash;
use libc::{self, socklen_t, sa_family_t};
use mem;
use super::{ntoh, hton};
use sys::common::net::{SocketAddr, IpAddr};
use sys::net as sys;
use super::ip::{IpAddrV4, IpAddrV6};

#[derive(Copy)]
pub struct SocketAddrV4(libc::sockaddr_in);

#[derive(Copy)]
pub struct SocketAddrV6(libc::sockaddr_in6);

impl SocketAddrV4 {
pub fn new(ip: IpAddrV4, port: u16) -> SocketAddrV4 {
SocketAddrV4(
libc::sockaddr_in {
sin_family: libc::AF_INET as sa_family_t,
sin_port: hton(port),
sin_addr: *ip.as_inner(),
.. unsafe { mem::zeroed() }
}
)
}

pub fn addr(&self) -> &IpAddrV4 {
unsafe {
&*(&self.0.sin_addr as *const libc::in_addr as *const IpAddrV4)
}
}

pub fn port(&self) -> u16 { ntoh(self.0.sin_port) }
}

impl SocketAddrV6 {
pub fn new(ip: IpAddrV6, port: u16, flowinfo: u32, scope_id: u32)
-> SocketAddrV6 {
SocketAddrV6(
libc::sockaddr_in6 {
sin6_family: libc::AF_INET6 as sa_family_t,
sin6_port: hton(port),
sin6_addr: *ip.as_inner(),
sin6_flowinfo: hton(flowinfo),
sin6_scope_id: hton(scope_id),
.. unsafe { mem::zeroed() }
}
)
}

pub fn addr(&self) -> &IpAddrV6 {
unsafe {
&*(&self.0.sin6_addr as *const libc::in6_addr as *const IpAddrV6)
}
}

pub fn port(&self) -> u16 { ntoh(self.0.sin6_port) }

pub fn flowinfo(&self) -> u32 { ntoh(self.0.sin6_flowinfo) }

pub fn scope_id(&self) -> u32 { ntoh(self.0.sin6_scope_id) }
}

impl Clone for SocketAddrV4 {
fn clone(&self) -> SocketAddrV4 { *self }
}

impl Clone for SocketAddrV6 {
fn clone(&self) -> SocketAddrV6 { *self }
}

impl PartialEq for SocketAddrV4 {
fn eq(&self, other: &SocketAddrV4) -> bool {
self.0.sin_port == other.0.sin_port &&
self.0.sin_addr.s_addr == other.0.sin_addr.s_addr
}
}

impl PartialEq for SocketAddrV6 {
fn eq(&self, other: &SocketAddrV6) -> bool {
self.0.sin6_port == other.0.sin6_port &&
self.0.sin6_addr.s6_addr == other.0.sin6_addr.s6_addr &&
self.0.sin6_flowinfo == other.0.sin6_flowinfo &&
self.0.sin6_scope_id == other.0.sin6_scope_id
}
}

impl Eq for SocketAddrV4 {}
impl Eq for SocketAddrV6 {}

impl hash::Hash for SocketAddrV4 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.0.sin_port, self.0.sin_addr.s_addr).hash(s)
}
}

impl hash::Hash for SocketAddrV6 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.0.sin6_port, &self.0.sin6_addr.s6_addr,
self.0.sin6_flowinfo, self.0.sin6_scope_id).hash(s)
}
}

impl_inner!(SocketAddrV4(libc::sockaddr_in));
impl_inner!(SocketAddrV6(libc::sockaddr_in6));

pub fn sockaddr(addr: &SocketAddr) -> (*const libc::sockaddr, socklen_t) {
match *addr {
SocketAddr::V4(ref a) => {
(&a.0 as *const _ as *const _, mem::size_of_val(&a.0) as socklen_t)
}
SocketAddr::V6(ref a) => {
(&a.0 as *const _ as *const _, mem::size_of_val(&a.0) as socklen_t)
}
}
}

pub fn new_sockaddr(addr: IpAddr, port: u16) -> SocketAddr {
match addr {
IpAddr::V4(a) => SocketAddr::V4(sys::SocketAddrV4::new(a, port)),
IpAddr::V6(a) => SocketAddr::V6(sys::SocketAddrV6::new(a, port, 0, 0)),
}
}
@@ -0,0 +1,125 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use cmp::Ordering;
use hash;
use libc;
use super::{hton, ntoh};

#[derive(Copy)]
pub struct IpAddrV4(libc::in_addr);

#[derive(Copy)]
pub struct IpAddrV6(libc::in6_addr);

impl_inner!(IpAddrV4(libc::in_addr));
impl_inner!(IpAddrV6(libc::in6_addr));

impl IpAddrV4 {
pub fn new(a: u8, b: u8, c: u8, d: u8) -> IpAddrV4 {
IpAddrV4(
libc::in_addr {
s_addr: hton(((a as u32) << 24) |
((b as u32) << 16) |
((c as u32) << 8) |
(d as u32)),
}
)
}

pub fn octets(&self) -> [u8; 4] {
let bits = ntoh(self.0.s_addr);
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
}
}

impl Clone for IpAddrV4 {
fn clone(&self) -> IpAddrV4 { *self }
}

impl PartialEq for IpAddrV4 {
fn eq(&self, other: &IpAddrV4) -> bool {
self.0.s_addr == other.0.s_addr
}
}

impl Eq for IpAddrV4 {}

impl hash::Hash for IpAddrV4 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.0.s_addr.hash(s)
}
}

impl PartialOrd for IpAddrV4 {
fn partial_cmp(&self, other: &IpAddrV4) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for IpAddrV4 {
fn cmp(&self, other: &IpAddrV4) -> Ordering {
self.0.s_addr.cmp(&other.0.s_addr)
}
}

impl IpAddrV6 {
pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
h: u16) -> IpAddrV6 {
IpAddrV6(
libc::in6_addr {
s6_addr: [hton(a), hton(b), hton(c), hton(d),
hton(e), hton(f), hton(g), hton(h)]
}
)
}

/// Returns the eight 16-bit segments that make up this address.
pub fn segments(&self) -> [u16; 8] {
[ntoh(self.0.s6_addr[0]),
ntoh(self.0.s6_addr[1]),
ntoh(self.0.s6_addr[2]),
ntoh(self.0.s6_addr[3]),
ntoh(self.0.s6_addr[4]),
ntoh(self.0.s6_addr[5]),
ntoh(self.0.s6_addr[6]),
ntoh(self.0.s6_addr[7])]
}
}

impl Clone for IpAddrV6 {
fn clone(&self) -> IpAddrV6 { *self }
}

impl PartialEq for IpAddrV6 {
fn eq(&self, other: &IpAddrV6) -> bool {
self.0.s6_addr == other.0.s6_addr
}
}

impl Eq for IpAddrV6 {}

impl hash::Hash for IpAddrV6 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.0.s6_addr.hash(s)
}
}

impl PartialOrd for IpAddrV6 {
fn partial_cmp(&self, other: &IpAddrV6) -> Option<Ordering> {
Some(self.cmp(other))
}
}

impl Ord for IpAddrV6 {
fn cmp(&self, other: &IpAddrV6) -> Ordering {
self.0.s6_addr.cmp(&other.0.s6_addr)
}
}
@@ -0,0 +1,314 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use io::prelude::*;
use sys::error::{Error, Result};
use sys::inner::*;

use ffi::{CStr, CString};
use libc::{self, c_int, c_char, c_void, socklen_t};
use mem;
use ptr;
use io;
use sys::target::c;
use sys::target::net::{cvt, cvt_r, cvt_gai, Socket as SocketImp, init, wrlen_t};
use sys::common::net::{SocketAddr, IpAddr};
use sys::net as sys;
use net::Shutdown;
use time::Duration;

mod ip;
mod addr;

use self::addr::{new_sockaddr, sockaddr};

pub use self::ip::{IpAddrV4, IpAddrV6};
pub use self::addr::{SocketAddrV4, SocketAddrV6};

pub type TcpStream = Socket;
pub type TcpListener = Socket;
pub type UdpSocket = Socket;

pub fn setsockopt<T>(sock: &SocketImp, opt: c_int, val: c_int,
payload: T) -> Result<()> {
unsafe {
let payload = &payload as *const T as *const c_void;
cvt(libc::setsockopt(*sock.as_inner(), opt, val, payload, mem::size_of::<T>() as socklen_t)).map(drop)
}
}

pub fn getsockopt<T: Copy>(sock: &SocketImp, opt: c_int,
val: c_int) -> Result<T> {
unsafe {
let mut slot: T = mem::zeroed();
let mut len = mem::size_of::<T>() as socklen_t;
try!(cvt(c::getsockopt(*sock.as_inner(), opt, val, &mut slot as *mut _ as *mut _, &mut len)));
if len as usize != mem::size_of::<T>() {
Err(Error::from_code(sys::EINVAL))
} else {
Ok(slot)
}
}
}

fn sockname<F>(f: F) -> Result<SocketAddr>
where F: FnOnce(*mut libc::sockaddr, *mut socklen_t) -> c_int
{
unsafe {
let mut storage: libc::sockaddr_storage = mem::zeroed();
let mut len = mem::size_of_val(&storage) as 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,
len: usize) -> Result<SocketAddr> {
match storage.ss_family as libc::c_int {
libc::AF_INET => {
assert!(len as usize >= mem::size_of::<libc::sockaddr_in>());
Ok(SocketAddr::V4(FromInner::from_inner(unsafe {
*(storage as *const _ as *const libc::sockaddr_in)
})))
}
libc::AF_INET6 => {
assert!(len as usize >= mem::size_of::<libc::sockaddr_in6>());
Ok(SocketAddr::V6(FromInner::from_inner(unsafe {
*(storage as *const _ as *const libc::sockaddr_in6)
})))
}
_ => Err(Error::from_code(sys::EINVAL))
}
}

trait NetInt {
fn from_be(i: Self) -> Self;
fn to_be(&self) -> Self;
}
macro_rules! doit {
($($t:ident)*) => ($(impl NetInt for $t {
fn from_be(i: Self) -> Self { <$t>::from_be(i) }
fn to_be(&self) -> Self { <$t>::to_be(*self) }
})*)
}
doit! { i8 i16 i32 i64 isize u8 u16 u32 u64 usize }

fn hton<I: NetInt>(i: I) -> I { i.to_be() }
fn ntoh<I: NetInt>(i: I) -> I { I::from_be(i) }

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

impl Iterator for LookupHost {
type Item = Result<SocketAddr>;
fn next(&mut self) -> Option<Result<SocketAddr>> {
unsafe {
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;
Some(ret)
}
}
}

unsafe impl Sync for LookupHost {}
unsafe impl Send for LookupHost {}

impl Drop for LookupHost {
fn drop(&mut self) {
unsafe { freeaddrinfo(self.original) }
}
}

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 struct LookupAddr([c_char; NI_MAXHOST]);

impl LookupAddr {
pub fn as_bytes(&self) -> &[u8] {
unsafe { CStr::from_ptr(self.0.as_ptr()).to_bytes() }
}
}

pub struct Socket(SocketImp);
impl_inner!(Socket(SocketImp));
impl_inner!(for<T> Socket(SocketImp(T)));

impl Socket {
pub fn set_read_timeout(&self, dur: Option<Duration>) -> Result<()> {
self.0.set_timeout(dur, libc::SO_RCVTIMEO)
}

pub fn set_write_timeout(&self, dur: Option<Duration>) -> Result<()> {
self.0.set_timeout(dur, libc::SO_SNDTIMEO)
}

pub fn read_timeout(&self) -> Result<Option<Duration>> {
self.0.timeout(libc::SO_RCVTIMEO)
}

pub fn write_timeout(&self) -> Result<Option<Duration>> {
self.0.timeout(libc::SO_SNDTIMEO)
}

pub fn duplicate(&self) -> Result<Self> {
self.0.duplicate().map(Socket)
}

pub fn socket_addr(&self) -> Result<SocketAddr> {
sockname(|buf, len| unsafe {
libc::getsockname(*self.0.as_inner(), buf, len)
})
}

pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
self.0.read(buf)
}

pub fn write(&self, buf: &[u8]) -> Result<usize> {
self.0.write(buf)
}

pub fn flush(&self) -> io::Result<()> { Ok(()) }
}

impl Socket {
pub fn peer_addr(&self) -> Result<SocketAddr> {
sockname(|buf, len| unsafe {
libc::getpeername(*self.0.as_inner(), buf, len)
})
}

pub fn shutdown(&self, how: Shutdown) -> 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,
};
cvt(unsafe { libc::shutdown(*self.0.as_inner(), how) })
.map_err(From::from).map(drop)
}
}

impl Socket {
pub fn accept(&self) -> Result<(Socket, SocketAddr)> {
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
let mut len = mem::size_of_val(&storage) as socklen_t;
let sock = try!(self.0.accept(&mut storage as *mut _ as *mut _,
&mut len));
let addr = try!(sockaddr_to_addr(&storage, len as usize));
Ok((Socket(sock), addr))
}
}

impl Socket {
pub fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
let mut storage: libc::sockaddr_storage = unsafe { mem::zeroed() };
let mut addrlen = mem::size_of_val(&storage) as socklen_t;

let n = try!(cvt(unsafe { libc::recvfrom(*self.0.as_inner(),
buf.as_mut_ptr() as *mut c_void, buf.len() as wrlen_t, 0, &mut storage as *mut _ as *mut _, &mut addrlen) }));
Ok((n as usize, try!(sockaddr_to_addr(&storage, addrlen as usize))))
}

pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> Result<usize> {
let (dstp, dstlen) = sockaddr(dst);
cvt(unsafe { libc::sendto(*self.0.as_inner(), buf.as_ptr() as *const c_void, buf.len() as wrlen_t, 0, dstp, dstlen) })
.map_err(From::from).map(|v| v as usize)
}
}

pub fn lookup_host(host: &str) -> Result<LookupHost> {
init();

let c_host = try!(CString::new(host).map_err(|_| Error::from_code(sys::EINVAL)));
let mut res = ptr::null_mut();
unsafe {
try!(cvt_gai(getaddrinfo(c_host.as_ptr(), ptr::null(), ptr::null(),
&mut res)));
Ok(LookupHost { original: res, cur: res })
}
}

pub fn lookup_addr(addr: &sys::IpAddr) -> Result<LookupAddr> {
init();

let saddr = new_sockaddr(addr.clone(), 0);
let (inner, len) = sockaddr(&saddr);
let mut hostbuf = [0 as c_char; NI_MAXHOST];

unsafe {
try!(cvt_gai(getnameinfo(inner, len,
hostbuf.as_mut_ptr(), NI_MAXHOST as libc::size_t,
ptr::null_mut(), 0, 0)));
}

Ok(LookupAddr(hostbuf))
}

pub fn connect_tcp(addr: &SocketAddr) -> Result<Socket> {
init();

let sock = try!(SocketImp::new(addr, libc::SOCK_STREAM));

let (addrp, len) = sockaddr(addr);
try!(cvt_r(|| unsafe { libc::connect(*sock.as_inner(), addrp, len) }));
Ok(Socket(sock))
}

pub fn bind_tcp(addr: &SocketAddr) -> Result<Socket> {
init();

let sock = try!(SocketImp::new(addr, libc::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,
1 as c_int));
}

// Bind our new socket
let (addrp, len) = sockaddr(addr);
try!(cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len) }));

// Start listening
try!(cvt(unsafe { libc::listen(*sock.as_inner(), 128) }));
Ok(Socket(sock))
}

pub fn bind_udp(addr: &SocketAddr) -> Result<Socket> {
init();

let sock = try!(SocketImp::new(addr, libc::SOCK_DGRAM));
let (addrp, len) = sockaddr(addr);
try!(cvt(unsafe { libc::bind(*sock.as_inner(), addrp, len) }));
Ok(Socket(sock))
}
@@ -0,0 +1,214 @@
/// The underlying OsString/OsStr implementation on Unix systems: just
/// a `Vec<u8>`/`[u8]`.
#[cfg(not(target_family = "windows"))]
pub mod u8 {
use string::String;
use vec::Vec;
use borrow;
use str;
use fmt;
use mem;
use ops;

#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct OsString {
pub inner: Vec<u8>
}

#[derive(PartialOrd, Ord, PartialEq, Eq, Hash)]
pub struct OsStr {
pub inner: [u8]
}

impl fmt::Debug for OsStr {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.to_string_lossy().fmt(formatter)
}
}

impl fmt::Debug for OsString {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
borrow::Borrow::<OsStr>::borrow(self).fmt(formatter)
}
}

impl OsString {
pub fn from_string(s: String) -> Self {
OsString { inner: s.into_bytes() }
}

pub fn from_bytes(b: Vec<u8>) -> Option<Self> {
Some(Self::from_vec(b))
}

pub fn into_string(self) -> Result<String, Self> {
String::from_utf8(self.inner).map_err(|p| OsString { inner: p.into_bytes() } )
}

pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
&mut self.inner
}

pub fn push_slice(&mut self, s: &OsStr) {
self.inner.push_all(&s.inner)
}
}

impl OsString {
pub fn from_vec(b: Vec<u8>) -> Self {
OsString { inner: b }
}
}

impl borrow::Borrow<OsStr> for OsString {
fn borrow(&self) -> &OsStr {
ops::Deref::deref(self)
}
}

impl ops::Deref for OsString {
type Target = OsStr;

fn deref(&self) -> &OsStr {
unsafe { mem::transmute(&*self.inner) }
}
}

impl OsStr {
pub fn from_str(s: &str) -> &OsStr {
Self::from_bytes(s.as_bytes())
}

pub fn to_bytes(&self) -> Option<&[u8]> {
Some(self.as_bytes())
}

pub fn as_bytes(&self) -> &[u8] {
&self.inner
}

pub fn to_str(&self) -> Option<&str> {
str::from_utf8(&self.inner).ok()
}

pub fn to_string_lossy(&self) -> borrow::Cow<str> {
String::from_utf8_lossy(&self.inner)
}
}

impl OsStr {
pub fn from_bytes(b: &[u8]) -> &OsStr {
unsafe { mem::transmute(b) }
}
}

impl borrow::ToOwned for OsStr {
type Owned = OsString;

fn to_owned(&self) -> OsString {
OsString { inner: self.inner.to_vec() }
}
}
}

#[cfg(target_family = "windows")]
pub mod wtf8 {
use string::String;
use vec::Vec;
use sys::wtf8::{Wtf8, Wtf8Buf};
use borrow;
use fmt;
use mem;
use ops;

#[derive(Clone, Hash)]
pub struct OsString {
pub inner: Wtf8Buf
}

pub struct OsStr {
pub inner: Wtf8
}

impl fmt::Debug for OsStr {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
self.to_string_lossy().fmt(formatter)
}
}

impl fmt::Debug for OsString {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
borrow::Borrow::<OsStr>::borrow(self).fmt(formatter)
}
}

impl OsString {
pub fn from_string(s: String) -> Self {
OsString { inner: Wtf8Buf::from_string(s) }
}

pub fn from_bytes(b: Vec<u8>) -> Option<Self> {
String::from_utf8(b).ok().map(Self::from_string)
}

pub fn into_string(self) -> Result<String, Self> {
self.inner.into_string().map_err(|buf| OsString { inner: buf })
}

pub fn as_mut_vec(&mut self) -> &mut Vec<u8> {
unsafe { mem::transmute(&mut self.inner) }
}

pub fn push_slice(&mut self, s: &OsStr) {
self.inner.push_wtf8(&s.inner)
}
}

impl borrow::Borrow<OsStr> for OsString {
fn borrow(&self) -> &OsStr {
ops::Deref::deref(self)
}
}

impl ops::Deref for OsString {
type Target = OsStr;

fn deref(&self) -> &OsStr {
unsafe { mem::transmute(self.inner.as_slice()) }
}
}

impl OsStr {
pub fn from_str(s: &str) -> &Self {
unsafe { mem::transmute(Wtf8::from_str(s)) }
}

pub fn to_bytes(&self) -> Option<&[u8]> {
self.to_str().map(|s| s.as_bytes())
}

pub fn as_bytes(&self) -> &[u8] {
use sys::inner::*;

self.inner.as_inner()
}

pub fn to_str(&self) -> Option<&str> {
self.inner.as_str()
}

pub fn to_string_lossy(&self) -> borrow::Cow<str> {
self.inner.to_string_lossy()
}
}

impl borrow::ToOwned for OsStr {
type Owned = OsString;

fn to_owned(&self) -> OsString {
let mut buf = Wtf8Buf::with_capacity(self.inner.len());
buf.push_wtf8(&self.inner);
OsString { inner: buf }
}
}
}
@@ -0,0 +1,8 @@
use sys::process::RawFd;

pub enum Stdio {
MakePipe,
Raw(RawFd),
Inherit,
None,
}
@@ -0,0 +1,35 @@
pub fn std_cleanup() {
::at_exit::cleanup();
}

pub fn min_stack() -> usize {
use env;
use sync::atomic::{AtomicUsize, Ordering};

static MIN: AtomicUsize = AtomicUsize::new(0);
match MIN.load(Ordering::Relaxed) {
0 => {}
n => return n - 1,
}
let amt = env::var("RUST_MIN_STACK").ok()
.and_then(|s| s.parse().ok());
let amt = amt.unwrap_or(2 * 1024 * 1024);
// 0 is our sentinel value, so ensure that we'll never see 0 after
// initialization has run
MIN.store(amt + 1, Ordering::Relaxed);
amt
}

#[macro_export]
macro_rules! rtabort {
($($t:tt)*) => ($crate::panicking::abort(format_args!($($t)*)))
}

#[macro_export]
macro_rules! rtassert {
($e:expr) => ({
if !$e {
rtabort!(concat!("assertion failed: ", stringify!($e)))
}
})
}

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,7 @@
use fmt;
use sys::stdio;
use io::Write;

pub fn dumb_print(args: fmt::Arguments) {
let _ = stdio::stderr().map(|mut stderr| stderr.write_fmt(args));
}

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#![allow(dead_code)]

//! OS-based thread local storage
//!
//! This module provides an implementation of OS-based thread local storage,
@@ -34,7 +36,7 @@
//! among many threads via an `Arc`.
//!
//! ```rust,ignore
//! let key = Key::new(None);
//! let key = OsKey::new(None);
//! assert!(key.get().is_null());
//! key.set(1 as *mut u8);
//! assert!(!key.get().is_null());
@@ -46,21 +48,30 @@
//! with, however.
//!
//! ```rust,ignore
//! static KEY: StaticKey = INIT;
//! static KEY: StaticOsKey = INIT;
//!
//! unsafe {
//! assert!(KEY.get().is_null());
//! KEY.set(1 as *mut u8);
//! }
//! ```

#![allow(non_camel_case_types)]
#![unstable(feature = "thread_local_internals", issue = "0")]
#![allow(dead_code)] // sys isn't exported yet

use sync::atomic::{self, AtomicUsize, Ordering};
use core::nonzero::NonZero;
use cell::{Cell, UnsafeCell};
use boxed::Box;
use marker;
use ptr;

use sys::thread_local as imp;
pub trait OsKeyImp: Sized {
unsafe fn create(dtor: Option<unsafe extern fn(*mut u8)>) -> Self;
unsafe fn get(&self) -> *mut u8;
unsafe fn set(&self, value: *mut u8);
unsafe fn destroy(&self);

unsafe fn from_usize(value: usize) -> Self;
unsafe fn into_usize(&self) -> NonZero<usize>;
}

/// A type for TLS keys that are statically allocated.
///
@@ -74,29 +85,30 @@ use sys::thread_local as imp;
/// # Examples
///
/// ```ignore
/// use tls::os::{StaticKey, INIT};
/// use sys::os::{StaticOsKey, INIT};
///
/// static KEY: StaticKey = INIT;
/// static KEY: StaticOsKey = INIT;
///
/// unsafe {
/// assert!(KEY.get().is_null());
/// KEY.set(1 as *mut u8);
/// }
/// ```
pub struct StaticKey {
pub struct StaticOsKey<K> {
/// Inner static TLS key (internals).
key: AtomicUsize,
/// Destructor for the TLS value.
///
/// See `Key::new` for information about when the destructor runs and how
/// See `OsKey::new` for information about when the destructor runs and how
/// it runs.
dtor: Option<unsafe extern fn(*mut u8)>,
data: marker::PhantomData<K>,
}

/// A type for a safely managed OS-based TLS slot.
///
/// This type allocates an OS TLS key when it is initialized and will deallocate
/// the key when it falls out of scope. When compared with `StaticKey`, this
/// the key when it falls out of scope. When compared with `StaticOsKey`, this
/// type is entirely safe to use.
///
/// Implementations will likely, however, contain unsafe code as this type only
@@ -105,45 +117,33 @@ pub struct StaticKey {
/// # Examples
///
/// ```rust,ignore
/// use tls::os::Key;
/// use sys::os::OsKey;
///
/// let key = Key::new(None);
/// let key = OsKey::new(None);
/// assert!(key.get().is_null());
/// key.set(1 as *mut u8);
/// assert!(!key.get().is_null());
///
/// drop(key); // deallocate this TLS slot.
/// ```
pub struct Key {
key: imp::Key,
pub struct OsKey<K: OsKeyImp> {
key: K,
}

/// Constant initialization value for static TLS keys.
///
/// This value specifies no destructor by default.
pub const INIT: StaticKey = StaticKey::new(None);

impl StaticKey {
pub const fn new(dtor: Option<unsafe extern fn(*mut u8)>) -> StaticKey {
StaticKey {
key: atomic::AtomicUsize::new(0),
dtor: dtor
}
}

impl<K: OsKeyImp> StaticOsKey<K> {
/// Gets the value associated with this TLS key
///
/// This will lazily allocate a TLS key from the OS if one has not already
/// been allocated.
#[inline]
pub unsafe fn get(&self) -> *mut u8 { imp::get(self.key()) }
pub unsafe fn get(&self) -> *mut u8 { self.key().get() }

/// Sets this TLS key to a new value.
///
/// This will lazily allocate a TLS key from the OS if one has not already
/// been allocated.
#[inline]
pub unsafe fn set(&self, val: *mut u8) { imp::set(self.key(), val) }
pub unsafe fn set(&self, val: *mut u8) { self.key().set(val) }

/// Deallocates this OS TLS key.
///
@@ -155,47 +155,38 @@ impl StaticKey {
pub unsafe fn destroy(&self) {
match self.key.swap(0, Ordering::SeqCst) {
0 => {}
n => { imp::destroy(n as imp::Key) }
n => { K::from_usize(n).destroy() }
}
}

pub const fn new(dtor: Option<unsafe extern fn(*mut u8)>) -> Self {
StaticOsKey {
key: atomic::AtomicUsize::new(0),
data: marker::PhantomData,
dtor: dtor
}
}

#[inline]
unsafe fn key(&self) -> imp::Key {
unsafe fn key(&self) -> K {
match self.key.load(Ordering::Relaxed) {
0 => self.lazy_init() as imp::Key,
n => n as imp::Key
0 => self.lazy_init(),
n => K::from_usize(n)
}
}

unsafe fn lazy_init(&self) -> usize {
// POSIX allows the key created here to be 0, but the compare_and_swap
// below relies on using 0 as a sentinel value to check who won the
// race to set the shared TLS key. As far as I know, there is no
// guaranteed value that cannot be returned as a posix_key_create key,
// so there is no value we can initialize the inner key with to
// prove that it has not yet been set. As such, we'll continue using a
// value of 0, but with some gyrations to make sure we have a non-0
// value returned from the creation routine.
// FIXME: this is clearly a hack, and should be cleaned up.
let key1 = imp::create(self.dtor);
let key = if key1 != 0 {
key1
} else {
let key2 = imp::create(self.dtor);
imp::destroy(key1);
key2
};
assert!(key != 0);
match self.key.compare_and_swap(0, key as usize, Ordering::SeqCst) {
unsafe fn lazy_init(&self) -> K {
let key = K::create(self.dtor);
match self.key.compare_and_swap(0, *key.into_usize(), Ordering::SeqCst) {
// The CAS succeeded, so we've created the actual key
0 => key as usize,
0 => { key },
// If someone beat us to the punch, use their key instead
n => { imp::destroy(key); n }
n => { key.destroy(); K::from_usize(n) }
}
}
}

impl Key {
impl<K: OsKeyImp> OsKey<K> {
/// Creates a new managed OS TLS key.
///
/// This key will be deallocated when the key falls out of scope.
@@ -205,36 +196,92 @@ impl Key {
/// is non-null the destructor will be invoked. The TLS value will be reset
/// to null before the destructor is invoked.
///
/// Note that the destructor will not be run when the `Key` goes out of
/// Note that the destructor will not be run when the `OsKey` goes out of
/// scope.
#[inline]
pub fn new(dtor: Option<unsafe extern fn(*mut u8)>) -> Key {
Key { key: unsafe { imp::create(dtor) } }
pub fn new(dtor: Option<unsafe extern fn(*mut u8)>) -> Self {
OsKey { key: unsafe { K::create(dtor) } }
}

/// See StaticKey::get
/// See StaticOsKey::get
#[inline]
pub fn get(&self) -> *mut u8 {
unsafe { imp::get(self.key) }
unsafe { self.key.get() }
}

/// See StaticKey::set
/// See StaticOsKey::set
#[inline]
pub fn set(&self, val: *mut u8) {
unsafe { imp::set(self.key, val) }
unsafe { self.key.set(val) }
}
}

impl Drop for Key {
impl<K: OsKeyImp> Drop for OsKey<K> {
fn drop(&mut self) {
unsafe { imp::destroy(self.key) }
unsafe { self.key.destroy() }
}
}

pub struct Key<T, K> {
// OS-TLS key that we'll use to key off.
os: StaticOsKey<K>,
marker: marker::PhantomData<Cell<T>>,
}

unsafe impl<T, K: OsKeyImp> marker::Sync for Key<T, K> { }

struct Value<T: 'static, K: 'static> {
key: &'static Key<T, K>,
value: UnsafeCell<Option<T>>,
}

impl<T: 'static, K: OsKeyImp + 'static> Key<T, K> {
pub const fn new() -> Self {
Key {
os: StaticOsKey::new(Some(destroy_value::<T, K>)),
marker: marker::PhantomData
}
}

pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
let ptr = self.os.get() as *mut Value<T, K>;
if !ptr.is_null() {
if ptr as usize == 1 {
return None
}
return Some(&(*ptr).value);
}

// If the lookup returned null, we haven't initialized our own local
// copy, so do that now.
let ptr: Box<Value<T, K>> = Box::new(Value {
key: self,
value: UnsafeCell::new(None),
});
let ptr = Box::into_raw(ptr);
self.os.set(ptr as *mut u8);
Some(&(*ptr).value)
}
}

unsafe extern fn destroy_value<T: 'static, K: OsKeyImp + 'static>(ptr: *mut u8) {
// The OS TLS ensures that this key contains a NULL value when this
// destructor starts to run. We set it back to a sentinel value of 1 to
// ensure that any future calls to `get` for this thread will return
// `None`.
//
// Note that to prevent an infinite loop we reset it back to null right
// before we return from the destructor ourselves.
let ptr = Box::from_raw(ptr as *mut Value<T, K>);
let key = ptr.key;
key.os.set(1 as *mut u8);
drop(ptr);
key.os.set(ptr::null_mut());
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
use super::{Key, StaticKey};
use super::{Key, StaticOsKey};

fn assert_sync<T: Sync>() {}
fn assert_send<T: Send>() {}
@@ -256,8 +303,8 @@ mod tests {

#[test]
fn statik() {
static K1: StaticKey = StaticKey::new(None);
static K2: StaticKey = StaticKey::new(None);
static K1: StaticOsKey = StaticOsKey::new(None);
static K2: StaticOsKey = StaticOsKey::new(None);

unsafe {
assert!(K1.get().is_null());
@@ -10,25 +10,25 @@

#![allow(private_no_mangle_fns)]

use prelude::v1::*;

use sys::unwind as sys;
use sys::common::libunwind as uw;
use any::Any;
use sys_common::libunwind as uw;
use boxed::Box;

struct Exception {
uwe: uw::_Unwind_Exception,
cause: Option<Box<Any + Send + 'static>>,
}

pub unsafe fn panic(data: Box<Any + Send + 'static>) -> ! {
let exception: Box<_> = box Exception {
let exception: Box<_> = Box::new(Exception {
uwe: uw::_Unwind_Exception {
exception_class: rust_exception_class(),
exception_cleanup: exception_cleanup,
private: [0; uw::unwinder_private_data_size],
},
cause: Some(data),
};
});
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
let error = uw::_Unwind_RaiseException(exception_param);
rtabort!("Could not unwind stack, error = {}", error as isize);
@@ -78,7 +78,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
not(all(windows, target_arch = "x86_64")),
not(test)))]
pub mod eabi {
use sys_common::libunwind as uw;
use sys::common::libunwind as uw;
use libc::c_int;

extern {
@@ -67,22 +67,23 @@
#![allow(dead_code)]
#![allow(unused_imports)]

use prelude::v1::*;

use sys::thread_local::StaticOsKey;
use sys::rt;
use any::Any;
use boxed;
use boxed::Box;
use string::String;
use panicking;
use cmp;
use panicking::{self,PANIC_COUNT};
use fmt;
use intrinsics;
use mem;
use sync::atomic::{self, Ordering};
use sys_common::mutex::Mutex;

// The actual unwinding implementation is cfg'd here, and we've got two current
// implementations. One goes through SEH on Windows and the other goes through
// libgcc via the libunwind-like API.

static PANIC_COUNT: StaticOsKey = StaticOsKey::new(None);

// i686-pc-windows-msvc
#[cfg(all(windows, target_arch = "x86", target_env = "msvc"))]
#[path = "seh.rs"] #[doc(hidden)]
@@ -145,17 +146,15 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
// care of exposing correctly.
unsafe fn inner_try(f: fn(*mut u8), data: *mut u8)
-> Result<(), Box<Any + Send>> {
PANIC_COUNT.with(|s| {
let prev = s.get();
s.set(0);
let ep = intrinsics::try(f, data);
s.set(prev);
if ep.is_null() {
Ok(())
} else {
Err(imp::cleanup(ep))
}
})
let prev = PANIC_COUNT.get();
PANIC_COUNT.set(0 as *mut _);
let ep = intrinsics::try(f, data);
PANIC_COUNT.set(prev);
if ep.is_null() {
Ok(())
} else {
Err(imp::cleanup(ep))
}
}

fn try_fn<F: FnOnce()>(opt_closure: *mut u8) {
@@ -174,8 +173,17 @@ pub unsafe fn try<F: FnOnce()>(f: F) -> Result<(), Box<Any + Send>> {
}

/// Determines whether the current thread is unwinding because of panic.
pub fn panicking() -> bool {
PANIC_COUNT.with(|s| s.get() != 0)
pub fn is_panicking() -> bool {
unsafe { PANIC_COUNT.get() as usize != 0 }
}

/// Increases the thread-local panic count by one, returning the previous value.
pub fn panic_inc() -> usize {
unsafe {
let panics = PANIC_COUNT.get() as usize;
PANIC_COUNT.set((panics + 1) as *mut _);
panics
}
}

// An uninlined, unmangled function upon which to slap yer breakpoints
@@ -191,7 +199,6 @@ fn rust_panic(cause: Box<Any + Send + 'static>) -> ! {
#[cfg(not(test))]
/// Entry point of panic from the libcore crate.
#[lang = "panic_fmt"]
#[unwind]
pub extern fn rust_begin_unwind(msg: fmt::Arguments,
file: &'static str, line: u32) -> ! {
begin_unwind_fmt(msg, &(file, line))
@@ -18,7 +18,7 @@ use prelude::v1::*;

use any::Any;
use self::EXCEPTION_DISPOSITION::*;
use sys_common::dwarf::eh;
use sys::common::dwarf::eh;
use core::mem;
use core::ptr;
use libc::{c_void, c_ulonglong, DWORD, LPVOID};

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,56 @@
// Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! This module contains the linkage attributes to all runtime dependencies of
//! the standard library This varies per-platform, but these libraries are
//! necessary for running libstd.

// A few small shims in C that haven't been translated to Rust yet
#[cfg(all(not(test), unix))]
#[link(name = "rust_builtin", kind = "static")]
extern {}

// On Linux, librt and libdl are indirect dependencies via std,
// and binutils 2.22+ won't add them automatically
#[cfg(all(target_os = "linux", not(target_env = "musl")))]
#[link(name = "dl")]
#[link(name = "pthread")]
extern {}

#[cfg(all(not(test),
any(all(unix, not(any(target_os = "macos", target_os = "ios"))),
all(windows, target_env = "gnu"))))]
#[link(name = "backtrace", kind = "static")]
extern {}

#[cfg(target_os = "android")]
#[link(name = "dl")]
#[link(name = "log")]
extern {}

#[cfg(target_os = "freebsd")]
#[link(name = "execinfo")]
#[link(name = "pthread")]
extern {}

#[cfg(any(target_os = "dragonfly",
target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd"))]
#[link(name = "pthread")]
extern {}

#[cfg(target_os = "macos")]
#[link(name = "System")]
extern {}

#[cfg(target_os = "ios")]
#[link(name = "System")]
extern {}
@@ -0,0 +1,28 @@
pub use sys::imp::error::{
Error,
ErrorString,
};

use str;
use borrow::Cow;
use string::String;

pub type Result<T> = ::result::Result<T, Error>;

pub fn expect_last_result<T>() -> Result<T> {
Err(expect_last_error())
}

pub fn expect_last_error() -> Error {
Error::last_error().unwrap_or_else(|| Error::from_code(0))
}

impl ErrorString {
pub fn to_str(&self) -> ::result::Result<&str, str::Utf8Error> {
str::from_utf8(self.as_bytes())
}

pub fn to_string_lossy(&self) -> Cow<str> {
String::from_utf8_lossy(self.as_bytes())
}
}
@@ -0,0 +1,131 @@
/// A trait for viewing representations from std types
pub trait AsInner<Inner: ?Sized> {
fn as_inner(&self) -> &Inner;
}

/// A trait for viewing representations from std types
pub trait AsInnerMut<Inner: ?Sized> {
fn as_inner_mut(&mut self) -> &mut Inner;
}

/// A trait for extracting representations from std types
pub trait IntoInner<Inner> {
fn into_inner(self) -> Inner;
}

/// A trait for creating std types from internal representations
pub trait FromInner<Inner> {
fn from_inner(inner: Inner) -> Self;
}

#[macro_export]
macro_rules! impl_inner {
(for<$T:ident> $t:ident($t0:ident($TT:ident)): AsInner) => {
impl<$T> $crate::sys::inner::AsInner<$T> for $t where $t0: $crate::sys::inner::AsInner<$T> {
fn as_inner(&self) -> &$T { $crate::sys::inner::AsInner::<$T>::as_inner(&self.0) }
}
};

(for<$T:ident> $t:ident($t0:ident($TT:ident)): IntoInner) => {
impl<$T> $crate::sys::inner::IntoInner<$T> for $t where $t0: $crate::sys::inner::IntoInner<$T> {
fn into_inner(self) -> $T { $crate::sys::inner::IntoInner::<$T>::into_inner(self.0) }
}
};

(for<$T:ident> $t:ident($t0:ident($TT:ident)): IntoInnerForget) => {
impl<$T> $crate::sys::inner::IntoInner<$T> for $t where $t0: $crate::sys::inner::IntoInner<$T> {
fn into_inner(self) -> $T {
let inner = $crate::sys::inner::IntoInner::<$T>::into_inner(self.0);
$crate::mem::forget(self);
inner
}
}
};

(for<$T:ident> $t:ident($t0:ident($TT:ident)): FromInner) => {
impl<$T> $crate::sys::inner::FromInner<$T> for $t where $t0: $crate::sys::inner::FromInner<$T> {
fn from_inner(inner: $T) -> $t { $t($crate::sys::inner::FromInner::<$T>::from_inner(inner)) }
}
};

(1 => $t:ident($t0:ident($inner:ty)): AsInner) => {
impl $crate::sys::inner::AsInner<$inner> for $t {
fn as_inner(&self) -> &$inner { $crate::sys::inner::AsInner::<$inner>::as_inner($crate::sys::inner::AsInner::<$t0>::as_inner(self)) }
}
};

(1 => $t:ident($t0:ident($inner:ty)): IntoInner) => {
impl $crate::sys::inner::IntoInner<$inner> for $t {
fn into_inner(self) -> $inner { $crate::sys::inner::IntoInner::<$inner>::into_inner($crate::sys::inner::IntoInner::<$t0>::into_inner(self)) }
}
};

(1 => $t:ident($t0:ident($inner:ty)): FromInner) => {
impl $crate::sys::inner::FromInner<$inner> for $t {
fn from_inner(inner: $inner) -> Self { $crate::sys::inner::FromInner::<$t0>::from_inner($crate::sys::inner::FromInner::<$inner>::from_inner(inner)) }
}
};

(0 => $t:ident($inner:ty): AsInner) => {
impl $crate::sys::inner::AsInner<$inner> for $t {
fn as_inner(&self) -> &$inner { &self.0 }
}
};

(0 => $t:ident($inner:ty): IntoInnerForget) => {
impl $crate::sys::inner::IntoInner<$inner> for $t {
fn into_inner(self) -> $inner {
let inner = self.0;
$crate::mem::forget(self);
inner
}
}
};

(0 => $t:ident($inner:ty): IntoInner) => {
impl $crate::sys::inner::IntoInner<$inner> for $t {
fn into_inner(self) -> $inner { self.0 }
}
};

(0 => $t:ident($inner:ty): FromInner) => {
impl $crate::sys::inner::FromInner<$inner> for $t {
fn from_inner(inner: $inner) -> Self { $t(inner) }
}
};

($t:ident($t0:ident($inner:ty)): $im:ident) => { impl_inner!(1 => $t($t0($inner)): $im); };
($t:ident($inner:ty): $im:ident) => { impl_inner!(0 => $t($inner): $im); };

($t:ident($t0:ident($inner:ty)): $im0:ident $(+ $im:ident)+) => {
$(
impl_inner!(1 =>$t($t0($inner)): $im);
)+

impl_inner!(1 => $t($t0($inner)): $im0);
};

($t:ident($inner:ty): $im0:ident $(+ $im:ident)+) => {
$(
impl_inner!(0 => $t($inner): $im);
)+

impl_inner!(0 => $t($inner): $im0);
};

(for<$T:ident> $t:ident($t0:ident($TT:ident)): $im0:ident $(+ $im:ident)+) => {
$(
impl_inner!(for<$T> $t($t0($TT)): $im);
)+

impl_inner!(for<$T> $t($t0($TT)): $im0);
};

($t:ident($($tt:tt)*)) => {
impl_inner!($t($($tt)*): AsInner + IntoInner + FromInner);
};

(for<$T:ident> $t:ident($($tt:tt)*)) => {
impl_inner!(for<$T> $t($($tt)*): AsInner + IntoInner + FromInner);
};
}
@@ -0,0 +1,38 @@
#![allow(missing_docs)]
#![doc(hidden)]

#[macro_use]
pub mod inner;
pub mod os;

#[cfg(target_family = "windows")]
mod wtf8;

#[macro_use]
pub mod common;

#[cfg(target_family = "unix")] pub mod unix;
#[cfg(target_family = "windows")] pub mod windows;

#[cfg(target_family = "unix")] pub use self::unix as target;
#[cfg(target_family = "windows")] pub use self::windows as target;

pub use self::target::{
time,
unwind,
sync,
backtrace,
path,
thread,
rand,
dynamic_lib,
fs,
stdio,
env,
rt,
process,
os_str,
error,
thread_local,
net,
};
@@ -0,0 +1,23 @@
pub use sys::imp::net::{
LookupAddr, LookupHost,
SocketAddrV4, SocketAddrV6,
IpAddrV4, IpAddrV6,
Socket, TcpStream, TcpListener, UdpSocket,
lookup_host, lookup_addr,
connect_tcp, bind_tcp, bind_udp,
};

pub enum SocketAddr {
V4(SocketAddrV4),
V6(SocketAddrV6),
}

pub enum IpAddr {
V4(IpAddrV4),
V6(IpAddrV6),
}

impl Copy for IpAddr { }
impl Copy for SocketAddr { }
impl Clone for IpAddr { fn clone(&self) -> Self { *self } }
impl Clone for SocketAddr { fn clone(&self) -> Self { *self } }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -16,5 +16,5 @@ pub mod raw;

pub mod fs {
#![stable(feature = "raw_ext", since = "1.1.0")]
pub use sys::fs::MetadataExt;
pub use os::unix::fs::MetadataExt;
}
@@ -25,7 +25,7 @@ pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
mod arch {
use super::{dev_t, mode_t};
use os::raw::{c_long, c_short};
use os::unix::raw::{gid_t, uid_t};
use sys::unix::raw::{gid_t, uid_t};

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
@@ -86,7 +86,7 @@ mod arch {
mod arch {
use super::mode_t;
use os::raw::{c_long, c_ulong};
use os::unix::raw::{gid_t, uid_t};
use sys::unix::raw::{gid_t, uid_t};

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i32;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
@@ -146,7 +146,7 @@ mod arch {
mod arch {
use super::{dev_t, mode_t};
use os::raw::{c_long, c_int};
use os::unix::raw::{gid_t, uid_t};
use sys::unix::raw::{gid_t, uid_t};

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i32;
@@ -204,7 +204,7 @@ mod arch {
mod arch {
use super::{dev_t, mode_t};
use os::raw::{c_long, c_int};
use os::unix::raw::{gid_t, uid_t};
use sys::unix::raw::{gid_t, uid_t};

#[stable(feature = "raw_ext", since = "1.1.0")] pub type blkcnt_t = i64;
#[stable(feature = "raw_ext", since = "1.1.0")] pub type blksize_t = i64;
File renamed without changes.
File renamed without changes.
@@ -13,8 +13,8 @@
#![stable(feature = "os", since = "1.0.0")]
#![allow(missing_docs, bad_style)]

#[cfg(unix)] pub use sys::ext as unix;
#[cfg(windows)] pub use sys::ext as windows;
#[cfg(target_family = "unix")] pub mod unix;
#[cfg(target_family = "windows")] pub mod windows;

#[cfg(target_os = "android")] pub mod android;
#[cfg(target_os = "bitrig")] pub mod bitrig;
@@ -24,7 +24,7 @@
#[cfg(target_os = "linux")] pub mod linux;
#[cfg(target_os = "macos")] pub mod macos;
#[cfg(target_os = "nacl")] pub mod nacl;
#[cfg(target_os = "netbsd")] pub mod netbsd;
#[cfg(target_os = "netbsd")] pub mod netbsd;
#[cfg(target_os = "openbsd")] pub mod openbsd;

pub mod raw;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Oops, something went wrong.