@@ -19,23 +19,20 @@
#![allow(missing_docs)]

use prelude::v1::*;
use sys::dynamic_lib as sys;

use env;
use ffi::{CString, OsString};
use ffi::OsString;
use mem;
use path::{Path, PathBuf};

pub struct DynamicLibrary {
handle: *mut u8
handle: sys::DynamicLibrary
}

impl Drop for DynamicLibrary {
fn drop(&mut self) {
match dl::check_for_errors_in(|| {
unsafe {
dl::close(self.handle)
}
}) {
match sys::DynamicLibrary::close(&self.handle) {
Ok(()) => {},
Err(str) => panic!("{}", str)
}
@@ -45,8 +42,8 @@ impl Drop for DynamicLibrary {
impl DynamicLibrary {
/// Lazily open a dynamic library. When passed None it gives a
/// handle to the calling process
pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
let maybe_library = dl::open(filename.map(|path| path.as_os_str()));
pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, sys::Error> {
let maybe_library = sys::open(filename.map(Path::as_os_str));

// The dynamic library must not be constructed if there is
// an error opening the library so the destructor does not
@@ -78,17 +75,11 @@ impl DynamicLibrary {
/// Returns the environment variable for this process's dynamic library
/// search path
pub fn envvar() -> &'static str {
if cfg!(windows) {
"PATH"
} else if cfg!(target_os = "macos") {
"DYLD_LIBRARY_PATH"
} else {
"LD_LIBRARY_PATH"
}
sys::ENVVAR
}

fn separator() -> &'static str {
if cfg!(windows) { ";" } else { ":" }
sys::SEPARATOR
}

/// Returns the current search path for dynamic libraries being used by this
@@ -101,14 +92,11 @@ impl DynamicLibrary {
}

/// Accesses the value at the symbol of the dynamic library.
pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, sys::Error> {
// This function should have a lifetime constraint of 'a on
// T but that feature is still unimplemented

let raw_string = CString::new(symbol).unwrap();
let maybe_symbol_value = dl::check_for_errors_in(|| {
dl::symbol(self.handle, raw_string.as_ptr())
});
let maybe_symbol_value = self.handle.symbol(symbol);

// The value must not be constructed if there is an error so
// the destructor does not run.
@@ -123,7 +111,7 @@ impl DynamicLibrary {
mod tests {
use super::*;
use prelude::v1::*;
use libc;
use sys::c::prelude as c;
use mem;
use path::Path;

@@ -139,7 +127,7 @@ mod tests {
Ok(libm) => libm
};

let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
let cosine: extern fn(c::c_double) -> c::c_double = unsafe {
match libm.symbol("cos") {
Err(error) => panic!("Could not load function cos: {}", error),
Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
@@ -173,203 +161,3 @@ mod tests {
}
}
}

#[cfg(any(target_os = "linux",
target_os = "android",
target_os = "macos",
target_os = "ios",
target_os = "freebsd",
target_os = "dragonfly",
target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd"))]
mod dl {
use prelude::v1::*;

use ffi::{CStr, OsStr};
use str;
use libc;
use ptr;

pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
check_for_errors_in(|| {
unsafe {
match filename {
Some(filename) => open_external(filename),
None => open_internal(),
}
}
})
}

const LAZY: libc::c_int = 1;

unsafe fn open_external(filename: &OsStr) -> *mut u8 {
let s = filename.to_cstring().unwrap();
dlopen(s.as_ptr(), LAZY) as *mut u8
}

unsafe fn open_internal() -> *mut u8 {
dlopen(ptr::null(), LAZY) as *mut u8
}

pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
use sync::StaticMutex;
static LOCK: StaticMutex = StaticMutex::new();
unsafe {
// dlerror isn't thread safe, so we need to lock around this entire
// sequence
let _guard = LOCK.lock();
let _old_error = dlerror();

let result = f();

let last_error = dlerror() as *const _;
let ret = if ptr::null() == last_error {
Ok(result)
} else {
let s = CStr::from_ptr(last_error).to_bytes();
Err(str::from_utf8(s).unwrap().to_owned())
};

ret
}
}

pub unsafe fn symbol(handle: *mut u8,
symbol: *const libc::c_char) -> *mut u8 {
dlsym(handle as *mut libc::c_void, symbol) as *mut u8
}
pub unsafe fn close(handle: *mut u8) {
dlclose(handle as *mut libc::c_void); ()
}

extern {
fn dlopen(filename: *const libc::c_char,
flag: libc::c_int) -> *mut libc::c_void;
fn dlerror() -> *mut libc::c_char;
fn dlsym(handle: *mut libc::c_void,
symbol: *const libc::c_char) -> *mut libc::c_void;
fn dlclose(handle: *mut libc::c_void) -> libc::c_int;
}
}

#[cfg(target_os = "windows")]
mod dl {
use prelude::v1::*;

use ffi::OsStr;
use libc;
use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
use sys::os;
use os::windows::prelude::*;
use ptr;
use sys::c::SetThreadErrorMode;

pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
// disable "dll load failed" error dialog.
let mut use_thread_mode = true;
let prev_error_mode = unsafe {
// SEM_FAILCRITICALERRORS 0x01
let new_error_mode = 1;
let mut prev_error_mode = 0;
// Windows >= 7 supports thread error mode.
let result = SetThreadErrorMode(new_error_mode, &mut prev_error_mode);
if result == 0 {
let err = os::errno();
if err as libc::c_int == ERROR_CALL_NOT_IMPLEMENTED {
use_thread_mode = false;
// SetThreadErrorMode not found. use fallback solution:
// SetErrorMode() Note that SetErrorMode is process-wide so
// this can cause race condition! However, since even
// Windows APIs do not care of such problem (#20650), we
// just assume SetErrorMode race is not a great deal.
prev_error_mode = SetErrorMode(new_error_mode);
}
}
prev_error_mode
};

unsafe {
SetLastError(0);
}

let result = match filename {
Some(filename) => {
let filename_str: Vec<_> =
filename.encode_wide().chain(Some(0)).collect();
let result = unsafe {
LoadLibraryW(filename_str.as_ptr() as *const libc::c_void)
};
// beware: Vec/String may change errno during drop!
// so we get error here.
if result == ptr::null_mut() {
let errno = os::errno();
Err(os::error_string(errno))
} else {
Ok(result as *mut u8)
}
}
None => {
let mut handle = ptr::null_mut();
let succeeded = unsafe {
GetModuleHandleExW(0 as libc::DWORD, ptr::null(), &mut handle)
};
if succeeded == libc::FALSE {
let errno = os::errno();
Err(os::error_string(errno))
} else {
Ok(handle as *mut u8)
}
}
};

unsafe {
if use_thread_mode {
SetThreadErrorMode(prev_error_mode, ptr::null_mut());
} else {
SetErrorMode(prev_error_mode);
}
}

result
}

pub fn check_for_errors_in<T, F>(f: F) -> Result<T, String> where
F: FnOnce() -> T,
{
unsafe {
SetLastError(0);

let result = f();

let error = os::errno();
if 0 == error {
Ok(result)
} else {
Err(format!("Error code {}", error))
}
}
}

pub unsafe fn symbol(handle: *mut u8, symbol: *const libc::c_char) -> *mut u8 {
GetProcAddress(handle as *mut libc::c_void, symbol) as *mut u8
}
pub unsafe fn close(handle: *mut u8) {
FreeLibrary(handle as *mut libc::c_void); ()
}

#[allow(non_snake_case)]
extern "system" {
fn SetLastError(error: libc::size_t);
fn LoadLibraryW(name: *const libc::c_void) -> *mut libc::c_void;
fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *const u16,
handle: *mut *mut libc::c_void) -> libc::BOOL;
fn GetProcAddress(handle: *mut libc::c_void,
name: *const libc::c_char) -> *mut libc::c_void;
fn FreeLibrary(handle: *mut libc::c_void);
fn SetErrorMode(uMode: libc::c_uint) -> libc::c_uint;
}
}

Large diffs are not rendered by default.

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

use sys::c::strlen;
use os::raw as libc;
use ascii;
use borrow::{Cow, ToOwned, Borrow};
use boxed::Box;
@@ -17,7 +19,6 @@ use error::Error;
use fmt::{self, Write};
use io;
use iter::Iterator;
use libc;
use mem;
use ops::Deref;
use option::Option::{self, Some, None};
@@ -222,7 +223,7 @@ impl CString {
/// using the pointer.
#[stable(feature = "cstr_memory", since = "1.4.0")]
pub unsafe fn from_raw(ptr: *mut libc::c_char) -> CString {
let len = libc::strlen(ptr) + 1; // Including the NUL byte
let len = strlen(ptr) + 1; // Including the NUL byte
let slice = slice::from_raw_parts(ptr, len as usize);
CString { inner: mem::transmute(slice) }
}
@@ -376,7 +377,7 @@ impl CStr {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_ptr<'a>(ptr: *const libc::c_char) -> &'a CStr {
let len = libc::strlen(ptr);
let len = strlen(ptr);
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
}

@@ -489,8 +490,8 @@ impl ToOwned for CStr {
#[cfg(test)]
mod tests {
use prelude::v1::*;
use sys::c::prelude as libc;
use super::*;
use libc;
use borrow::Cow::{Borrowed, Owned};
use hash::{SipHasher, Hash, Hasher};

@@ -29,6 +29,9 @@
//! for conversion to/from various other string types. Eventually these types
//! will offer a full-fledged string API.

use sys::os_str::{OsString as Buf, OsStr as Slice};
use sys::inner::*;

use borrow::{Borrow, Cow, ToOwned};
use ffi::CString;
use fmt::{self, Debug};
@@ -39,9 +42,6 @@ use cmp;
use hash::{Hash, Hasher};
use vec::Vec;

use sys::os_str::{Buf, Slice};
use sys_common::{AsInner, IntoInner, FromInner};

/// Owned, mutable OS strings.
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -73,18 +73,7 @@ impl OsString {
/// convert; non UTF-8 data will produce `None`.
#[unstable(feature = "convert", reason = "recently added", issue = "27704")]
pub fn from_bytes<B>(bytes: B) -> Option<OsString> where B: Into<Vec<u8>> {
Self::_from_bytes(bytes.into())
}

#[cfg(unix)]
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
use os::unix::ffi::OsStringExt;
Some(OsString::from_vec(vec))
}

#[cfg(windows)]
fn _from_bytes(vec: Vec<u8>) -> Option<OsString> {
String::from_utf8(vec).ok().map(OsString::from)
Buf::from_bytes(bytes.into()).map(FromInner::from_inner)
}

/// Converts to an `OsStr` slice.
@@ -128,7 +117,7 @@ impl ops::Index<ops::RangeFull> for OsString {

#[inline]
fn index(&self, _index: ops::RangeFull) -> &OsStr {
OsStr::from_inner(self.inner.as_slice())
FromInner::from_inner(self.inner.borrow())
}
}

@@ -220,10 +209,6 @@ impl OsStr {
s.as_ref()
}

fn from_inner(inner: &Slice) -> &OsStr {
unsafe { mem::transmute(inner) }
}

/// Yields a `&str` slice if the `OsStr` is valid unicode.
///
/// This conversion may entail doing a check for UTF-8 validity.
@@ -257,11 +242,7 @@ impl OsStr {
/// data. This may entail checking validity.
#[unstable(feature = "convert", reason = "recently added", issue = "27704")]
pub fn to_bytes(&self) -> Option<&[u8]> {
if cfg!(windows) {
self.to_str().map(|s| s.as_bytes())
} else {
Some(self.bytes())
}
self.inner.to_bytes()
}

/// Creates a `CString` containing this `OsStr` data.
@@ -385,7 +366,7 @@ impl AsRef<OsStr> for OsString {
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<OsStr> for str {
fn as_ref(&self) -> &OsStr {
OsStr::from_inner(Slice::from_str(self))
FromInner::from_inner(Slice::from_str(self))
}
}

@@ -408,6 +389,18 @@ impl IntoInner<Buf> for OsString {
}
}

impl AsInnerMut<Buf> for OsString {
fn as_inner_mut(&mut self) -> &mut Buf {
&mut self.inner
}
}

impl<'a> FromInner<&'a Slice> for &'a OsStr {
fn from_inner(inner: &Slice) -> Self {
unsafe { mem::transmute(inner) }
}
}

impl AsInner<Slice> for OsStr {
fn as_inner(&self) -> &Slice {
&self.inner
@@ -17,13 +17,14 @@

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

use sys::inner::*;
use sys::fs as fs_imp;

use fmt;
use ffi::OsString;
use io::{self, SeekFrom, Seek, Read, Write};
use borrow::ToOwned;
use ffi::{OsStr, OsString};
use io::{self, SeekFrom, Seek, Read, Write, read_to_end_uninitialized};
use path::{Path, PathBuf};
use sys::fs as fs_imp;
use sys_common::io::read_to_end_uninitialized;
use sys_common::{AsInnerMut, FromInner, AsInner, IntoInner};
use vec::Vec;

/// A reference to an open file on the filesystem.
@@ -230,7 +231,7 @@ impl File {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_all(&self) -> io::Result<()> {
self.inner.fsync()
self.inner.fsync().map_err(From::from)
}

/// This function is similar to `sync_all`, except that it may not
@@ -259,7 +260,7 @@ impl File {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_data(&self) -> io::Result<()> {
self.inner.datasync()
self.inner.datasync().map_err(From::from)
}

/// Truncates or extends the underlying file, updating the size of
@@ -287,7 +288,7 @@ impl File {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_len(&self, size: u64) -> io::Result<()> {
self.inner.truncate(size)
self.inner.truncate(size).map_err(From::from)
}

/// Queries metadata about the underlying file.
@@ -305,7 +306,7 @@ impl File {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.inner.file_attr().map(Metadata)
self.inner.file_attr().map(Metadata).map_err(From::from)
}
}

@@ -325,14 +326,14 @@ impl IntoInner<fs_imp::File> for File {

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

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
self.inner.read(buf).map_err(From::from)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
unsafe { read_to_end_uninitialized(self, buf) }
@@ -341,33 +342,37 @@ impl Read for File {
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
self.inner.write(buf).map_err(From::from)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush().map_err(From::from)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Seek for File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
self.inner.seek(pos).map_err(From::from)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a File {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.inner.read(buf)
self.inner.read(buf).map_err(From::from)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a File {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.inner.write(buf)
self.inner.write(buf).map_err(From::from)
}
fn flush(&mut self) -> io::Result<()> {
self.inner.flush().map_err(From::from)
}
fn flush(&mut self) -> io::Result<()> { self.inner.flush() }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Seek for &'a File {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
self.inner.seek(pos)
self.inner.seek(pos).map_err(From::from)
}
}

@@ -498,7 +503,7 @@ impl OpenOptions {
}

fn _open(&self, path: &Path) -> io::Result<File> {
let inner = try!(fs_imp::File::open(path, &self.0));
let inner = try!(fs_imp::File::open(path.as_os_str(), &self.0));
Ok(File { inner: inner })
}
}
@@ -672,7 +677,7 @@ impl Iterator for ReadDir {
type Item = io::Result<DirEntry>;

fn next(&mut self) -> Option<io::Result<DirEntry>> {
self.0.next().map(|entry| entry.map(DirEntry))
self.0.next().map(|entry| entry.map(DirEntry).map_err(From::from))
}
}

@@ -706,7 +711,7 @@ impl DirEntry {
///
/// The exact text, of course, depends on what files you have in `.`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn path(&self) -> PathBuf { self.0.path() }
pub fn path(&self) -> PathBuf { Path::new(self.0.root()).join(self.file_name()) }

/// Return the metadata for the file that this entry points at.
///
@@ -720,7 +725,7 @@ impl DirEntry {
/// calling `symlink_metadata` on the path.
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn metadata(&self) -> io::Result<Metadata> {
self.0.metadata().map(Metadata)
self.0.metadata().map(Metadata).map_err(From::from)
}

/// Return the file type for the file that this entry points at.
@@ -735,14 +740,15 @@ impl DirEntry {
/// call to `symlink_metadata` to learn about the target file type.
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_type(&self) -> io::Result<FileType> {
self.0.file_type().map(FileType)
self.0.file_type().map(FileType).map_err(From::from)
}

/// Returns the bare file name of this directory entry without any other
/// leading path component.
#[stable(feature = "dir_entry_ext", since = "1.1.0")]
pub fn file_name(&self) -> OsString {
self.0.file_name()
let name: &OsStr = self.0.file_name();
name.to_owned()
}
}

@@ -774,7 +780,7 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs_imp::unlink(path.as_ref())
fs_imp::unlink(path.as_ref().as_os_str()).map_err(From::from)
}

/// Given a path, query the file system to get information about a file,
@@ -802,7 +808,7 @@ pub fn remove_file<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// is no entry in the filesystem at the provided path.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
fs_imp::stat(path.as_ref()).map(Metadata)
fs_imp::stat(path.as_ref().as_os_str()).map(Metadata).map_err(From::from)
}

/// Query the metadata about a file without following symlinks.
@@ -820,7 +826,7 @@ pub fn metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
/// ```
#[stable(feature = "symlink_metadata", since = "1.1.0")]
pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
fs_imp::lstat(path.as_ref()).map(Metadata)
fs_imp::lstat(path.as_ref().as_os_str()).map(Metadata).map_err(From::from)
}

/// Rename a file or directory to a new name.
@@ -846,7 +852,7 @@ pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> io::Result<Metadata> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
fs_imp::rename(from.as_ref(), to.as_ref())
fs_imp::rename(from.as_ref().as_os_str(), to.as_ref().as_os_str()).map_err(From::from)
}

/// Copies the contents of one file to another. This function will also
@@ -880,7 +886,28 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
fs_imp::copy(from.as_ref(), to.as_ref())
if fs_imp::COPY_IMP {
fs_imp::copy(from.as_ref().as_os_str(), to.as_ref().as_os_str()).map_err(From::from)
} else {
use fs::{File, PathExt, set_permissions};
use io::{Error, ErrorKind};

let from = from.as_ref();
let to = to.as_ref();

if !from.is_file() {
return Err(Error::new(ErrorKind::InvalidInput,
"the source path is not an existing regular file"))
}

let mut reader = try!(File::open(from));
let mut writer = try!(File::create(to));
let perm = try!(reader.metadata()).permissions();

let ret = try!(io::copy(&mut reader, &mut writer));
try!(set_permissions(to, perm));
Ok(ret)
}
}

/// Creates a new hard link on the filesystem.
@@ -900,7 +927,7 @@ pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<u64> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
fs_imp::link(src.as_ref(), dst.as_ref())
fs_imp::link(src.as_ref().as_os_str(), dst.as_ref().as_os_str()).map_err(From::from)
}

/// Creates a new symbolic link on the filesystem.
@@ -926,7 +953,7 @@ pub fn hard_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
std::os::windows::fs::{symlink_file, symlink_dir}")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()> {
fs_imp::symlink(src.as_ref(), dst.as_ref())
fs_imp::symlink(src.as_ref().as_os_str(), dst.as_ref().as_os_str()).map_err(From::from)
}

/// Reads a symbolic link, returning the file that the link points to.
@@ -949,15 +976,15 @@ pub fn soft_link<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<(
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
fs_imp::readlink(path.as_ref())
fs_imp::readlink(path.as_ref().as_os_str()).map(From::from).map_err(From::from)
}

/// Returns the canonical form of a path with all intermediate components
/// normalized and symbolic links resolved.
#[unstable(feature = "fs_canonicalize", reason = "recently added API",
issue = "27706")]
pub fn canonicalize<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
fs_imp::canonicalize(path.as_ref())
fs_imp::canonicalize(path.as_ref().as_os_str()).map(From::from).map_err(From::from)
}

/// Creates a new, empty directory at the provided path
@@ -1026,7 +1053,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
fs_imp::rmdir(path.as_ref())
fs_imp::rmdir(path.as_ref().as_os_str()).map_err(From::from)
}

/// Removes a directory at this path, after removing all its contents. Use
@@ -1102,7 +1129,7 @@ fn _remove_dir_all(path: &Path) -> io::Result<()> {
/// at a non-directory file
#[stable(feature = "rust1", since = "1.0.0")]
pub fn read_dir<P: AsRef<Path>>(path: P) -> io::Result<ReadDir> {
fs_imp::readdir(path.as_ref()).map(ReadDir)
fs_imp::readdir(path.as_ref().as_os_str()).map(ReadDir).map_err(From::from)
}

/// Returns an iterator that will recursively walk the directory structure
@@ -1254,7 +1281,7 @@ impl PathExt for Path {
#[stable(feature = "set_permissions", since = "1.1.0")]
pub fn set_permissions<P: AsRef<Path>>(path: P, perm: Permissions)
-> io::Result<()> {
fs_imp::set_perm(path.as_ref(), perm.0)
fs_imp::set_perm(path.as_ref().as_os_str(), perm.0).map_err(From::from)
}

#[unstable(feature = "dir_builder", reason = "recently added API",
@@ -1289,7 +1316,7 @@ impl DirBuilder {
if self.recursive {
self.create_dir_all(path)
} else {
self.inner.mkdir(path)
self.inner.mkdir(path.as_os_str()).map_err(From::from)
}
}

@@ -1298,7 +1325,7 @@ impl DirBuilder {
if let Some(p) = path.parent() {
try!(self.create_dir_all(p))
}
self.inner.mkdir(path)
self.inner.mkdir(path.as_os_str()).map_err(From::from)
}
}

@@ -8,14 +8,17 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use sys::inner::*;
use sys::error as sys;
use sys::c as c;

use boxed::Box;
use convert::Into;
use error;
use fmt;
use marker::{Send, Sync};
use option::Option::{self, Some, None};
use result;
use sys;

/// A specialized [`Result`][result] type for I/O operations.
///
@@ -64,7 +67,7 @@ pub struct Error {
}

enum Repr {
Os(i32),
Os(sys::Error),
Custom(Box<Custom>),
}

@@ -210,13 +213,13 @@ impl Error {
/// `Error` for the error code.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn last_os_error() -> Error {
Error::from_raw_os_error(sys::os::errno() as i32)
Error::from(sys::expect_last_error())
}

/// Creates a new instance of an `Error` from a particular OS error code.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn from_raw_os_error(code: i32) -> Error {
Error { repr: Repr::Os(code) }
Error::from(sys::Error::from_code(code))
}

/// Returns the OS error that this error represents (if any).
@@ -227,7 +230,7 @@ impl Error {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn raw_os_error(&self) -> Option<i32> {
match self.repr {
Repr::Os(i) => Some(i),
Repr::Os(ref i) => Some(i.code()),
Repr::Custom(..) => None,
}
}
@@ -273,7 +276,7 @@ impl Error {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn kind(&self) -> ErrorKind {
match self.repr {
Repr::Os(code) => sys::decode_error_kind(code),
Repr::Os(ref e) => e.kind(),
Repr::Custom(ref c) => c.kind,
}
}
@@ -282,9 +285,9 @@ impl Error {
impl fmt::Debug for Repr {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match *self {
Repr::Os(ref code) =>
fmt.debug_struct("Os").field("code", code)
.field("message", &sys::os::error_string(*code)).finish(),
Repr::Os(ref e) =>
fmt.debug_struct("Os").field("code", &e.code())
.field("message", &e.description().to_string_lossy()).finish(),
Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
}
}
@@ -294,9 +297,9 @@ impl fmt::Debug for Repr {
impl fmt::Display for Error {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
match self.repr {
Repr::Os(code) => {
let detail = sys::os::error_string(code);
write!(fmt, "{} (os error {})", detail, code)
Repr::Os(ref e) => {
let detail = e.description();
write!(fmt, "{} (os error {})", detail.to_string_lossy(), e.code())
}
Repr::Custom(ref c) => c.error.fmt(fmt),
}
@@ -320,6 +323,18 @@ impl error::Error for Error {
}
}

impl From<sys::Error> for Error {
fn from(e: sys::Error) -> Self {
Error { repr: Repr::Os(e) }
}
}

impl IntoInner<sys::Error> for Error {
fn into_inner(self) -> sys::Error {
sys::Error::from_code(self.raw_os_error().unwrap_or(c::EINVAL))
}
}

fn _assert_error_is_sync_send() {
fn _is_sync_send<T: Sync+Send>() {}
_is_sync_send::<Error>();
@@ -328,17 +343,18 @@ fn _assert_error_is_sync_send() {
#[cfg(test)]
mod test {
use prelude::v1::*;
use sys::error as sys;
use super::{Error, ErrorKind};
use error;
use error::Error as error_Error;
use fmt;
use sys::os::error_string;

#[test]
fn test_debug_error() {
let code = 6;
let msg = error_string(code);
let err = Error { repr: super::Repr::Os(code) };
let msg = sys::Error::from_code(code).description();
let msg = msg.to_str().unwrap();
let err = Error { repr: super::Repr::Os(sys::Error::from_code(code)) };
let expected = format!("Error {{ repr: Os {{ code: {:?}, message: {:?} }} }}", code, msg);
assert_eq!(format!("{:?}", err), expected);
}
@@ -12,8 +12,8 @@ use prelude::v1::*;

use cell::Cell;
use ptr;
use at_exit;
use sync::{StaticMutex, Arc};
use sys_common;

pub struct Lazy<T> {
lock: StaticMutex,
@@ -51,7 +51,7 @@ impl<T: Send + Sync + 'static> Lazy<T> {
// `Arc` allocation in our own internal box (it will get deallocated by
// the at exit handler). Otherwise we just return the freshly allocated
// `Arc`.
let registered = sys_common::at_exit(move || {
let registered = at_exit::at_exit(move || {
let g = self.lock.lock();
let ptr = self.ptr.get();
self.ptr.set(1 as *mut _);
@@ -264,6 +264,7 @@ pub use self::stdio::{stdin, stdout, stderr, _print, Stdin, Stdout, Stderr};
pub use self::stdio::{StdoutLock, StderrLock, StdinLock};
#[doc(no_inline, hidden)]
pub use self::stdio::{set_panic, set_print};
pub use self::read_uninitialized::read_to_end_uninitialized;

pub mod prelude;
mod buffered;
@@ -273,6 +274,7 @@ mod impls;
mod lazy;
mod util;
mod stdio;
mod read_uninitialized;

const DEFAULT_BUF_SIZE: usize = 64 * 1024;

@@ -13,16 +13,17 @@ use io::ErrorKind;
use io::Read;
use slice::from_raw_parts_mut;

// Provides read_to_end functionality over an uninitialized buffer.
// This function is unsafe because it calls the underlying
// read function with a slice into uninitialized memory. The default
// implementation of read_to_end for readers will zero out new memory in
// the buf before passing it to read, but avoiding this zero can often
// lead to a fairly significant performance win.
//
// Implementations using this method have to adhere to two guarantees:
// * The implementation of read never reads the buffer provided.
// * The implementation of read correctly reports how many bytes were written.
/// Provides read_to_end functionality over an uninitialized buffer.
/// This function is unsafe because it calls the underlying
/// read function with a slice into uninitialized memory. The default
/// implementation of read_to_end for readers will zero out new memory in
/// the buf before passing it to read, but avoiding this zero can often
/// lead to a fairly significant performance win.
///
/// Implementations using this method have to adhere to two guarantees:
/// * The implementation of read never reads the buffer provided.
/// * The implementation of read correctly reports how many bytes were written.
#[unstable(feature = "read_to_end_uninitialized", reason = "unsure", issue = "0")]
pub unsafe fn read_to_end_uninitialized(r: &mut Read, buf: &mut Vec<u8>) -> io::Result<usize> {

let start_len = buf.len();
@@ -11,16 +11,24 @@
use prelude::v1::*;
use io::prelude::*;

use sys::stdio as sys;

use cell::{RefCell, BorrowState};
use cmp;
use fmt;
use io::lazy::Lazy;
use io::{self, BufReader, LineWriter};
use io::{self, BufReader, LineWriter, read_to_end_uninitialized};
use sync::{Arc, Mutex, MutexGuard};
use sys::stdio;
use sys_common::io::{read_to_end_uninitialized};
use sys_common::remutex::{ReentrantMutex, ReentrantMutexGuard};
use libc;
use sync::{ReentrantMutex, ReentrantMutexGuard};

fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
use sys::c;

match r {
Err(ref e) if e.raw_os_error() == Some(c::EBADF) => Ok(default),
r => r
}
}

/// Stdout used by print! and println! macros
thread_local! {
@@ -33,19 +41,19 @@ thread_local! {
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stdin_raw` function.
struct StdinRaw(stdio::Stdin);
type StdinRaw = sys::Stdin;

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stdout_raw` function.
struct StdoutRaw(stdio::Stdout);
type StdoutRaw = sys::Stdout;

/// A handle to a raw instance of the standard output stream of this process.
///
/// This handle is not synchronized or buffered in any fashion. Constructed via
/// the `std::io::stdio::stderr_raw` function.
struct StderrRaw(stdio::Stderr);
type StderrRaw = sys::Stderr;

/// Constructs a new raw handle to the standard input of this process.
///
@@ -54,7 +62,7 @@ struct StderrRaw(stdio::Stderr);
/// handles is **not** available to raw handles returned from this function.
///
/// The returned handle has no external synchronization or buffering.
fn stdin_raw() -> io::Result<StdinRaw> { stdio::Stdin::new().map(StdinRaw) }
fn stdin_raw() -> io::Result<StdinRaw> { sys::stdin().map_err(From::from) }

/// Constructs a new raw handle to the standard output stream of this process.
///
@@ -65,7 +73,7 @@ fn stdin_raw() -> io::Result<StdinRaw> { stdio::Stdin::new().map(StdinRaw) }
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
fn stdout_raw() -> io::Result<StdoutRaw> { stdio::Stdout::new().map(StdoutRaw) }
fn stdout_raw() -> io::Result<StdoutRaw> { sys::stdout().map_err(From::from) }

/// Constructs a new raw handle to the standard error stream of this process.
///
@@ -74,19 +82,7 @@ fn stdout_raw() -> io::Result<StdoutRaw> { stdio::Stdout::new().map(StdoutRaw) }
///
/// The returned handle has no external synchronization or buffering layered on
/// top.
fn stderr_raw() -> io::Result<StderrRaw> { stdio::Stderr::new().map(StderrRaw) }

impl Read for StdinRaw {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
}
impl Write for StdoutRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
impl Write for StderrRaw {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
}
fn stderr_raw() -> io::Result<StderrRaw> { sys::stderr().map_err(From::from) }

enum Maybe<T> {
Real(T),
@@ -96,14 +92,14 @@ enum Maybe<T> {
impl<W: io::Write> io::Write for Maybe<W> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
match *self {
Maybe::Real(ref mut w) => handle_ebadf(w.write(buf), buf.len()),
Maybe::Real(ref mut w) => handle_ebadf(w.write(buf), buf.len()).map_err(From::from),
Maybe::Fake => Ok(buf.len())
}
}

fn flush(&mut self) -> io::Result<()> {
match *self {
Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()),
Maybe::Real(ref mut w) => handle_ebadf(w.flush(), ()).map_err(From::from),
Maybe::Fake => Ok(())
}
}
@@ -112,24 +108,12 @@ impl<W: io::Write> io::Write for Maybe<W> {
impl<R: io::Read> io::Read for Maybe<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match *self {
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), buf.len()),
Maybe::Real(ref mut r) => handle_ebadf(r.read(buf), buf.len()).map_err(From::from),
Maybe::Fake => Ok(0)
}
}
}

fn handle_ebadf<T>(r: io::Result<T>, default: T) -> io::Result<T> {
#[cfg(windows)]
const ERR: libc::c_int = libc::ERROR_INVALID_HANDLE;
#[cfg(not(windows))]
const ERR: libc::c_int = libc::EBADF;

match r {
Err(ref e) if e.raw_os_error() == Some(ERR) => Ok(default),
r => r
}
}

/// A handle to the standard input stream of a process.
///
/// Each handle is a shared reference to a global buffer of input data to this
@@ -540,6 +524,7 @@ impl<'a> Write for StderrLock<'a> {
pub fn set_panic(sink: Box<Write + Send>) -> Option<Box<Write + Send>> {
use panicking::LOCAL_STDERR;
use mem;

LOCAL_STDERR.with(move |slot| {
mem::replace(&mut *slot.borrow_mut(), Some(sink))
}).and_then(|mut s| {
@@ -209,7 +209,6 @@
#![feature(associated_consts)]
#![feature(borrow_state)]
#![feature(box_syntax)]
#![feature(cfg_target_vendor)]
#![feature(char_from_unchecked)]
#![feature(char_internals)]
#![feature(clone_from_slice)]
@@ -227,11 +226,11 @@
#![feature(into_cow)]
#![feature(iter_order)]
#![feature(lang_items)]
#![feature(libc)]
#![feature(linkage, thread_local, asm)]
#![feature(macro_reexport)]
#![feature(slice_concat_ext)]
#![feature(no_std)]
#![feature(nonzero)]
#![feature(oom)]
#![feature(optin_builtin_traits)]
#![feature(placement_in_syntax)]
@@ -249,15 +248,16 @@
#![feature(dropck_parametricity)]
#![feature(unsafe_no_drop_flag, filling_drop)]
#![feature(decode_utf16)]
#![feature(unwind_attributes)]
#![feature(vec_push_all)]
#![feature(vec_resize)]
#![feature(wrapping)]
#![feature(zero_one)]
#![feature(libc)]
#![cfg_attr(windows, feature(str_utf16))]
#![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras))]
#![cfg_attr(test, feature(test, rustc_private))]
#![cfg_attr(target_env = "msvc", feature(link_args))]
#![cfg_attr(target_os = "netbsd", feature(cfg_target_vendor))]

// Don't link to std. We are std.
#![no_std]
@@ -325,8 +325,6 @@ pub use rustc_unicode::char;
#[macro_use]
mod macros;

mod rtdeps;

/* The Prelude. */

pub mod prelude;
@@ -350,8 +348,8 @@ pub use core::u16;
pub use core::u32;
pub use core::u64;

#[path = "num/f32.rs"] pub mod f32;
#[path = "num/f64.rs"] pub mod f64;
#[path = "num/f32.rs"] pub mod f32;
#[path = "num/f64.rs"] pub mod f64;

pub mod ascii;

@@ -364,29 +362,26 @@ pub mod num;
#[macro_use]
pub mod thread;

mod sys;

pub use sys::os;

pub mod collections;
pub mod dynamic_lib;
pub mod env;
pub mod ffi;
pub mod fs;
pub mod io;
pub mod net;
pub mod os;
pub mod path;
pub mod process;
pub mod sync;
pub mod time;

#[macro_use]
#[path = "sys/common/mod.rs"] mod sys_common;

#[cfg(unix)]
#[path = "sys/unix/mod.rs"] mod sys;
#[cfg(windows)]
#[path = "sys/windows/mod.rs"] mod sys;

pub mod rt;
mod panicking;
mod backtrace;
mod at_exit;

mod rand;

// Some external utilities of the standard library rely on randomness (aka
@@ -400,6 +395,16 @@ pub mod __rand {
pub use rand::{thread_rng, ThreadRng, Rng};
}

// Reexport some of our utilities which are expected by other crates.
#[doc(hidden)]
#[unstable(feature = "rt",
reason = "this public module should not exist and is highly likely \
to disappear",
issue = "0")]
pub mod rt {
pub use sys::unwind::{begin_unwind_fmt, begin_unwind};
}

// Include a number of private modules that exist solely to provide
// the rustdoc documentation for primitive types. Using `include!`
// because rustdoc only looks for these modules at the crate level.
@@ -9,15 +9,14 @@
// except according to those terms.

use prelude::v1::*;
use sys::inner::*;
use sys::net as sys;

use fmt;
use hash;
use io;
use libc::{self, socklen_t, sa_family_t};
use mem;
use net::{lookup_host, ntoh, hton, IpAddr, Ipv4Addr, Ipv6Addr};
use net::{lookup_host, IpAddr, Ipv4Addr, Ipv6Addr};
use option;
use sys_common::{FromInner, AsInner, IntoInner};
use vec;

/// Representation of a socket address for networking applications.
@@ -39,12 +38,12 @@ pub enum SocketAddr {
/// An IPv4 socket address which is a (ip, port) combination.
#[derive(Copy)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct SocketAddrV4 { inner: libc::sockaddr_in }
pub struct SocketAddrV4 { inner: sys::SocketAddrV4 }

/// An IPv6 socket address.
#[derive(Copy)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct SocketAddrV6 { inner: libc::sockaddr_in6 }
pub struct SocketAddrV6 { inner: sys::SocketAddrV6 }

impl SocketAddr {
/// Creates a new socket address from the (ip, port) pair.
@@ -80,26 +79,17 @@ impl SocketAddrV4 {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(ip: Ipv4Addr, port: u16) -> SocketAddrV4 {
SocketAddrV4 {
inner: libc::sockaddr_in {
sin_family: libc::AF_INET as sa_family_t,
sin_port: hton(port),
sin_addr: *ip.as_inner(),
.. unsafe { mem::zeroed() }
},
inner: sys::SocketAddrV4::new(*ip.as_inner(), port),
}
}

/// Returns the IP address associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ip(&self) -> &Ipv4Addr {
unsafe {
&*(&self.inner.sin_addr as *const libc::in_addr as *const Ipv4Addr)
}
}
pub fn ip(&self) -> &Ipv4Addr { FromInner::from_inner(self.inner.addr()) }

/// Returns the port number associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { ntoh(self.inner.sin_port) }
pub fn port(&self) -> u16 { self.inner.port() }
}

impl SocketAddrV6 {
@@ -109,65 +99,71 @@ impl SocketAddrV6 {
pub fn new(ip: Ipv6Addr, port: u16, flowinfo: u32, scope_id: u32)
-> SocketAddrV6 {
SocketAddrV6 {
inner: libc::sockaddr_in6 {
sin6_family: libc::AF_INET6 as sa_family_t,
sin6_port: hton(port),
sin6_addr: *ip.as_inner(),
sin6_flowinfo: hton(flowinfo),
sin6_scope_id: hton(scope_id),
.. unsafe { mem::zeroed() }
},
inner: sys::SocketAddrV6::new(*ip.as_inner(), port, flowinfo, scope_id),
}
}

/// Returns the IP address associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn ip(&self) -> &Ipv6Addr {
unsafe {
&*(&self.inner.sin6_addr as *const libc::in6_addr as *const Ipv6Addr)
}
}
pub fn ip(&self) -> &Ipv6Addr { FromInner::from_inner(self.inner.addr()) }

/// Returns the port number associated with this socket address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn port(&self) -> u16 { ntoh(self.inner.sin6_port) }
pub fn port(&self) -> u16 { self.inner.port() }

/// Returns scope ID associated with this address, corresponding to the
/// `sin6_flowinfo` field in C.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn flowinfo(&self) -> u32 { ntoh(self.inner.sin6_flowinfo) }
pub fn flowinfo(&self) -> u32 { self.inner.flowinfo() }

/// Returns scope ID associated with this address, corresponding to the
/// `sin6_scope_id` field in C.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn scope_id(&self) -> u32 { ntoh(self.inner.sin6_scope_id) }
pub fn scope_id(&self) -> u32 { self.inner.scope_id() }
}

impl FromInner<libc::sockaddr_in> for SocketAddrV4 {
fn from_inner(addr: libc::sockaddr_in) -> SocketAddrV4 {
impl FromInner<sys::SocketAddrV4> for SocketAddrV4 {
fn from_inner(addr: sys::SocketAddrV4) -> SocketAddrV4 {
SocketAddrV4 { inner: addr }
}
}

impl FromInner<libc::sockaddr_in6> for SocketAddrV6 {
fn from_inner(addr: libc::sockaddr_in6) -> SocketAddrV6 {
impl FromInner<sys::SocketAddrV6> for SocketAddrV6 {
fn from_inner(addr: sys::SocketAddrV6) -> SocketAddrV6 {
SocketAddrV6 { inner: addr }
}
}

impl<'a> IntoInner<(*const libc::sockaddr, socklen_t)> for &'a SocketAddr {
fn into_inner(self) -> (*const libc::sockaddr, socklen_t) {
impl FromInner<sys::SocketAddr> for SocketAddr {
fn from_inner(addr: sys::SocketAddr) -> SocketAddr {
match addr {
sys::SocketAddr::V4(addr) => SocketAddr::V4(FromInner::from_inner(addr)),
sys::SocketAddr::V6(addr) => SocketAddr::V6(FromInner::from_inner(addr)),
}
}
}

impl<'a> IntoInner<sys::SocketAddr> for &'a SocketAddr {
fn into_inner(self) -> sys::SocketAddr {
match *self {
SocketAddr::V4(ref a) => {
(a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
}
SocketAddr::V6(ref a) => {
(a as *const _ as *const _, mem::size_of_val(a) as socklen_t)
}
SocketAddr::V4(ref addr) => sys::SocketAddr::V4(*addr.as_inner()),
SocketAddr::V6(ref addr) => sys::SocketAddr::V6(*addr.as_inner()),
}
}
}

impl AsInner<sys::SocketAddrV4> for SocketAddrV4 {
fn as_inner(&self) -> &sys::SocketAddrV4 {
&self.inner
}
}

impl AsInner<sys::SocketAddrV6> for SocketAddrV6 {
fn as_inner(&self) -> &sys::SocketAddrV6 {
&self.inner
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for SocketAddr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -218,17 +214,13 @@ impl Clone for SocketAddrV6 {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for SocketAddrV4 {
fn eq(&self, other: &SocketAddrV4) -> bool {
self.inner.sin_port == other.inner.sin_port &&
self.inner.sin_addr.s_addr == other.inner.sin_addr.s_addr
self.inner == other.inner
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for SocketAddrV6 {
fn eq(&self, other: &SocketAddrV6) -> bool {
self.inner.sin6_port == other.inner.sin6_port &&
self.inner.sin6_addr.s6_addr == other.inner.sin6_addr.s6_addr &&
self.inner.sin6_flowinfo == other.inner.sin6_flowinfo &&
self.inner.sin6_scope_id == other.inner.sin6_scope_id
self.inner == other.inner
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -239,14 +231,13 @@ impl Eq for SocketAddrV6 {}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for SocketAddrV4 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.inner.sin_port, self.inner.sin_addr.s_addr).hash(s)
self.inner.hash(s)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for SocketAddrV6 {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
(self.inner.sin6_port, &self.inner.sin6_addr.s6_addr,
self.inner.sin6_flowinfo, self.inner.sin6_scope_id).hash(s)
self.inner.hash(s)
}
}

@@ -14,13 +14,13 @@
issue = "27709")]

use prelude::v1::*;
use sys::inner::*;
use sys::net as sys;

use cmp::Ordering;
use hash;
use fmt;
use libc;
use sys_common::{AsInner, FromInner};
use net::{hton, ntoh};
use mem;

/// An IP address, either an IPv4 or IPv6 address.
#[unstable(feature = "ip_addr", reason = "recent addition", issue = "27801")]
@@ -36,14 +36,14 @@ pub enum IpAddr {
#[derive(Copy)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Ipv4Addr {
inner: libc::in_addr,
inner: sys::IpAddrV4,
}

/// Representation of an IPv6 address.
#[derive(Copy)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Ipv6Addr {
inner: libc::in6_addr,
inner: sys::IpAddrV6,
}

#[allow(missing_docs)]
@@ -58,32 +58,35 @@ pub enum Ipv6MulticastScope {
Global
}

impl IntoInner<sys::IpAddr> for IpAddr {
fn into_inner(self) -> sys::IpAddr {
match self {
IpAddr::V4(addr) => sys::IpAddr::V4(*addr.as_inner()),
IpAddr::V6(addr) => sys::IpAddr::V6(*addr.as_inner()),
}
}
}

impl Ipv4Addr {
/// Creates a new IPv4 address from four eight-bit octets.
///
/// The result will represent the IP address `a`.`b`.`c`.`d`.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr {
Ipv4Addr {
inner: libc::in_addr {
s_addr: hton(((a as u32) << 24) |
((b as u32) << 16) |
((c as u32) << 8) |
(d as u32)),
}
inner: sys::IpAddrV4::new(a, b, c, d),
}
}

/// Returns the four eight-bit integers that make up this address.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn octets(&self) -> [u8; 4] {
let bits = ntoh(self.inner.s_addr);
[(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8]
self.inner.octets()
}

/// Returns true for the special 'unspecified' address 0.0.0.0.
pub fn is_unspecified(&self) -> bool {
self.inner.s_addr == 0
self.octets() == [0; 4]
}

/// Returns true if this is a loopback address (127.0.0.0/8).
@@ -211,7 +214,7 @@ impl Clone for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for Ipv4Addr {
fn eq(&self, other: &Ipv4Addr) -> bool {
self.inner.s_addr == other.inner.s_addr
self.inner == other.inner
}
}

@@ -221,7 +224,7 @@ impl Eq for Ipv4Addr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for Ipv4Addr {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.inner.s_addr.hash(s)
self.inner.hash(s)
}
}

@@ -235,19 +238,26 @@ impl PartialOrd for Ipv4Addr {
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for Ipv4Addr {
fn cmp(&self, other: &Ipv4Addr) -> Ordering {
self.inner.s_addr.cmp(&other.inner.s_addr)
self.inner.cmp(&other.inner)
}
}

impl AsInner<libc::in_addr> for Ipv4Addr {
fn as_inner(&self) -> &libc::in_addr { &self.inner }
impl AsInner<sys::IpAddrV4> for Ipv4Addr {
fn as_inner(&self) -> &sys::IpAddrV4 { &self.inner }
}
impl FromInner<libc::in_addr> for Ipv4Addr {
fn from_inner(addr: libc::in_addr) -> Ipv4Addr {

impl FromInner<sys::IpAddrV4> for Ipv4Addr {
fn from_inner(addr: sys::IpAddrV4) -> Ipv4Addr {
Ipv4Addr { inner: addr }
}
}

impl<'a> FromInner<&'a sys::IpAddrV4> for &'a Ipv4Addr {
fn from_inner(addr: &'a sys::IpAddrV4) -> &'a Ipv4Addr {
unsafe { mem::transmute(addr) }
}
}

#[stable(feature = "ip_u32", since = "1.1.0")]
impl From<Ipv4Addr> for u32 {
fn from(ip: Ipv4Addr) -> u32 {
@@ -271,24 +281,14 @@ impl Ipv6Addr {
pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16,
h: u16) -> Ipv6Addr {
Ipv6Addr {
inner: libc::in6_addr {
s6_addr: [hton(a), hton(b), hton(c), hton(d),
hton(e), hton(f), hton(g), hton(h)]
}
inner: sys::IpAddrV6::new(a, b, c, d, e, f, g, h),
}
}

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

/// Returns true for the special 'unspecified' address ::.
@@ -474,7 +474,7 @@ impl Clone for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for Ipv6Addr {
fn eq(&self, other: &Ipv6Addr) -> bool {
self.inner.s6_addr == other.inner.s6_addr
self.inner == other.inner
}
}

@@ -484,7 +484,7 @@ impl Eq for Ipv6Addr {}
#[stable(feature = "rust1", since = "1.0.0")]
impl hash::Hash for Ipv6Addr {
fn hash<H: hash::Hasher>(&self, s: &mut H) {
self.inner.s6_addr.hash(s)
self.inner.hash(s)
}
}

@@ -498,19 +498,26 @@ impl PartialOrd for Ipv6Addr {
#[stable(feature = "rust1", since = "1.0.0")]
impl Ord for Ipv6Addr {
fn cmp(&self, other: &Ipv6Addr) -> Ordering {
self.inner.s6_addr.cmp(&other.inner.s6_addr)
self.inner.cmp(&other.inner)
}
}

impl AsInner<libc::in6_addr> for Ipv6Addr {
fn as_inner(&self) -> &libc::in6_addr { &self.inner }
impl AsInner<sys::IpAddrV6> for Ipv6Addr {
fn as_inner(&self) -> &sys::IpAddrV6 { &self.inner }
}
impl FromInner<libc::in6_addr> for Ipv6Addr {
fn from_inner(addr: libc::in6_addr) -> Ipv6Addr {

impl FromInner<sys::IpAddrV6> for Ipv6Addr {
fn from_inner(addr: sys::IpAddrV6) -> Ipv6Addr {
Ipv6Addr { inner: addr }
}
}

impl<'a> FromInner<&'a sys::IpAddrV6> for &'a Ipv6Addr {
fn from_inner(addr: &'a sys::IpAddrV6) -> &'a Ipv6Addr {
unsafe { mem::transmute(addr) }
}
}

// Tests for this module
#[cfg(test)]
mod tests {
@@ -13,9 +13,11 @@
#![stable(feature = "rust1", since = "1.0.0")]

use prelude::v1::*;
use sys::inner::*;
use sys::net as sys;
use sys::error;

use io::{self, Error, ErrorKind};
use sys_common::net as net_imp;

pub use self::ip::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
pub use self::addr::{SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
@@ -49,30 +51,14 @@ pub enum Shutdown {
Both,
}

#[doc(hidden)]
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) }

fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
where F: FnMut(&SocketAddr) -> io::Result<T>
where F: FnMut(&sys::SocketAddr) -> error::Result<T>
{
let mut last_err = None;
for addr in try!(addr.to_socket_addrs()) {
match f(&addr) {
match f(&addr.into_inner()) {
Ok(l) => return Ok(l),
Err(e) => last_err = Some(e),
Err(e) => last_err = Some(e.into()),
}
}
Err(last_err.unwrap_or_else(|| {
@@ -86,15 +72,15 @@ fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
iterator and returning socket \
addresses",
issue = "27705")]
pub struct LookupHost(net_imp::LookupHost);
pub struct LookupHost(sys::LookupHost);

#[unstable(feature = "lookup_host", reason = "unsure about the returned \
iterator and returning socket \
addresses",
issue = "27705")]
impl Iterator for LookupHost {
type Item = io::Result<SocketAddr>;
fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next() }
fn next(&mut self) -> Option<io::Result<SocketAddr>> { self.0.next().map(|i| i.map(FromInner::from_inner).map_err(From::from)) }
}

/// Resolve the host specified by `host` as a number of `SocketAddr` instances.
@@ -121,7 +107,7 @@ impl Iterator for LookupHost {
addresses",
issue = "27705")]
pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
net_imp::lookup_host(host).map(LookupHost)
sys::lookup_host(host).map(LookupHost).map_err(From::from)
}

/// Resolve the given address to a hostname.
@@ -132,5 +118,5 @@ pub fn lookup_host(host: &str) -> io::Result<LookupHost> {
#[unstable(feature = "lookup_addr", reason = "recent addition",
issue = "27705")]
pub fn lookup_addr(addr: &IpAddr) -> io::Result<String> {
net_imp::lookup_addr(addr)
sys::lookup_addr(&addr.into_inner()).map(|a| String::from_utf8_lossy(a.as_bytes()).into_owned()).map_err(From::from)
}
@@ -10,13 +10,13 @@

use prelude::v1::*;
use io::prelude::*;
use sys::inner::*;
use sys::net as sys;

use fmt;
use io;
use net::{ToSocketAddrs, SocketAddr, Shutdown};
use sys_common::io::read_to_end_uninitialized;
use sys_common::net as net_imp;
use sys_common::{AsInner, FromInner, IntoInner};
use io::read_to_end_uninitialized;
use time::Duration;

/// A structure which represents a TCP stream between a local socket and a
@@ -39,7 +39,7 @@ use time::Duration;
/// } // the stream is closed here
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TcpStream(net_imp::TcpStream);
pub struct TcpStream(sys::TcpStream);

/// A structure representing a socket server.
///
@@ -72,7 +72,7 @@ pub struct TcpStream(net_imp::TcpStream);
/// drop(listener);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct TcpListener(net_imp::TcpListener);
pub struct TcpListener(sys::TcpListener);

/// An infinite iterator over the connections from a `TcpListener`.
///
@@ -89,19 +89,19 @@ impl TcpStream {
/// documentation for concrete examples.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
super::each_addr(addr, net_imp::TcpStream::connect).map(TcpStream)
super::each_addr(addr, sys::connect_tcp).map(TcpStream)
}

/// Returns the socket address of the remote peer of this TCP connection.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn peer_addr(&self) -> io::Result<SocketAddr> {
self.0.peer_addr()
self.0.peer_addr().map(FromInner::from_inner).map_err(From::from)
}

/// Returns the socket address of the local half of this TCP connection.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.0.socket_addr()
self.0.socket_addr().map(FromInner::from_inner).map_err(From::from)
}

/// Shuts down the read, write, or both halves of this connection.
@@ -111,7 +111,7 @@ impl TcpStream {
/// documentation of `Shutdown`).
#[stable(feature = "rust1", since = "1.0.0")]
pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
self.0.shutdown(how)
self.0.shutdown(how).map_err(From::from)
}

/// Creates a new independently owned handle to the underlying socket.
@@ -122,7 +122,7 @@ impl TcpStream {
/// stream.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn try_clone(&self) -> io::Result<TcpStream> {
self.0.duplicate().map(TcpStream)
self.0.duplicate().map(TcpStream).map_err(From::from)
}

/// Sets the read timeout to the timeout specified.
@@ -138,7 +138,7 @@ impl TcpStream {
/// error of the kind `WouldBlock`, but Windows may return `TimedOut`.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_read_timeout(dur)
self.0.set_read_timeout(dur).map_err(From::from)
}

/// Sets the write timeout to the timeout specified.
@@ -154,7 +154,7 @@ impl TcpStream {
/// an error of the kind `WouldBlock`, but Windows may return `TimedOut`.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_write_timeout(dur)
self.0.set_write_timeout(dur).map_err(From::from)
}

/// Returns the read timeout of this socket.
@@ -166,7 +166,7 @@ impl TcpStream {
/// Some platforms do not provide access to the current timeout.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
self.0.read_timeout()
self.0.read_timeout().map_err(From::from)
}

/// Returns the write timeout of this socket.
@@ -178,50 +178,62 @@ impl TcpStream {
/// Some platforms do not provide access to the current timeout.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
self.0.write_timeout()
self.0.write_timeout().map_err(From::from)
}
}

#[stable(feature = "rust1", since = "1.0.0")]
impl Read for TcpStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf).map_err(From::from) }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
unsafe { read_to_end_uninitialized(self, buf) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Write for TcpStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf).map_err(From::from) }
fn flush(&mut self) -> io::Result<()> { self.0.flush().map_err(From::from) }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Read for &'a TcpStream {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf) }
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { self.0.read(buf).map_err(From::from) }
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
unsafe { read_to_end_uninitialized(self, buf) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> Write for &'a TcpStream {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf) }
fn flush(&mut self) -> io::Result<()> { Ok(()) }
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { self.0.write(buf).map_err(From::from) }
fn flush(&mut self) -> io::Result<()> { self.0.flush().map_err(From::from) }
}

impl AsInner<net_imp::TcpStream> for TcpStream {
fn as_inner(&self) -> &net_imp::TcpStream { &self.0 }
impl AsInner<sys::TcpStream> for TcpStream {
fn as_inner(&self) -> &sys::TcpStream { &self.0 }
}

impl FromInner<net_imp::TcpStream> for TcpStream {
fn from_inner(inner: net_imp::TcpStream) -> TcpStream { TcpStream(inner) }
impl FromInner<sys::TcpStream> for TcpStream {
fn from_inner(inner: sys::TcpStream) -> TcpStream { TcpStream(inner) }
}

impl IntoInner<net_imp::TcpStream> for TcpStream {
fn into_inner(self) -> net_imp::TcpStream { self.0 }
impl IntoInner<sys::TcpStream> for TcpStream {
fn into_inner(self) -> sys::TcpStream { self.0 }
}

impl fmt::Debug for TcpStream {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
let mut res = f.debug_struct("TcpStream");

if let Ok(addr) = self.local_addr() {
res.field("addr", &addr);
}

if let Ok(addr) = self.peer_addr() {
res.field("peer", &addr);
}

let name = if cfg!(windows) {"socket"} else {"fd"};
res.field(name, AsInner::<sys::Socket>::as_inner(&self.0))
.finish()
}
}

@@ -233,19 +245,19 @@ impl TcpListener {
///
/// Binding with a port number of 0 will request that the OS assigns a port
/// to this listener. The port allocated can be queried via the
/// `socket_addr` function.
/// `local_addr` function.
///
/// The address type can be any implementer of `ToSocketAddrs` trait. See
/// its documentation for concrete examples.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
super::each_addr(addr, net_imp::TcpListener::bind).map(TcpListener)
super::each_addr(addr, sys::bind_tcp).map(TcpListener)
}

/// Returns the local socket address of this listener.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.0.socket_addr()
self.0.socket_addr().map(FromInner::from_inner).map_err(From::from)
}

/// Creates a new independently owned handle to the underlying socket.
@@ -255,7 +267,7 @@ impl TcpListener {
/// connections and options set on one listener will affect the other.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn try_clone(&self) -> io::Result<TcpListener> {
self.0.duplicate().map(TcpListener)
self.0.duplicate().map(TcpListener).map_err(From::from)
}

/// Accept a new incoming connection from this listener.
@@ -265,7 +277,7 @@ impl TcpListener {
/// remote peer's address will be returned.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
self.0.accept().map(|(a, b)| (TcpStream(a), b))
self.0.accept().map(|(a, b)| (TcpStream(a), FromInner::from_inner(b))).map_err(From::from)
}

/// Returns an iterator over the connections being received on this
@@ -287,23 +299,31 @@ impl<'a> Iterator for Incoming<'a> {
}
}

impl AsInner<net_imp::TcpListener> for TcpListener {
fn as_inner(&self) -> &net_imp::TcpListener { &self.0 }
impl AsInner<sys::TcpListener> for TcpListener {
fn as_inner(&self) -> &sys::TcpListener { &self.0 }
}

impl FromInner<net_imp::TcpListener> for TcpListener {
fn from_inner(inner: net_imp::TcpListener) -> TcpListener {
impl FromInner<sys::TcpListener> for TcpListener {
fn from_inner(inner: sys::TcpListener) -> TcpListener {
TcpListener(inner)
}
}

impl IntoInner<net_imp::TcpListener> for TcpListener {
fn into_inner(self) -> net_imp::TcpListener { self.0 }
impl IntoInner<sys::TcpListener> for TcpListener {
fn into_inner(self) -> sys::TcpListener { self.0 }
}

impl fmt::Debug for TcpListener {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
let mut res = f.debug_struct("TcpListener");

if let Ok(addr) = self.local_addr() {
res.field("addr", &addr);
}

let name = if cfg!(windows) {"socket"} else {"fd"};
res.field(name, AsInner::<sys::Socket>::as_inner(&self.0))
.finish()
}
}

@@ -313,11 +333,11 @@ mod tests {

use io::ErrorKind;
use io::prelude::*;
use sys::inner::prelude::*;
use net::*;
use net::test::{next_test_ip4, next_test_ip6};
use sync::mpsc::channel;
use sys_common::AsInner;
use time::Duration;
use time::{self, Duration};
use thread;

fn each_ip(f: &mut FnMut(SocketAddr)) {
@@ -891,18 +911,20 @@ mod tests {

#[test]
fn debug() {
use sys::net::prelude as sys;

let name = if cfg!(windows) {"socket"} else {"fd"};
let socket_addr = next_test_ip4();

let listener = t!(TcpListener::bind(&socket_addr));
let listener_inner = listener.0.socket().as_inner();
let listener_inner = AsInner::<sys::Socket>::as_inner(&listener.0);
let compare = format!("TcpListener {{ addr: {:?}, {}: {:?} }}",
socket_addr, name, listener_inner);
assert_eq!(format!("{:?}", listener), compare);

let stream = t!(TcpStream::connect(&("localhost",
socket_addr.port())));
let stream_inner = stream.0.socket().as_inner();
let stream_inner = AsInner::<sys::Socket>::as_inner(&stream.0);
let compare = format!("TcpStream {{ addr: {:?}, \
peer: {:?}, {}: {:?} }}",
stream.local_addr().unwrap(),
@@ -949,7 +971,7 @@ mod tests {
t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));

let mut buf = [0; 10];
let wait = Duration::span(|| {
let wait = time::span(|| {
let kind = stream.read(&mut buf).err().expect("expected error").kind();
assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
});
@@ -971,7 +993,7 @@ mod tests {
t!(stream.read(&mut buf));
assert_eq!(b"hello world", &buf[..]);

let wait = Duration::span(|| {
let wait = time::span(|| {
let kind = stream.read(&mut buf).err().expect("expected error").kind();
assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
});
@@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use sys::inner::*;
use sys::net as sys;

use fmt;
use io::{self, Error, ErrorKind};
use net::{ToSocketAddrs, SocketAddr};
use sys_common::net as net_imp;
use sys_common::{AsInner, FromInner, IntoInner};
use time::Duration;

/// A User Datagram Protocol socket.
@@ -42,7 +43,7 @@ use time::Duration;
/// # }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub struct UdpSocket(net_imp::UdpSocket);
pub struct UdpSocket(sys::UdpSocket);

impl UdpSocket {
/// Creates a UDP socket from the given address.
@@ -51,14 +52,14 @@ impl UdpSocket {
/// its documentation for concrete examples.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
super::each_addr(addr, sys::bind_udp).map(UdpSocket).map_err(From::from)
}

/// Receives data from the socket. On success, returns the number of bytes
/// read and the address from whence the data came.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
self.0.recv_from(buf)
self.0.recv_from(buf).map(|(s, a)| (s, FromInner::from_inner(a))).map_err(From::from)
}

/// Sends data on the socket to the given address. On success, returns the
@@ -70,7 +71,7 @@ impl UdpSocket {
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
-> io::Result<usize> {
match try!(addr.to_socket_addrs()).next() {
Some(addr) => self.0.send_to(buf, &addr),
Some(addr) => self.0.send_to(buf, &addr.into_inner()).map_err(From::from),
None => Err(Error::new(ErrorKind::InvalidInput,
"no addresses to send data to")),
}
@@ -79,7 +80,7 @@ impl UdpSocket {
/// Returns the socket address that this socket was created from.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn local_addr(&self) -> io::Result<SocketAddr> {
self.0.socket_addr()
self.0.socket_addr().map(FromInner::from_inner).map_err(From::from)
}

/// Creates a new independently owned handle to the underlying socket.
@@ -89,7 +90,7 @@ impl UdpSocket {
/// options set on one socket will be propagated to the other.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn try_clone(&self) -> io::Result<UdpSocket> {
self.0.duplicate().map(UdpSocket)
self.0.duplicate().map(UdpSocket).map_err(From::from)
}

/// Sets the read timeout to the timeout specified.
@@ -105,7 +106,7 @@ impl UdpSocket {
/// error of the kind `WouldBlock`, but Windows may return `TimedOut`.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_read_timeout(dur)
self.0.set_read_timeout(dur).map_err(From::from)
}

/// Sets the write timeout to the timeout specified.
@@ -121,54 +122,63 @@ impl UdpSocket {
/// an error of the kind `WouldBlock`, but Windows may return `TimedOut`.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
self.0.set_write_timeout(dur)
self.0.set_write_timeout(dur).map_err(From::from)
}

/// Returns the read timeout of this socket.
///
/// If the timeout is `None`, then `read` calls will block indefinitely.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
self.0.read_timeout()
self.0.read_timeout().map_err(From::from)
}

/// Returns the write timeout of this socket.
///
/// If the timeout is `None`, then `write` calls will block indefinitely.
#[stable(feature = "socket_timeout", since = "1.4.0")]
pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
self.0.write_timeout()
self.0.write_timeout().map_err(From::from)
}
}

impl AsInner<net_imp::UdpSocket> for UdpSocket {
fn as_inner(&self) -> &net_imp::UdpSocket { &self.0 }
impl AsInner<sys::UdpSocket> for UdpSocket {
fn as_inner(&self) -> &sys::UdpSocket { &self.0 }
}

impl FromInner<net_imp::UdpSocket> for UdpSocket {
fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket { UdpSocket(inner) }
impl FromInner<sys::UdpSocket> for UdpSocket {
fn from_inner(inner: sys::UdpSocket) -> UdpSocket { UdpSocket(inner) }
}

impl IntoInner<net_imp::UdpSocket> for UdpSocket {
fn into_inner(self) -> net_imp::UdpSocket { self.0 }
impl IntoInner<sys::UdpSocket> for UdpSocket {
fn into_inner(self) -> sys::UdpSocket { self.0 }
}

impl fmt::Debug for UdpSocket {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(f)
let mut res = f.debug_struct("UdpSocket");

if let Ok(addr) = self.local_addr() {
res.field("addr", &addr);
}

let name = if cfg!(windows) {"socket"} else {"fd"};
res.field(name, AsInner::<sys::Socket>::as_inner(&self.0))
.finish()
}
}


#[cfg(test)]
mod tests {
use prelude::v1::*;

use sys::inner::*;
use io::ErrorKind;
use net::*;
use net::test::{next_test_ip4, next_test_ip6};
use sync::mpsc::channel;
use sys_common::AsInner;
use time::Duration;
use time::{self, Duration};
use thread;

fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
@@ -328,11 +338,13 @@ mod tests {

#[test]
fn debug() {
use sys::net as sys;

let name = if cfg!(windows) {"socket"} else {"fd"};
let socket_addr = next_test_ip4();

let udpsock = t!(UdpSocket::bind(&socket_addr));
let udpsock_inner = udpsock.0.socket().as_inner();
let udpsock_inner = AsInner::<sys::Socket>::as_inner(&udpsock.0);
let compare = format!("UdpSocket {{ addr: {:?}, {}: {:?} }}",
socket_addr, name, udpsock_inner);
assert_eq!(format!("{:?}", udpsock), compare);
@@ -373,7 +385,7 @@ mod tests {
t!(stream.set_read_timeout(Some(Duration::from_millis(1000))));

let mut buf = [0; 10];
let wait = Duration::span(|| {
let wait = time::span(|| {
let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
});
@@ -393,7 +405,7 @@ mod tests {
t!(stream.recv_from(&mut buf));
assert_eq!(b"hello world", &buf[..]);

let wait = Duration::span(|| {
let wait = time::span(|| {
let kind = stream.recv_from(&mut buf).err().expect("expected error").kind();
assert!(kind == ErrorKind::WouldBlock || kind == ErrorKind::TimedOut);
});
@@ -17,7 +17,7 @@

use core::num;
use intrinsics;
use libc::c_int;
use os::raw::c_int;
use num::{FpCategory, ParseFloatError};

pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
@@ -28,7 +28,7 @@ pub use core::f32::consts;

#[allow(dead_code)]
mod cmath {
use libc::{c_float, c_int};
use os::raw::{c_float, c_int};

extern {
pub fn cbrtf(n: c_float) -> c_float;
@@ -72,7 +72,7 @@ mod cmath {
pub use self::shims::*;
#[cfg(target_env = "msvc")]
mod shims {
use libc::{c_float, c_int};
use os::raw::{c_float, c_int};

pub unsafe fn acosf(n: c_float) -> c_float {
f64::acos(n as f64) as c_float
@@ -16,8 +16,8 @@
#![allow(missing_docs)]

use core::num;
use os::raw::c_int;
use intrinsics;
use libc::c_int;
use num::{FpCategory, ParseFloatError};

pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
@@ -28,7 +28,7 @@ pub use core::f64::consts;

#[allow(dead_code)]
mod cmath {
use libc::{c_double, c_int};
use os::raw::{c_double, c_int};

#[link_name = "m"]
extern {
@@ -10,24 +10,28 @@

use prelude::v1::*;
use io::prelude::*;
use sys::unwind;
use sys::backtrace::Backtrace;
use sys::stdio;

use any::Any;
use cell::Cell;
use cell::RefCell;
use sync::StaticMutex;
use backtrace;
use intrinsics;
use sys::stdio::Stderr;
use sys_common::backtrace;
use sys_common::thread_info;
use sys_common::util;

thread_local! { pub static PANIC_COUNT: Cell<usize> = Cell::new(0) }
use thread;
use fmt;
use io;

thread_local! {
pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
RefCell::new(None)
}
}

static BACKTRACE_LOCK: StaticMutex = StaticMutex::new();
static mut BACKTRACE: Backtrace = Backtrace::new();

fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
log_backtrace: bool) {
let msg = match obj.downcast_ref::<&'static str>() {
@@ -37,62 +41,67 @@ fn log_panic(obj: &(Any+Send), file: &'static str, line: u32,
None => "Box<Any>",
}
};
let mut err = Stderr::new().ok();
let thread = thread_info::current_thread();
let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
let thread = thread::current();
let name = thread.name().unwrap_or("<unnamed>");

let write = |err: &mut ::io::Write| {
let write = |err: &mut Write| {
let _ = writeln!(err, "thread '{}' panicked at '{}', {}:{}",
name, msg, file, line);
if log_backtrace {
let _ = backtrace::write(err);
let _g = BACKTRACE_LOCK.lock();
let _ = unsafe { BACKTRACE.write(err) };
}
};

let prev = LOCAL_STDERR.with(|s| s.borrow_mut().take());
match (prev, err.as_mut()) {
(Some(mut stderr), _) => {
write(&mut *stderr);
let mut s = Some(stderr);
LOCAL_STDERR.with(|slot| {
*slot.borrow_mut() = s.take();
});
}
(None, Some(ref mut err)) => { write(err) }
_ => {}
if let Some(mut w) = LOCAL_STDERR.with(|s| s.borrow_mut().take()) {
write(&mut *w);
LOCAL_STDERR.with(move |slot| {
*slot.borrow_mut() = Some(w);
});
} else {
write(&mut io::stderr())
}
}

pub fn on_panic(obj: &(Any+Send), file: &'static str, line: u32) {
let panics = PANIC_COUNT.with(|s| {
let count = s.get() + 1;
s.set(count);
count
});
let panics = unwind::panic_inc();

// If this is the third nested call, on_panic triggered the last panic,
// otherwise the double-panic check would have aborted the process.
// Even if it is likely that on_panic was unable to log the backtrace,
// abort immediately to avoid infinite recursion, so that attaching a
// debugger provides a useable stacktrace.
if panics >= 3 {
util::dumb_print(format_args!("thread panicked while processing \
if panics > 1 {
stdio::dumb_print(format_args!("thread panicked while processing \
panic. aborting."));
unsafe { intrinsics::abort() }
}

// If this is a double panic, make sure that we print a backtrace
// for this panic. Otherwise only print it if logging is enabled.
let log_backtrace = panics >= 2 || backtrace::log_enabled();
let log_backtrace = panics > 0 || backtrace::log_enabled();
log_panic(obj, file, line, log_backtrace);

if panics >= 2 {
if panics > 0 {
// If a thread panics while it's already unwinding then we
// have limited options. Currently our preference is to
// just abort. In the future we may consider resuming
// unwinding or otherwise exiting the thread cleanly.
util::dumb_print(format_args!("thread panicked while panicking. \
aborting."));
stdio::dumb_print(format_args!("thread panicked while panicking. \
aborting."));
unsafe { intrinsics::abort() }
}
}

pub fn abort(args: fmt::Arguments) -> ! {
use intrinsics;
use sys::stdio;

stdio::dumb_print(format_args!("fatal runtime error: {}", args));
unsafe { intrinsics::abort(); }
}

pub fn report_overflow() {
stdio::dumb_print(format_args!("\nthread '{}' has overflowed its stack",
thread::current().name().unwrap_or("<unknown>")));
}
@@ -98,6 +98,8 @@

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

use sys::path as sys;

use ascii::*;
use borrow::{Borrow, IntoCow, ToOwned, Cow};
use cmp;
@@ -110,8 +112,6 @@ use fmt;

use ffi::{OsStr, OsString};

use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};

////////////////////////////////////////////////////////////////////////////////
// GENERAL NOTES
////////////////////////////////////////////////////////////////////////////////
@@ -122,132 +122,6 @@ use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
// OsStr APIs for parsing, but it will take a while for those to become
// available.

////////////////////////////////////////////////////////////////////////////////
// Platform-specific definitions
////////////////////////////////////////////////////////////////////////////////

// The following modules give the most basic tools for parsing paths on various
// platforms. The bulk of the code is devoted to parsing prefixes on Windows.

#[cfg(unix)]
mod platform {
use super::Prefix;
use ffi::OsStr;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/'
}

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'/'
}

pub fn parse_prefix(_: &OsStr) -> Option<Prefix> {
None
}

pub const MAIN_SEP_STR: &'static str = "/";
pub const MAIN_SEP: char = '/';
}

#[cfg(windows)]
mod platform {
use ascii::*;

use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
use ffi::OsStr;

#[inline]
pub fn is_sep_byte(b: u8) -> bool {
b == b'/' || b == b'\\'
}

#[inline]
pub fn is_verbatim_sep(b: u8) -> bool {
b == b'\\'
}

pub fn parse_prefix<'a>(path: &'a OsStr) -> Option<Prefix> {
use super::Prefix::*;
unsafe {
// The unsafety here stems from converting between &OsStr and &[u8]
// and back. This is safe to do because (1) we only look at ASCII
// contents of the encoding and (2) new &OsStr values are produced
// only from ASCII-bounded slices of existing &OsStr values.
let mut path = os_str_as_u8_slice(path);

if path.starts_with(br"\\") {
// \\
path = &path[2..];
if path.starts_with(br"?\") {
// \\?\
path = &path[2..];
if path.starts_with(br"UNC\") {
// \\?\UNC\server\share
path = &path[4..];
let (server, share) = match parse_two_comps(path, is_verbatim_sep) {
Some((server, share)) => (u8_slice_as_os_str(server),
u8_slice_as_os_str(share)),
None => (u8_slice_as_os_str(path),
u8_slice_as_os_str(&[])),
};
return Some(VerbatimUNC(server, share));
} else {
// \\?\path
let idx = path.iter().position(|&b| b == b'\\');
if idx == Some(2) && path[1] == b':' {
let c = path[0];
if c.is_ascii() && (c as char).is_alphabetic() {
// \\?\C:\ path
return Some(VerbatimDisk(c.to_ascii_uppercase()));
}
}
let slice = &path[.. idx.unwrap_or(path.len())];
return Some(Verbatim(u8_slice_as_os_str(slice)));
}
} else if path.starts_with(b".\\") {
// \\.\path
path = &path[2..];
let pos = path.iter().position(|&b| b == b'\\');
let slice = &path[..pos.unwrap_or(path.len())];
return Some(DeviceNS(u8_slice_as_os_str(slice)));
}
match parse_two_comps(path, is_sep_byte) {
Some((server, share)) if !server.is_empty() && !share.is_empty() => {
// \\server\share
return Some(UNC(u8_slice_as_os_str(server),
u8_slice_as_os_str(share)));
}
_ => ()
}
} else if path.len() > 1 && path[1] == b':' {
// C:
let c = path[0];
if c.is_ascii() && (c as char).is_alphabetic() {
return Some(Disk(c.to_ascii_uppercase()));
}
}
return None;
}

fn parse_two_comps(mut path: &[u8], f: fn(u8) -> bool) -> Option<(&[u8], &[u8])> {
let first = match path.iter().position(|x| f(*x)) {
None => return None,
Some(x) => &path[.. x]
};
path = &path[(first.len()+1)..];
let idx = path.iter().position(|x| f(*x));
let second = &path[.. idx.unwrap_or(path.len())];
Some((first, second))
}
}

pub const MAIN_SEP_STR: &'static str = "\\";
pub const MAIN_SEP: char = '\\';
}

////////////////////////////////////////////////////////////////////////////////
// Windows Prefixes
////////////////////////////////////////////////////////////////////////////////
@@ -351,12 +225,12 @@ impl<'a> Prefix<'a> {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_separator(c: char) -> bool {
c.is_ascii() && is_sep_byte(c as u8)
c.is_ascii() && sys::is_sep_byte(c as u8)
}

/// The primary separator for the current platform
#[stable(feature = "rust1", since = "1.0.0")]
pub const MAIN_SEPARATOR: char = platform::MAIN_SEP;
pub const MAIN_SEPARATOR: char = sys::MAIN_SEP;

////////////////////////////////////////////////////////////////////////////////
// Misc helpers
@@ -397,7 +271,7 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
/// Says whether the first byte after the prefix is a separator.
fn has_physical_root(s: &[u8], prefix: Option<Prefix>) -> bool {
let path = if let Some(p) = prefix { &s[p.len()..] } else { s };
!path.is_empty() && is_sep_byte(path[0])
!path.is_empty() && sys::is_sep_byte(path[0])
}

// basic workhorse for splitting stem and extension
@@ -524,7 +398,7 @@ impl<'a> Component<'a> {
pub fn as_os_str(self) -> &'a OsStr {
match self {
Component::Prefix(p) => p.as_os_str(),
Component::RootDir => OsStr::new(MAIN_SEP_STR),
Component::RootDir => OsStr::new(sys::MAIN_SEP_STR),
Component::CurDir => OsStr::new("."),
Component::ParentDir => OsStr::new(".."),
Component::Normal(path) => path,
@@ -621,9 +495,9 @@ impl<'a> Components<'a> {
#[inline]
fn is_sep_byte(&self, b: u8) -> bool {
if self.prefix_verbatim() {
is_verbatim_sep(b)
sys::is_verbatim_sep(b)
} else {
is_sep_byte(b)
sys::is_sep_byte(b)
}
}

@@ -938,7 +812,9 @@ pub struct PathBuf {

impl PathBuf {
fn as_mut_vec(&mut self) -> &mut Vec<u8> {
unsafe { &mut *(self as *mut PathBuf as *mut Vec<u8>) }
use sys::inner::*;

self.inner.as_inner_mut().as_mut_vec()
}

/// Allocates an empty `PathBuf`.
@@ -969,7 +845,7 @@ impl PathBuf {

fn _push(&mut self, path: &Path) {
// in general, a separator is needed if the rightmost byte is not a separator
let mut need_sep = self.as_mut_vec().last().map(|c| !is_sep_byte(*c)).unwrap_or(false);
let mut need_sep = self.as_mut_vec().last().map(|c| !sys::is_sep_byte(*c)).unwrap_or(false);

// in the special case of `C:` on Windows, do *not* add a separator
{
@@ -993,7 +869,7 @@ impl PathBuf {

// `path` is a pure relative path
} else if need_sep {
self.inner.push(MAIN_SEP_STR);
self.inner.push(sys::MAIN_SEP_STR);
}

self.inner.push(path);
@@ -1349,7 +1225,7 @@ impl Path {
#[stable(feature = "rust1", since = "1.0.0")]
pub fn is_absolute(&self) -> bool {
self.has_root() &&
(cfg!(unix) || self.prefix().is_some())
(!sys::PREFIX_IMP || self.prefix().is_some())
}

/// A path is *relative* if it is not absolute.
@@ -1644,7 +1520,7 @@ impl Path {
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn components(&self) -> Components {
let prefix = parse_prefix(self.as_os_str());
let prefix = sys::parse_prefix(self.as_os_str());
Components {
path: self.as_u8_slice(),
prefix: prefix,
Oops, something went wrong.