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
@@ -229,7 +229,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.
///
@@ -239,13 +239,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) }
}
}

@@ -273,7 +273,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 {
@@ -315,7 +315,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 {
@@ -343,14 +343,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))
@@ -383,15 +383,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.
///
@@ -403,10 +403,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,12 +10,13 @@

use prelude::v1::*;

use sys::sync as sys;

use cell::UnsafeCell;
use fmt;
use marker;
use ops::{Deref, DerefMut};
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,12 +10,13 @@

use prelude::v1::*;

use sys::sync as sys;

use cell::UnsafeCell;
use fmt;
use marker;
use ops::{Deref, DerefMut};
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
///
@@ -101,7 +102,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,
}

@@ -293,7 +294,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,3 @@
pub use sys::imp::backtrace::{
Backtrace,
};
@@ -0,0 +1,5 @@
pub use sys::imp::c::{
EINVAL, EIO,
EBADF,
strlen
};
@@ -19,8 +19,6 @@
//!
//! FIXME #7756: Would be nice for this to not exist.

#![allow(dead_code)] // different code on OSX/linux/etc

use vec::Vec;

/// One-time global initialization.
@@ -40,11 +38,11 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
target_os = "netbsd",
target_os = "openbsd"))]
mod imp {
use prelude::v1::*;

use libc::c_char;
use mem;
use core::mem;
use ffi::CStr;
use alloc::boxed::Box;
use vec::Vec;

use sync::StaticMutex;

@@ -56,22 +54,23 @@ mod imp {
CStr::from_ptr(*argv.offset(i) as *const c_char).to_bytes().to_vec()
}).collect();

let _guard = LOCK.lock();
let _g = LOCK.lock();
let ptr = get_global_ptr();
assert!((*ptr).is_none());
(*ptr) = Some(box args);
(*ptr) = Some(Box::new(args));
}

pub unsafe fn cleanup() {
let _guard = LOCK.lock();
let _g = LOCK.lock();
*get_global_ptr() = None;
}

pub fn clone() -> Option<Vec<Vec<u8>>> {
let _guard = LOCK.lock();
unsafe {
let _g = LOCK.lock();
let ptr = get_global_ptr();
(*ptr).as_ref().map(|s| (**s).clone())
let v = (*ptr).as_ref().map(|s| (**s).clone());
v
}
}

@@ -0,0 +1,4 @@
pub use libc::{
EINVAL, EIO,
strlen
};

This file was deleted.

Oops, something went wrong.
@@ -8,16 +8,16 @@
// 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;
use core::ptr;

////////////////////////////////////////////////////////////////////////
// libbacktrace.h API
@@ -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));
}
}

@@ -132,12 +132,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,16 @@

#![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(unix, windows))] pub mod args;
#[cfg(any(unix, windows))] pub mod thread_local;
#[cfg(any(unix, windows))] pub mod net;
#[cfg(any(unix, windows))] pub mod unwind;
#[cfg(any(unix, windows))] pub mod libunwind;
#[cfg(any(unix, windows))] pub mod c;

#[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();
});
}

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -0,0 +1,134 @@
// 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::net::{self as sys, IpAddr, SocketAddr};
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,313 @@
// 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, cvt, cvt_r};
use sys::target::net::{cvt_gai, Socket as SocketImp, init, wrlen_t};
use sys::net::{self as sys, SocketAddr, IpAddr};
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(libc::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(libc::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));
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,31 @@
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.

This file was deleted.

Oops, something went wrong.

This file was deleted.

Oops, something went wrong.
@@ -34,7 +34,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 +46,17 @@
//! 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 sys::thread_local as imp;
use sys::target::thread_local as imp;

/// A type for TLS keys that are statically allocated.
///
@@ -74,29 +70,29 @@ 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 {
/// 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)>,
}

/// 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,32 +101,20 @@ 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 {
pub struct OsKey {
key: imp::Key,
}

/// 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 StaticOsKey {
/// Gets the value associated with this TLS key
///
/// This will lazily allocate a TLS key from the OS if one has not already
@@ -158,6 +142,15 @@ impl StaticKey {
n => { imp::destroy(n as imp::Key) }
}
}
}

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

#[inline]
unsafe fn key(&self) -> imp::Key {
@@ -195,7 +188,7 @@ impl StaticKey {
}
}

impl Key {
impl OsKey {
/// Creates a new managed OS TLS key.
///
/// This key will be deallocated when the key falls out of scope.
@@ -205,36 +198,197 @@ 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)>) -> OsKey {
OsKey { key: unsafe { imp::create(dtor) } }
}

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

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

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

#[cfg(all(any(target_os = "macos", target_os = "linux"),
not(target_arch = "aarch64"),
not(no_elf_tls)))]
#[doc(hidden)]
pub mod key_imp {
use sys::thread_local::StaticOsKey;
use boxed::Box;
use vec::Vec;
use cell::{Cell, UnsafeCell};
use marker;
use intrinsics;
use ptr;

pub struct Key<T> {
inner: UnsafeCell<Option<T>>,

// Metadata to keep track of the state of the destructor. Remember that
// these variables are thread-local, not global.
dtor_registered: Cell<bool>,
dtor_running: Cell<bool>,
}

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

impl<T> Key<T> {
pub const fn new() -> Key<T> {
Key {
inner: UnsafeCell::new(None),
dtor_registered: Cell::new(false),
dtor_running: Cell::new(false)
}
}

unsafe fn register_dtor(&self) {
if !intrinsics::needs_drop::<T>() || self.dtor_registered.get() {
return
}

register_dtor(self as *const _ as *mut u8,
destroy_value::<T>);
self.dtor_registered.set(true);
}
}

impl<T> Key<T> {
pub unsafe fn get(&'static self) -> Option<&'static UnsafeCell<Option<T>>> {
if intrinsics::needs_drop::<T>() && self.dtor_running.get() {
return None
}
self.register_dtor();
Some(&self.inner)
}
}

// Since what appears to be glibc 2.18 this symbol has been shipped which
// GCC and clang both use to invoke destructors in thread_local globals, so
// let's do the same!
//
// Note, however, that we run on lots older linuxes, as well as cross
// compiling from a newer linux to an older linux, so we also have a
// fallback implementation to use as well.
//
// Due to rust-lang/rust#18804, make sure this is not generic!
#[cfg(target_os = "linux")]
unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
use core::mem;
use libc;

extern {
#[linkage = "extern_weak"]
static __dso_handle: *mut u8;
#[linkage = "extern_weak"]
static __cxa_thread_atexit_impl: *const libc::c_void;
}
if !__cxa_thread_atexit_impl.is_null() {
type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
arg: *mut u8,
dso_handle: *mut u8) -> libc::c_int;
mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
(dtor, t, &__dso_handle as *const _ as *mut _);
return
}

// The fallback implementation uses a vanilla OS-based TLS key to track
// the list of destructors that need to be run for this thread. The key
// then has its own destructor which runs all the other destructors.
//
// The destructor for DTORS is a little special in that it has a `while`
// loop to continuously drain the list of registered destructors. It
// *should* be the case that this loop always terminates because we
// provide the guarantee that a TLS key cannot be set after it is
// flagged for destruction.
static DTORS: super::StaticOsKey = super::StaticOsKey::new(Some(run_dtors));
type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
if DTORS.get().is_null() {
let v: Box<List> = Box::new(Vec::new());
DTORS.set(Box::into_raw(v) as *mut u8);
}
let list: &mut List = &mut *(DTORS.get() as *mut List);
list.push((t, dtor));

unsafe extern fn run_dtors(mut ptr: *mut u8) {
while !ptr.is_null() {
let list: Box<List> = Box::from_raw(ptr as *mut List);
for &(ptr, dtor) in list.iter() {
dtor(ptr);
}
ptr = DTORS.get();
DTORS.set(ptr::null_mut());
}
}
}

// OSX's analog of the above linux function is this _tlv_atexit function.
// The disassembly of thread_local globals in C++ (at least produced by
// clang) will have this show up in the output.
#[cfg(target_os = "macos")]
unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
extern {
fn _tlv_atexit(dtor: unsafe extern fn(*mut u8),
arg: *mut u8);
}
_tlv_atexit(dtor, t);
}

pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
let ptr = ptr as *mut Key<T>;
// Right before we run the user destructor be sure to flag the
// destructor as running for this thread so calls to `get` will return
// `None`.
(*ptr).dtor_running.set(true);

// The OSX implementation of TLS apparently had an odd aspect to it
// where the pointer we have may be overwritten while this destructor
// is running. Specifically if a TLS destructor re-accesses TLS it may
// trigger a re-initialization of all TLS variables, paving over at
// least some destroyed ones with initial values.
//
// This means that if we drop a TLS value in place on OSX that we could
// revert the value to its original state halfway through the
// destructor, which would be bad!
//
// Hence, we use `ptr::read` on OSX (to move to a "safe" location)
// instead of drop_in_place.
if cfg!(target_os = "macos") {
ptr::read((*ptr).inner.get());
} else {
intrinsics::drop_in_place((*ptr).inner.get());
}
}
}

#[cfg(any(not(any(target_os = "macos", target_os = "linux")),
target_arch = "aarch64",
no_elf_tls))]
#[doc(hidden)]
pub mod key_imp {
pub use thread_local::os::Key;
}

pub use self::key_imp::Key;

#[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 +410,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 {
@@ -60,22 +60,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)]
@@ -138,17 +139,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) {
@@ -167,8 +166,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
@@ -184,7 +192,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))
@@ -198,7 +205,7 @@ pub extern fn rust_begin_unwind(msg: fmt::Arguments,
/// the actual formatting into this shared place.
#[inline(never)] #[cold]
pub fn begin_unwind_fmt(msg: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
use fmt::Write;
use core::fmt::Write;

// We do two allocations here, unfortunately. But (a) they're
// required with the current scheme, and (b) we don't handle

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,5 @@
pub use sys::imp::dynamic_lib::{
ENVVAR, SEPARATOR,
DynamicLibrary, Error,
open,
};
@@ -0,0 +1,53 @@
pub use sys::imp::env::{
Args, Vars, SplitPaths,
getcwd, chdir,
getenv, setenv, unsetenv,
home_dir, temp_dir, current_exe,
vars, args,
join_paths, join_paths_error,
split_paths,
FAMILY, OS,
DLL_PREFIX, DLL_SUFFIX, DLL_EXTENSION,
EXE_SUFFIX, EXE_EXTENSION,
};

use fmt;

pub struct JoinPathsError(());

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

impl fmt::Debug for JoinPathsError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
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,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,8 @@
pub use sys::imp::fs::{
ReadDir, DirEntry,
File, OpenOptions,
FileAttr, FileType, FilePermissions, FileHandle,
DirBuilder,
COPY_IMP, copy,
unlink, stat, lstat, rename, link, symlink, readlink, canonicalize, rmdir, readdir, set_perm,
};
@@ -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);
::core::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;
::core::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,104 @@
#![allow(missing_docs)]
#![doc(hidden)]

#[macro_use]
pub mod inner;
mod wtf8;
mod deps;

#[macro_use]
#[cfg(any(target_family = "unix", target_family = "windows"))]
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 mod thread_local;
pub mod unwind;
pub mod error;
pub mod time;
pub mod sync;
pub mod thread;
pub mod backtrace;
pub mod env;
pub mod stdio;
pub mod path;
pub mod stack_overflow;
pub mod rand;
pub mod fs;
pub mod dynamic_lib;
pub mod net;
pub mod os_str;
pub mod process;
pub mod rt;
pub mod c;

pub mod os;

#[cfg(target_family = "unix")]
pub mod imp {
pub use sys::unix::{
error,
env,
stdio,
path,
time,
thread,
stack_overflow,
rand,
dynamic_lib,
fs,
process,
backtrace,
};

pub use sys::common::{
thread_local,
unwind,
};

pub mod rt {
pub use sys::unix::rt::{
run_main, run_thread,
cleanup, thread_cleanup,
};
pub use sys::common::rt::min_stack;
}

pub mod sync {
pub use sys::unix::mutex::{Mutex, ReentrantMutex};
pub use sys::unix::condvar::Condvar;
pub use sys::unix::rwlock::RwLock;
}

pub mod net {
pub use sys::unix::net::Socket;
pub use sys::common::net::{
TcpListener, TcpStream, UdpSocket,
IpAddrV4, IpAddrV6,
SocketAddrV4, SocketAddrV6,
LookupHost, LookupAddr,
connect_tcp, bind_tcp, bind_udp,
lookup_host, lookup_addr,
};
}

pub mod c {
pub use libc::{
EINVAL, EIO,
EBADF,
strlen,
};
}

pub use sys::os_str::u8 as os_str;
}
@@ -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;
@@ -85,7 +85,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;
@@ -144,7 +144,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;
@@ -201,7 +201,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.
@@ -59,9 +59,8 @@ pub enum c_void {

#[cfg(test)]
mod tests {
use any::TypeId;
use libc;
use mem;
use core::mem;
use core::any::TypeId;

macro_rules! ok {
($($t:ident)*) => {$(
@@ -78,20 +77,25 @@ mod tests {
}

#[test]
#[cfg(any(unix, windows))]
fn same() {
use libc;

use os::raw;
ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
c_longlong c_ulonglong c_float c_double);
}

#[cfg(unix)]
fn unix() {
use libc;

{
use os::unix::raw;
ok!(uid_t gid_t dev_t ino_t mode_t nlink_t off_t blksize_t blkcnt_t);
}
{
use sys::platform::raw;
use unix::platform::raw;
ok_size!(stat);
}
}
@@ -12,11 +12,11 @@

#![stable(feature = "rust1", since = "1.0.0")]

use sys::inner::*;
use sys::os_str as sys;
use ffi::{OsStr, OsString};
use vec::Vec;
use mem;
use prelude::v1::*;
use sys::os_str::Buf;
use sys_common::{FromInner, IntoInner, AsInner};

/// Unix-specific extensions to `OsString`.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -33,7 +33,7 @@ pub trait OsStringExt {
#[stable(feature = "rust1", since = "1.0.0")]
impl OsStringExt for OsString {
fn from_vec(vec: Vec<u8>) -> OsString {
FromInner::from_inner(Buf { inner: vec })
FromInner::from_inner(sys::OsString::from_vec(vec))
}
fn into_vec(self) -> Vec<u8> {
self.into_inner().inner
@@ -44,6 +44,7 @@ impl OsStringExt for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
pub trait OsStrExt {
#[stable(feature = "rust1", since = "1.0.0")]
/// Creates an `OsStr from a byte slice.
fn from_bytes(slice: &[u8]) -> &Self;

/// Gets the underlying byte view of the `OsStr` slice.
Oops, something went wrong.