about summary refs log tree commit diff
path: root/src/libstd/sys/unix
diff options
context:
space:
mode:
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-12-06 09:25:29 +0100
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>2017-12-06 09:25:29 +0100
commitacdf83f2288e1b80259dafeca4a0cee9a42973c3 (patch)
treeef7ffe46fee2f0b9f331a206af4a71d23fabe0a1 /src/libstd/sys/unix
parentd4c442d65c150b99d18202a5cce4a2cbdbd4dc83 (diff)
downloadrust-acdf83f2288e1b80259dafeca4a0cee9a42973c3.tar.gz
rust-acdf83f2288e1b80259dafeca4a0cee9a42973c3.zip
Update miri to rustc changes
Diffstat (limited to 'src/libstd/sys/unix')
-rw-r--r--src/libstd/sys/unix/backtrace/printing/dladdr.rs5
-rw-r--r--src/libstd/sys/unix/backtrace/printing/mod.rs2
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs4
-rw-r--r--src/libstd/sys/unix/backtrace/tracing/gcc_s.rs4
-rw-r--r--src/libstd/sys/unix/cmath.rs43
-rw-r--r--src/libstd/sys/unix/condvar.rs5
-rw-r--r--src/libstd/sys/unix/env.rs21
-rw-r--r--src/libstd/sys/unix/ext/fs.rs362
-rw-r--r--src/libstd/sys/unix/ext/mod.rs10
-rw-r--r--src/libstd/sys/unix/ext/process.rs6
-rw-r--r--src/libstd/sys/unix/fs.rs4
-rw-r--r--src/libstd/sys/unix/l4re.rs4
-rw-r--r--src/libstd/sys/unix/mod.rs9
-rw-r--r--src/libstd/sys/unix/net.rs92
-rw-r--r--src/libstd/sys/unix/os.rs39
-rw-r--r--src/libstd/sys/unix/os_str.rs24
-rw-r--r--src/libstd/sys/unix/process/process_common.rs1
-rw-r--r--src/libstd/sys/unix/process/process_fuchsia.rs10
-rw-r--r--src/libstd/sys/unix/process/process_unix.rs4
-rw-r--r--src/libstd/sys/unix/process/zircon.rs25
-rw-r--r--src/libstd/sys/unix/rand.rs340
-rw-r--r--src/libstd/sys/unix/stdio.rs5
-rw-r--r--src/libstd/sys/unix/thread.rs4
-rw-r--r--src/libstd/sys/unix/time.rs4
24 files changed, 688 insertions, 339 deletions
diff --git a/src/libstd/sys/unix/backtrace/printing/dladdr.rs b/src/libstd/sys/unix/backtrace/printing/dladdr.rs
index 21f0b3724c1..bc56fd6594e 100644
--- a/src/libstd/sys/unix/backtrace/printing/dladdr.rs
+++ b/src/libstd/sys/unix/backtrace/printing/dladdr.rs
@@ -22,7 +22,7 @@ pub fn resolve_symname<F>(frame: Frame,
 {
     unsafe {
         let mut info: Dl_info = intrinsics::init();
-        let symname = if dladdr(frame.exact_position, &mut info) == 0 ||
+        let symname = if dladdr(frame.exact_position as *mut _, &mut info) == 0 ||
                          info.dli_sname.is_null() {
             None
         } else {
@@ -41,6 +41,5 @@ struct Dl_info {
 }
 
 extern {
-    fn dladdr(addr: *const libc::c_void,
-              info: *mut Dl_info) -> libc::c_int;
+    fn dladdr(addr: *const libc::c_void, info: *mut Dl_info) -> libc::c_int;
 }
diff --git a/src/libstd/sys/unix/backtrace/printing/mod.rs b/src/libstd/sys/unix/backtrace/printing/mod.rs
index 8bd2d9eccd8..caa60712b1d 100644
--- a/src/libstd/sys/unix/backtrace/printing/mod.rs
+++ b/src/libstd/sys/unix/backtrace/printing/mod.rs
@@ -20,7 +20,7 @@ pub use self::dladdr::resolve_symname;
 #[cfg(target_os = "emscripten")]
 pub fn foreach_symbol_fileline<F>(_: Frame, _: F, _: &BacktraceContext) -> io::Result<bool>
 where
-    F: FnMut(&[u8], ::libc::c_int) -> io::Result<()>
+    F: FnMut(&[u8], u32) -> io::Result<()>
 {
     Ok(false)
 }
diff --git a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
index ecd32aa9462..400d39cd4bd 100644
--- a/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/backtrace_fn.rs
@@ -36,8 +36,8 @@ pub fn unwind_backtrace(frames: &mut [Frame])
     } as usize;
     for (from, to) in raw_frames.iter().zip(frames.iter_mut()).take(nb_frames) {
         *to = Frame {
-            exact_position: *from,
-            symbol_addr: *from,
+            exact_position: *from as *mut u8,
+            symbol_addr: *from as *mut u8,
         };
     }
     Ok((nb_frames as usize, BacktraceContext))
diff --git a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
index e3ffbe88acd..000c08d2e0d 100644
--- a/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
+++ b/src/libstd/sys/unix/backtrace/tracing/gcc_s.rs
@@ -96,8 +96,8 @@ extern fn trace_fn(ctx: *mut uw::_Unwind_Context,
 
     if cx.idx < cx.frames.len() {
         cx.frames[cx.idx] = Frame {
-            symbol_addr: symaddr,
-            exact_position: ip,
+            symbol_addr: symaddr as *mut u8,
+            exact_position: ip as *mut u8,
         };
         cx.idx += 1;
     }
diff --git a/src/libstd/sys/unix/cmath.rs b/src/libstd/sys/unix/cmath.rs
new file mode 100644
index 00000000000..2bc96651b0c
--- /dev/null
+++ b/src/libstd/sys/unix/cmath.rs
@@ -0,0 +1,43 @@
+// Copyright 2017 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.
+
+#![cfg(not(test))]
+
+use libc::{c_float, c_double};
+
+#[link_name = "m"]
+extern {
+    pub fn acos(n: c_double) -> c_double;
+    pub fn acosf(n: c_float) -> c_float;
+    pub fn asin(n: c_double) -> c_double;
+    pub fn asinf(n: c_float) -> c_float;
+    pub fn atan(n: c_double) -> c_double;
+    pub fn atan2(a: c_double, b: c_double) -> c_double;
+    pub fn atan2f(a: c_float, b: c_float) -> c_float;
+    pub fn atanf(n: c_float) -> c_float;
+    pub fn cbrt(n: c_double) -> c_double;
+    pub fn cbrtf(n: c_float) -> c_float;
+    pub fn cosh(n: c_double) -> c_double;
+    pub fn coshf(n: c_float) -> c_float;
+    pub fn expm1(n: c_double) -> c_double;
+    pub fn expm1f(n: c_float) -> c_float;
+    pub fn fdim(a: c_double, b: c_double) -> c_double;
+    pub fn fdimf(a: c_float, b: c_float) -> c_float;
+    pub fn hypot(x: c_double, y: c_double) -> c_double;
+    pub fn hypotf(x: c_float, y: c_float) -> c_float;
+    pub fn log1p(n: c_double) -> c_double;
+    pub fn log1pf(n: c_float) -> c_float;
+    pub fn sinh(n: c_double) -> c_double;
+    pub fn sinhf(n: c_float) -> c_float;
+    pub fn tan(n: c_double) -> c_double;
+    pub fn tanf(n: c_float) -> c_float;
+    pub fn tanh(n: c_double) -> c_double;
+    pub fn tanhf(n: c_float) -> c_float;
+}
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index 89a44b97657..4f878d8ad1f 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -92,14 +92,15 @@ impl Condvar {
         assert_eq!(r, 0);
 
         // Nanosecond calculations can't overflow because both values are below 1e9.
-        let nsec = dur.subsec_nanos() as libc::c_long + now.tv_nsec as libc::c_long;
+        let nsec = dur.subsec_nanos() + now.tv_nsec as u32;
+
         let sec = saturating_cast_to_time_t(dur.as_secs())
             .checked_add((nsec / 1_000_000_000) as libc::time_t)
             .and_then(|s| s.checked_add(now.tv_sec));
         let nsec = nsec % 1_000_000_000;
 
         let timeout = sec.map(|s| {
-            libc::timespec { tv_sec: s, tv_nsec: nsec }
+            libc::timespec { tv_sec: s, tv_nsec: nsec as _}
         }).unwrap_or(TIMESPEC_MAX);
 
         let r = libc::pthread_cond_timedwait(self.inner.get(), mutex::raw(mutex),
diff --git a/src/libstd/sys/unix/env.rs b/src/libstd/sys/unix/env.rs
index 3d9a06bedd5..00cf7eca75d 100644
--- a/src/libstd/sys/unix/env.rs
+++ b/src/libstd/sys/unix/env.rs
@@ -118,27 +118,6 @@ pub mod os {
     pub const EXE_EXTENSION: &'static str = "";
 }
 
-#[cfg(all(target_os = "nacl", not(target_arch = "le32")))]
-pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "nacl";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".so";
-    pub const DLL_EXTENSION: &'static str = "so";
-    pub const EXE_SUFFIX: &'static str = ".nexe";
-    pub const EXE_EXTENSION: &'static str = "nexe";
-}
-#[cfg(all(target_os = "nacl", target_arch = "le32"))]
-pub mod os {
-    pub const FAMILY: &'static str = "unix";
-    pub const OS: &'static str = "pnacl";
-    pub const DLL_PREFIX: &'static str = "lib";
-    pub const DLL_SUFFIX: &'static str = ".pso";
-    pub const DLL_EXTENSION: &'static str = "pso";
-    pub const EXE_SUFFIX: &'static str = ".pexe";
-    pub const EXE_EXTENSION: &'static str = "pexe";
-}
-
 #[cfg(target_os = "haiku")]
 pub mod os {
     pub const FAMILY: &'static str = "unix";
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 3e631ad40ac..2e17fd58e0a 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -20,7 +20,9 @@ use sys;
 use sys_common::{FromInner, AsInner, AsInnerMut};
 use sys::platform::fs::MetadataExt as UnixMetadataExt;
 
-/// Unix-specific extensions to `File`
+/// Unix-specific extensions to [`File`].
+///
+/// [`File`]: ../../../../std/fs/struct.File.html
 #[stable(feature = "file_offset", since = "1.15.0")]
 pub trait FileExt {
     /// Reads a number of bytes starting from a given offset.
@@ -32,8 +34,28 @@ pub trait FileExt {
     ///
     /// The current file cursor is not affected by this function.
     ///
-    /// Note that similar to `File::read`, it is not an error to return with a
+    /// Note that similar to [`File::read`], it is not an error to return with a
     /// short read.
+    ///
+    /// [`File::read`]: ../../../../std/fs/struct.File.html#method.read
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::prelude::FileExt;
+    /// use std::fs::File;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let mut buf = [0u8; 8];
+    /// let file = File::open("foo.txt")?;
+    ///
+    /// // We now read 8 bytes from the offset 10.
+    /// let num_bytes_read = file.read_at(&mut buf, 10)?;
+    /// println!("read {} bytes: {:?}", num_bytes_read, buf);
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
 
@@ -49,8 +71,26 @@ pub trait FileExt {
     /// When writing beyond the end of the file, the file is appropriately
     /// extended and the intermediate bytes are initialized with the value 0.
     ///
-    /// Note that similar to `File::write`, it is not an error to return a
+    /// Note that similar to [`File::write`], it is not an error to return a
     /// short write.
+    ///
+    /// [`File::write`]: ../../../../std/fs/struct.File.html#write.v
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::os::unix::prelude::FileExt;
+    /// use std::fs::File;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let file = File::open("foo.txt")?;
+    ///
+    /// // We now write at the offset 10.
+    /// file.write_at(b"sushi", 10)?;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_offset", since = "1.15.0")]
     fn write_at(&self, buf: &[u8], offset: u64) -> io::Result<usize>;
 }
@@ -215,36 +255,282 @@ impl OpenOptionsExt for OpenOptions {
 // casts and rely on manual lowering to `stat` if the raw type is desired.
 #[stable(feature = "metadata_ext", since = "1.1.0")]
 pub trait MetadataExt {
+    /// Returns the ID of the device containing the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let dev_id = meta.dev();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn dev(&self) -> u64;
+    /// Returns the inode number.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let inode = meta.ino();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ino(&self) -> u64;
+    /// Returns the rights applied to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let mode = meta.mode();
+    /// let user_has_write_access      = mode & 0o200;
+    /// let user_has_read_write_access = mode & 0o600;
+    /// let group_has_read_access      = mode & 0o040;
+    /// let others_have_exec_access    = mode & 0o001;
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mode(&self) -> u32;
+    /// Returns the number of hard links pointing to this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nb_hard_links = meta.nlink();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn nlink(&self) -> u64;
+    /// Returns the user ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let user_id = meta.uid();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn uid(&self) -> u32;
+    /// Returns the group ID of the owner of this file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let group_id = meta.gid();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn gid(&self) -> u32;
+    /// Returns the device ID of this file (if it is a special one).
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let device_id = meta.rdev();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn rdev(&self) -> u64;
+    /// Returns the total size of this file in bytes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let file_size = meta.size();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn size(&self) -> u64;
+    /// Returns the time of the last access to the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_access_time = meta.atime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime(&self) -> i64;
+    /// Returns the time of the last access to the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_access_time = meta.atime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn atime_nsec(&self) -> i64;
+    /// Returns the time of the last modification of the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_modification_time = meta.mtime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime(&self) -> i64;
+    /// Returns the time of the last modification of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_modification_time = meta.mtime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn mtime_nsec(&self) -> i64;
+    /// Returns the time of the last status change of the file.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let last_status_change_time = meta.ctime();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime(&self) -> i64;
+    /// Returns the time of the last status change of the file in nanoseconds.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let nano_last_status_change_time = meta.ctime_nsec();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn ctime_nsec(&self) -> i64;
+    /// Returns the blocksize for filesystem I/O.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let blocksize = meta.blksize();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn blksize(&self) -> u64;
+    /// Returns the number of blocks allocated to the file, in 512-byte units.
+    ///
+    /// Please note that this may be smaller than `st_size / 512` when the file has holes.
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// use std::fs;
+    /// use std::os::unix::fs::MetadataExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("some_file")?;
+    /// let blocks = meta.blocks();
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "metadata_ext", since = "1.1.0")]
     fn blocks(&self) -> u64;
 }
@@ -269,19 +555,79 @@ impl MetadataExt for fs::Metadata {
     fn blocks(&self) -> u64 { self.st_blocks() }
 }
 
-/// Add special unix types (block/char device, fifo and socket)
+/// Add support for special unix types (block/char device, fifo and socket).
 #[stable(feature = "file_type_ext", since = "1.5.0")]
 pub trait FileTypeExt {
     /// Returns whether this file type is a block device.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("block_device_file")?;
+    /// let file_type = meta.file_type();
+    /// assert!(file_type.is_block_device());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type_ext", since = "1.5.0")]
     fn is_block_device(&self) -> bool;
     /// Returns whether this file type is a char device.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("char_device_file")?;
+    /// let file_type = meta.file_type();
+    /// assert!(file_type.is_char_device());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type_ext", since = "1.5.0")]
     fn is_char_device(&self) -> bool;
     /// Returns whether this file type is a fifo.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("fifo_file")?;
+    /// let file_type = meta.file_type();
+    /// assert!(file_type.is_fifo());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type_ext", since = "1.5.0")]
     fn is_fifo(&self) -> bool;
     /// Returns whether this file type is a socket.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// use std::fs;
+    /// use std::os::unix::fs::FileTypeExt;
+    ///
+    /// # use std::io;
+    /// # fn f() -> io::Result<()> {
+    /// let meta = fs::metadata("unix.socket")?;
+    /// let file_type = meta.file_type();
+    /// assert!(file_type.is_socket());
+    /// # Ok(())
+    /// # }
+    /// ```
     #[stable(feature = "file_type_ext", since = "1.5.0")]
     fn is_socket(&self) -> bool;
 }
@@ -294,7 +640,9 @@ impl FileTypeExt for fs::FileType {
     fn is_socket(&self) -> bool { self.as_inner().is(libc::S_IFSOCK) }
 }
 
-/// Unix-specific extension methods for `fs::DirEntry`
+/// Unix-specific extension methods for [`fs::DirEntry`].
+///
+/// [`fs::DirEntry`]: ../../../../std/fs/struct.DirEntry.html
 #[stable(feature = "dir_entry_ext", since = "1.1.0")]
 pub trait DirEntryExt {
     /// Returns the underlying `d_ino` field in the contained `dirent`
@@ -354,7 +702,9 @@ pub fn symlink<P: AsRef<Path>, Q: AsRef<Path>>(src: P, dst: Q) -> io::Result<()>
 }
 
 #[stable(feature = "dir_builder", since = "1.6.0")]
-/// An extension trait for `fs::DirBuilder` for unix-specific options.
+/// An extension trait for [`fs::DirBuilder`] for unix-specific options.
+///
+/// [`fs::DirBuilder`]: ../../../../std/fs/struct.DirBuilder.html
 pub trait DirBuilderExt {
     /// Sets the mode to create new directories with. This option defaults to
     /// 0o777.
diff --git a/src/libstd/sys/unix/ext/mod.rs b/src/libstd/sys/unix/ext/mod.rs
index 98bc90dd4e1..c221f7c8cfe 100644
--- a/src/libstd/sys/unix/ext/mod.rs
+++ b/src/libstd/sys/unix/ext/mod.rs
@@ -10,8 +10,14 @@
 
 //! Experimental extensions to `std` for Unix platforms.
 //!
-//! For now, this module is limited to extracting file descriptors,
-//! but its functionality will grow over time.
+//! Provides access to platform-level information on Unix platforms, and
+//! exposes Unix-specific functions that would otherwise be inappropriate as
+//! part of the core `std` library.
+//!
+//! It exposes more ways to deal with platform-specific strings (`OsStr`,
+//! `OsString`), allows to set permissions more granularly, extract low-level
+//! file descriptors from files and sockets, and has platform-specific helpers
+//! for spawning processes.
 //!
 //! # Examples
 //!
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index cde21b089a2..60309bec6d4 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -191,3 +191,9 @@ impl IntoRawFd for process::ChildStderr {
         self.into_inner().into_fd().into_raw()
     }
 }
+
+/// Returns the OS-assigned process identifier associated with this process's parent.
+#[unstable(feature = "unix_ppid", issue = "46104")]
+pub fn parent_id() -> u32 {
+    ::sys::os::getppid()
+}
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index c4616c3b395..a1ca839dc18 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -132,14 +132,14 @@ impl FileAttr {
     pub fn modified(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_mtime as libc::time_t,
-            tv_nsec: self.stat.st_mtime_nsec as libc::c_long,
+            tv_nsec: self.stat.st_mtime_nsec as _,
         }))
     }
 
     pub fn accessed(&self) -> io::Result<SystemTime> {
         Ok(SystemTime::from(libc::timespec {
             tv_sec: self.stat.st_atime as libc::time_t,
-            tv_nsec: self.stat.st_atime_nsec as libc::c_long,
+            tv_nsec: self.stat.st_atime_nsec as _,
         }))
     }
 
diff --git a/src/libstd/sys/unix/l4re.rs b/src/libstd/sys/unix/l4re.rs
index 21218489679..c3e8d0b7d95 100644
--- a/src/libstd/sys/unix/l4re.rs
+++ b/src/libstd/sys/unix/l4re.rs
@@ -437,5 +437,9 @@ pub mod net {
     pub fn lookup_host(_: &str) -> io::Result<LookupHost> {
         unimpl!();
     }
+
+    pub fn res_init_if_glibc_before_2_26() -> io::Result<()> {
+        unimpl!();
+    }
 }
 
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 1b3f1000b77..9bdea945ea4 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -22,7 +22,6 @@ use libc;
 #[cfg(all(not(dox), target_os = "haiku"))]     pub use os::haiku as platform;
 #[cfg(all(not(dox), target_os = "ios"))]       pub use os::ios as platform;
 #[cfg(all(not(dox), target_os = "macos"))]     pub use os::macos as platform;
-#[cfg(all(not(dox), target_os = "nacl"))]      pub use os::nacl as platform;
 #[cfg(all(not(dox), target_os = "netbsd"))]    pub use os::netbsd as platform;
 #[cfg(all(not(dox), target_os = "openbsd"))]   pub use os::openbsd as platform;
 #[cfg(all(not(dox), target_os = "solaris"))]   pub use os::solaris as platform;
@@ -30,6 +29,9 @@ use libc;
 #[cfg(all(not(dox), target_os = "fuchsia"))]   pub use os::fuchsia as platform;
 #[cfg(all(not(dox), target_os = "l4re"))]      pub use os::linux as platform;
 
+pub use self::rand::hashmap_random_keys;
+pub use libc::strlen;
+
 #[macro_use]
 pub mod weak;
 
@@ -37,6 +39,7 @@ pub mod args;
 pub mod android;
 #[cfg(feature = "backtrace")]
 pub mod backtrace;
+pub mod cmath;
 pub mod condvar;
 pub mod env;
 pub mod ext;
@@ -77,11 +80,11 @@ pub fn init() {
         reset_sigpipe();
     }
 
-    #[cfg(not(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia")))]
+    #[cfg(not(any(target_os = "emscripten", target_os="fuchsia")))]
     unsafe fn reset_sigpipe() {
         assert!(signal(libc::SIGPIPE, libc::SIG_IGN) != libc::SIG_ERR);
     }
-    #[cfg(any(target_os = "nacl", target_os = "emscripten", target_os="fuchsia"))]
+    #[cfg(any(target_os = "emscripten", target_os="fuchsia"))]
     unsafe fn reset_sigpipe() {}
 }
 
diff --git a/src/libstd/sys/unix/net.rs b/src/libstd/sys/unix/net.rs
index 668b2f92aba..e775f857f2b 100644
--- a/src/libstd/sys/unix/net.rs
+++ b/src/libstd/sys/unix/net.rs
@@ -176,11 +176,16 @@ impl Socket {
                 }
                 0 => {}
                 _ => {
-                    if pollfd.revents & libc::POLLOUT == 0 {
-                        if let Some(e) = self.take_error()? {
-                            return Err(e);
-                        }
+                    // linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
+                    // for POLLHUP rather than read readiness
+                    if pollfd.revents & libc::POLLHUP != 0 {
+                        let e = self.take_error()?
+                            .unwrap_or_else(|| {
+                                io::Error::new(io::ErrorKind::Other, "no error set after POLLHUP")
+                            });
+                        return Err(e);
                     }
+
                     return Ok(());
                 }
             }
@@ -355,3 +360,82 @@ impl FromInner<c_int> for Socket {
 impl IntoInner<c_int> for Socket {
     fn into_inner(self) -> c_int { self.0.into_raw() }
 }
+
+// In versions of glibc prior to 2.26, there's a bug where the DNS resolver
+// will cache the contents of /etc/resolv.conf, so changes to that file on disk
+// can be ignored by a long-running program. That can break DNS lookups on e.g.
+// laptops where the network comes and goes. See
+// https://sourceware.org/bugzilla/show_bug.cgi?id=984. Note however that some
+// distros including Debian have patched glibc to fix this for a long time.
+//
+// A workaround for this bug is to call the res_init libc function, to clear
+// the cached configs. Unfortunately, while we believe glibc's implementation
+// of res_init is thread-safe, we know that other implementations are not
+// (https://github.com/rust-lang/rust/issues/43592). Code here in libstd could
+// try to synchronize its res_init calls with a Mutex, but that wouldn't
+// protect programs that call into libc in other ways. So instead of calling
+// res_init unconditionally, we call it only when we detect we're linking
+// against glibc version < 2.26. (That is, when we both know its needed and
+// believe it's thread-safe).
+pub fn res_init_if_glibc_before_2_26() -> io::Result<()> {
+    // If the version fails to parse, we treat it the same as "not glibc".
+    if let Some(Ok(version_str)) = glibc_version_cstr().map(CStr::to_str) {
+        if let Some(version) = parse_glibc_version(version_str) {
+            if version < (2, 26) {
+                let ret = unsafe { libc::res_init() };
+                if ret != 0 {
+                    return Err(io::Error::last_os_error());
+                }
+            }
+        }
+    }
+    Ok(())
+}
+
+fn glibc_version_cstr() -> Option<&'static CStr> {
+    weak! {
+        fn gnu_get_libc_version() -> *const libc::c_char
+    }
+    if let Some(f) = gnu_get_libc_version.get() {
+        unsafe { Some(CStr::from_ptr(f())) }
+    } else {
+        None
+    }
+}
+
+// Returns Some((major, minor)) if the string is a valid "x.y" version,
+// ignoring any extra dot-separated parts. Otherwise return None.
+fn parse_glibc_version(version: &str) -> Option<(usize, usize)> {
+    let mut parsed_ints = version.split(".").map(str::parse::<usize>).fuse();
+    match (parsed_ints.next(), parsed_ints.next()) {
+        (Some(Ok(major)), Some(Ok(minor))) => Some((major, minor)),
+        _ => None
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_res_init() {
+        // This mostly just tests that the weak linkage doesn't panic wildly...
+        res_init_if_glibc_before_2_26().unwrap();
+    }
+
+    #[test]
+    fn test_parse_glibc_version() {
+        let cases = [
+            ("0.0", Some((0, 0))),
+            ("01.+2", Some((1, 2))),
+            ("3.4.5.six", Some((3, 4))),
+            ("1", None),
+            ("1.-2", None),
+            ("1.foo", None),
+            ("foo.1", None),
+        ];
+        for &(version_str, parsed) in cases.iter() {
+            assert_eq!(parsed, parse_glibc_version(version_str));
+        }
+    }
+}
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 5ef98d24710..4f33a2b12fe 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -223,7 +223,34 @@ pub fn current_exe() -> io::Result<PathBuf> {
 
 #[cfg(target_os = "netbsd")]
 pub fn current_exe() -> io::Result<PathBuf> {
-    ::fs::read_link("/proc/curproc/exe")
+    fn sysctl() -> io::Result<PathBuf> {
+        unsafe {
+            let mib = [libc::CTL_KERN, libc::KERN_PROC_ARGS, -1, libc::KERN_PROC_PATHNAME];
+            let mut path_len: usize = 0;
+            cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
+                             ptr::null_mut(), &mut path_len,
+                             ptr::null(), 0))?;
+            if path_len <= 1 {
+                return Err(io::Error::new(io::ErrorKind::Other,
+                           "KERN_PROC_PATHNAME sysctl returned zero-length string"))
+            }
+            let mut path: Vec<u8> = Vec::with_capacity(path_len);
+            cvt(libc::sysctl(mib.as_ptr(), mib.len() as ::libc::c_uint,
+                             path.as_ptr() as *mut libc::c_void, &mut path_len,
+                             ptr::null(), 0))?;
+            path.set_len(path_len - 1); // chop off NUL
+            Ok(PathBuf::from(OsString::from_vec(path)))
+        }
+    }
+    fn procfs() -> io::Result<PathBuf> {
+        let curproc_exe = path::Path::new("/proc/curproc/exe");
+        if curproc_exe.is_file() {
+            return ::fs::read_link(curproc_exe);
+        }
+        Err(io::Error::new(io::ErrorKind::Other,
+                           "/proc/curproc/exe doesn't point to regular file."))
+    }
+    sysctl().or_else(|_| procfs())
 }
 
 #[cfg(any(target_os = "bitrig", target_os = "openbsd"))]
@@ -483,12 +510,10 @@ pub fn home_dir() -> Option<PathBuf> {
 
     #[cfg(any(target_os = "android",
               target_os = "ios",
-              target_os = "nacl",
               target_os = "emscripten"))]
     unsafe fn fallback() -> Option<OsString> { None }
     #[cfg(not(any(target_os = "android",
                   target_os = "ios",
-                  target_os = "nacl",
                   target_os = "emscripten")))]
     unsafe fn fallback() -> Option<OsString> {
         let amt = match libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) {
@@ -513,3 +538,11 @@ pub fn home_dir() -> Option<PathBuf> {
 pub fn exit(code: i32) -> ! {
     unsafe { libc::exit(code as c_int) }
 }
+
+pub fn getpid() -> u32 {
+    unsafe { libc::getpid() as u32 }
+}
+
+pub fn getppid() -> u32 {
+    unsafe { libc::getppid() as u32 }
+}
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
index 777db17e3e1..a27e76a0e3b 100644
--- a/src/libstd/sys/unix/os_str.rs
+++ b/src/libstd/sys/unix/os_str.rs
@@ -15,6 +15,8 @@ use borrow::Cow;
 use fmt;
 use str;
 use mem;
+use rc::Rc;
+use sync::Arc;
 use sys_common::{AsInner, IntoInner};
 use std_unicode::lossy::Utf8Lossy;
 
@@ -123,6 +125,16 @@ impl Buf {
         let inner: Box<[u8]> = unsafe { mem::transmute(boxed) };
         Buf { inner: inner.into_vec() }
     }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        self.as_slice().into_arc()
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        self.as_slice().into_rc()
+    }
 }
 
 impl Slice {
@@ -156,4 +168,16 @@ impl Slice {
         let boxed: Box<[u8]> = Default::default();
         unsafe { mem::transmute(boxed) }
     }
+
+    #[inline]
+    pub fn into_arc(&self) -> Arc<Slice> {
+        let arc: Arc<[u8]> = Arc::from(&self.inner);
+        unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) }
+    }
+
+    #[inline]
+    pub fn into_rc(&self) -> Rc<Slice> {
+        let rc: Rc<[u8]> = Rc::from(&self.inner);
+        unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) }
+    }
 }
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 689ccd78524..383434b1cd8 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -464,7 +464,6 @@ mod tests {
     // test from being flaky we ignore it on macOS.
     #[test]
     #[cfg_attr(target_os = "macos", ignore)]
-    #[cfg_attr(target_os = "nacl", ignore)] // no signals on NaCl.
     // When run under our current QEMU emulation test suite this test fails,
     // although the reason isn't very clear as to why. For now this test is
     // ignored there.
diff --git a/src/libstd/sys/unix/process/process_fuchsia.rs b/src/libstd/sys/unix/process/process_fuchsia.rs
index 5d34da04446..a7a67ed36e8 100644
--- a/src/libstd/sys/unix/process/process_fuchsia.rs
+++ b/src/libstd/sys/unix/process/process_fuchsia.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use io;
-use libc;
+use libc::{self, size_t};
 use mem;
 use ptr;
 
@@ -148,8 +148,8 @@ impl Process {
         use sys::process::zircon::*;
 
         let mut proc_info: zx_info_process_t = Default::default();
-        let mut actual: zx_size_t = 0;
-        let mut avail: zx_size_t = 0;
+        let mut actual: size_t = 0;
+        let mut avail: size_t = 0;
 
         unsafe {
             zx_cvt(zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
@@ -171,8 +171,8 @@ impl Process {
         use sys::process::zircon::*;
 
         let mut proc_info: zx_info_process_t = Default::default();
-        let mut actual: zx_size_t = 0;
-        let mut avail: zx_size_t = 0;
+        let mut actual: size_t = 0;
+        let mut avail: size_t = 0;
 
         unsafe {
             let status = zx_object_wait_one(self.handle.raw(), ZX_TASK_TERMINATED,
diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs
index 870db820027..743c458d580 100644
--- a/src/libstd/sys/unix/process/process_unix.rs
+++ b/src/libstd/sys/unix/process/process_unix.rs
@@ -184,8 +184,8 @@ impl Command {
             *sys::os::environ() = envp.as_ptr();
         }
 
-        // NaCl has no signal support.
-        #[cfg(not(any(target_os = "nacl", target_os = "emscripten")))]
+        // emscripten has no signal support.
+        #[cfg(not(any(target_os = "emscripten")))]
         {
             use mem;
             // Reset signal handling so the child process starts in a
diff --git a/src/libstd/sys/unix/process/zircon.rs b/src/libstd/sys/unix/process/zircon.rs
index b5ec11b40fd..90864e6ef3f 100644
--- a/src/libstd/sys/unix/process/zircon.rs
+++ b/src/libstd/sys/unix/process/zircon.rs
@@ -15,15 +15,13 @@ use io;
 use os::raw::c_char;
 use u64;
 
-use libc::{c_int, c_void};
+use libc::{c_int, c_void, size_t};
 
-pub type zx_handle_t = i32;
+pub type zx_handle_t = u32;
 pub type zx_vaddr_t = usize;
 pub type zx_rights_t = u32;
 pub type zx_status_t = i32;
 
-pub type zx_size_t = usize;
-
 pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
 
 pub type zx_time_t = u64;
@@ -115,36 +113,37 @@ extern {
                               pending: *mut zx_signals_t) -> zx_status_t;
 
     pub fn zx_object_get_info(handle: zx_handle_t, topic: u32, buffer: *mut c_void,
-                              buffer_size: zx_size_t, actual_size: *mut zx_size_t,
-                              avail: *mut zx_size_t) -> zx_status_t;
+                              buffer_size: size_t, actual_size: *mut size_t,
+                              avail: *mut size_t) -> zx_status_t;
 }
 
 // From `enum special_handles` in system/ulib/launchpad/launchpad.c
 // HND_LOADER_SVC = 0
 // HND_EXEC_VMO = 1
-pub const HND_SPECIAL_COUNT: usize = 2;
+// HND_SEGMENTS_VMAR = 2
+const HND_SPECIAL_COUNT: c_int = 3;
 
 #[repr(C)]
 pub struct launchpad_t {
     argc: u32,
     envc: u32,
     args: *const c_char,
-    args_len: usize,
+    args_len: size_t,
     env: *const c_char,
-    env_len: usize,
+    env_len: size_t,
 
     handles: *mut zx_handle_t,
     handles_info: *mut u32,
-    handle_count: usize,
-    handle_alloc: usize,
+    handle_count: size_t,
+    handle_alloc: size_t,
 
     entry: zx_vaddr_t,
     base: zx_vaddr_t,
     vdso_base: zx_vaddr_t,
 
-    stack_size: usize,
+    stack_size: size_t,
 
-    special_handles: [zx_handle_t; HND_SPECIAL_COUNT],
+    special_handles: [zx_handle_t; HND_SPECIAL_COUNT as usize],
     loader_message: bool,
 }
 
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index fd066c9cdbe..caa18945765 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -8,20 +8,17 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::imp::OsRng;
-
 use mem;
+use slice;
 
-fn next_u32(fill_buf: &mut FnMut(&mut [u8])) -> u32 {
-    let mut buf: [u8; 4] = [0; 4];
-    fill_buf(&mut buf);
-    unsafe { mem::transmute::<[u8; 4], u32>(buf) }
-}
-
-fn next_u64(fill_buf: &mut FnMut(&mut [u8])) -> u64 {
-    let mut buf: [u8; 8] = [0; 8];
-    fill_buf(&mut buf);
-    unsafe { mem::transmute::<[u8; 8], u64>(buf) }
+pub fn hashmap_random_keys() -> (u64, u64) {
+    let mut v = (0, 0);
+    unsafe {
+        let view = slice::from_raw_parts_mut(&mut v as *mut _ as *mut u8,
+                                             mem::size_of_val(&v));
+        imp::fill_bytes(view);
+    }
+    return v
 }
 
 #[cfg(all(unix,
@@ -30,56 +27,22 @@ fn next_u64(fill_buf: &mut FnMut(&mut [u8])) -> u64 {
           not(target_os = "freebsd"),
           not(target_os = "fuchsia")))]
 mod imp {
-    use self::OsRngInner::*;
-    use super::{next_u32, next_u64};
-
     use fs::File;
-    use io;
+    use io::Read;
     use libc;
-    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",
-                  target_arch = "powerpc64",
-                  target_arch = "s390x")))]
+    #[cfg(any(target_os = "linux", target_os = "android"))]
     fn getrandom(buf: &mut [u8]) -> 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(target_arch = "arm")]
-        const NR_GETRANDOM: libc::c_long = 384;
-        #[cfg(target_arch = "s390x")]
-        const NR_GETRANDOM: libc::c_long = 349;
-        #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
-        const NR_GETRANDOM: libc::c_long = 359;
-        #[cfg(target_arch = "aarch64")]
-        const NR_GETRANDOM: libc::c_long = 278;
-
-        const GRND_NONBLOCK: libc::c_uint = 0x0001;
-
         unsafe {
-            libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)
+            libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr(), buf.len(), libc::GRND_NONBLOCK)
         }
     }
 
-    #[cfg(not(all(target_os = "linux",
-                  any(target_arch = "x86_64",
-                      target_arch = "x86",
-                      target_arch = "arm",
-                      target_arch = "aarch64",
-                      target_arch = "powerpc",
-                      target_arch = "powerpc64",
-                      target_arch = "s390x"))))]
+    #[cfg(not(any(target_os = "linux", target_os = "android")))]
     fn getrandom(_buf: &mut [u8]) -> libc::c_long { -1 }
 
-    fn getrandom_fill_bytes(v: &mut [u8]) {
+    fn getrandom_fill_bytes(v: &mut [u8]) -> bool {
         let mut read = 0;
         while read < v.len() {
             let result = getrandom(&mut v[read..]);
@@ -88,18 +51,7 @@ mod imp {
                 if err == libc::EINTR {
                     continue;
                 } else if err == libc::EAGAIN {
-                    // if getrandom() returns EAGAIN it would have blocked
-                    // because the non-blocking pool (urandom) has not
-                    // initialized in the kernel yet due to a lack of entropy
-                    // the fallback we do here is to avoid blocking applications
-                    // which could depend on this call without ever knowing
-                    // they do and don't have a work around. The PRNG of
-                    // /dev/urandom will still be used but not over a completely
-                    // full entropy pool
-                    let reader = File::open("/dev/urandom").expect("Unable to open /dev/urandom");
-                    let mut reader_rng = ReaderRng::new(reader);
-                    reader_rng.fill_bytes(&mut v[read..]);
-                    read += v.len();
+                    return false
                 } else {
                     panic!("unexpected getrandom error: {}", err);
                 }
@@ -107,17 +59,13 @@ mod imp {
                 read += result as usize;
             }
         }
+
+        return true
     }
 
-    #[cfg(all(target_os = "linux",
-              any(target_arch = "x86_64",
-                  target_arch = "x86",
-                  target_arch = "arm",
-                  target_arch = "aarch64",
-                  target_arch = "powerpc",
-                  target_arch = "powerpc64",
-                  target_arch = "s390x")))]
+    #[cfg(any(target_os = "linux", target_os = "android"))]
     fn is_getrandom_available() -> bool {
+        use io;
         use sync::atomic::{AtomicBool, Ordering};
         use sync::Once;
 
@@ -139,99 +87,40 @@ mod imp {
         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",
-                      target_arch = "powerpc64",
-                      target_arch = "s390x"))))]
+    #[cfg(not(any(target_os = "linux", target_os = "android")))]
     fn is_getrandom_available() -> bool { false }
 
-    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 = File::open("/dev/urandom")?;
-            let reader_rng = ReaderRng::new(reader);
-
-            Ok(OsRng { inner: OsReaderRng(reader_rng) })
+    pub fn fill_bytes(v: &mut [u8]) {
+        // getrandom_fill_bytes here can fail if getrandom() returns EAGAIN,
+        // meaning it would have blocked because the non-blocking pool (urandom)
+        // has not initialized in the kernel yet due to a lack of entropy the
+        // fallback we do here is to avoid blocking applications which could
+        // depend on this call without ever knowing they do and don't have a
+        // work around.  The PRNG of /dev/urandom will still be used but not
+        // over a completely full entropy pool
+        if is_getrandom_available() && getrandom_fill_bytes(v) {
+            return
         }
-    }
 
-    impl Rng for OsRng {
-        fn next_u32(&mut self) -> u32 {
-            match self.inner {
-                OsGetrandomRng => next_u32(&mut getrandom_fill_bytes),
-                OsReaderRng(ref mut rng) => rng.next_u32(),
-            }
-        }
-        fn next_u64(&mut self) -> u64 {
-            match self.inner {
-                OsGetrandomRng => next_u64(&mut getrandom_fill_bytes),
-                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)
-            }
-        }
+        let mut file = File::open("/dev/urandom")
+            .expect("failed to open /dev/urandom");
+        file.read_exact(v).expect("failed to read /dev/urandom");
     }
 }
 
 #[cfg(target_os = "openbsd")]
 mod imp {
-    use super::{next_u32, next_u64};
-
-    use io;
     use libc;
     use sys::os::errno;
-    use rand::Rng;
-
-    pub struct OsRng {
-        // dummy field to ensure that this struct cannot be constructed outside
-        // of this module
-        _dummy: (),
-    }
-
-    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 {
-            next_u32(&mut |v| self.fill_bytes(v))
-        }
-        fn next_u64(&mut self) -> u64 {
-            next_u64(&mut |v| self.fill_bytes(v))
-        }
-        fn fill_bytes(&mut self, v: &mut [u8]) {
-            // getentropy(2) permits a maximum buffer size of 256 bytes
-            for s in v.chunks_mut(256) {
-                let ret = unsafe {
-                    libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
-                };
-                if ret == -1 {
-                    panic!("unexpected getentropy error: {}", errno());
-                }
+    pub fn fill_bytes(v: &mut [u8]) {
+        // getentropy(2) permits a maximum buffer size of 256 bytes
+        for s in v.chunks_mut(256) {
+            let ret = unsafe {
+                libc::getentropy(s.as_mut_ptr() as *mut libc::c_void, s.len())
+            };
+            if ret == -1 {
+                panic!("unexpected getentropy error: {}", errno());
             }
         }
     }
@@ -239,18 +128,9 @@ mod imp {
 
 #[cfg(target_os = "ios")]
 mod imp {
-    use super::{next_u32, next_u64};
-
     use io;
-    use ptr;
-    use rand::Rng;
     use libc::{c_int, size_t};
-
-    pub struct OsRng {
-        // dummy field to ensure that this struct cannot be constructed outside
-        // of this module
-        _dummy: (),
-    }
+    use ptr;
 
     enum SecRandom {}
 
@@ -259,79 +139,41 @@ mod imp {
 
     extern {
         fn SecRandomCopyBytes(rnd: *const SecRandom,
-                              count: size_t, bytes: *mut u8) -> c_int;
+                              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 {
-            next_u32(&mut |v| self.fill_bytes(v))
-        }
-        fn next_u64(&mut self) -> u64 {
-            next_u64(&mut |v| self.fill_bytes(v))
-        }
-        fn fill_bytes(&mut self, v: &mut [u8]) {
-            let ret = unsafe {
-                SecRandomCopyBytes(kSecRandomDefault, v.len(),
-                                   v.as_mut_ptr())
-            };
-            if ret == -1 {
-                panic!("couldn't generate random bytes: {}",
-                       io::Error::last_os_error());
-            }
+    pub fn fill_bytes(v: &mut [u8]) {
+        let ret = unsafe {
+            SecRandomCopyBytes(kSecRandomDefault,
+                               v.len(),
+                               v.as_mut_ptr())
+        };
+        if ret == -1 {
+            panic!("couldn't generate random bytes: {}",
+                   io::Error::last_os_error());
         }
     }
 }
 
 #[cfg(target_os = "freebsd")]
 mod imp {
-    use super::{next_u32, next_u64};
-
-    use io;
     use libc;
-    use rand::Rng;
     use ptr;
 
-    pub struct OsRng {
-        // dummy field to ensure that this struct cannot be constructed outside
-        // of this module
-        _dummy: (),
-    }
-
-    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 {
-            next_u32(&mut |v| self.fill_bytes(v))
-        }
-        fn next_u64(&mut self) -> u64 {
-            next_u64(&mut |v| self.fill_bytes(v))
-        }
-        fn fill_bytes(&mut self, v: &mut [u8]) {
-            let mib = [libc::CTL_KERN, libc::KERN_ARND];
-            // kern.arandom permits a maximum buffer size of 256 bytes
-            for s in v.chunks_mut(256) {
-                let mut s_len = s.len();
-                let ret = unsafe {
-                    libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
-                                 s.as_mut_ptr() as *mut _, &mut s_len,
-                                 ptr::null(), 0)
-                };
-                if ret == -1 || s_len != s.len() {
-                    panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
-                           ret, s.len(), s_len);
-                }
+    pub fn fill_bytes(v: &mut [u8]) {
+        let mib = [libc::CTL_KERN, libc::KERN_ARND];
+        // kern.arandom permits a maximum buffer size of 256 bytes
+        for s in v.chunks_mut(256) {
+            let mut s_len = s.len();
+            let ret = unsafe {
+                libc::sysctl(mib.as_ptr(), mib.len() as libc::c_uint,
+                             s.as_mut_ptr() as *mut _, &mut s_len,
+                             ptr::null(), 0)
+            };
+            if ret == -1 || s_len != s.len() {
+                panic!("kern.arandom sysctl failed! (returned {}, s.len() {}, oldlenp {})",
+                       ret, s.len(), s_len);
             }
         }
     }
@@ -339,11 +181,6 @@ mod imp {
 
 #[cfg(target_os = "fuchsia")]
 mod imp {
-    use super::{next_u32, next_u64};
-
-    use io;
-    use rand::Rng;
-
     #[link(name = "zircon")]
     extern {
         fn zx_cprng_draw(buffer: *mut u8, len: usize, actual: *mut usize) -> i32;
@@ -361,39 +198,18 @@ mod imp {
         }
     }
 
-    pub struct OsRng {
-        // dummy field to ensure that this struct cannot be constructed outside
-        // of this module
-        _dummy: (),
-    }
-
-    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 {
-            next_u32(&mut |v| self.fill_bytes(v))
-        }
-        fn next_u64(&mut self) -> u64 {
-            next_u64(&mut |v| self.fill_bytes(v))
-        }
-        fn fill_bytes(&mut self, v: &mut [u8]) {
-            let mut buf = v;
-            while !buf.is_empty() {
-                let ret = getrandom(buf);
-                match ret {
-                    Err(err) => {
-                        panic!("kernel zx_cprng_draw call failed! (returned {}, buf.len() {})",
-                            err, buf.len())
-                    }
-                    Ok(actual) => {
-                        let move_buf = buf;
-                        buf = &mut move_buf[(actual as usize)..];
-                    }
+    pub fn fill_bytes(v: &mut [u8]) {
+        let mut buf = v;
+        while !buf.is_empty() {
+            let ret = getrandom(buf);
+            match ret {
+                Err(err) => {
+                    panic!("kernel zx_cprng_draw call failed! (returned {}, buf.len() {})",
+                        err, buf.len())
+                }
+                Ok(actual) => {
+                    let move_buf = buf;
+                    buf = &mut move_buf[(actual as usize)..];
                 }
             }
         }
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
index 7a8fe25d98e..e9b3d4affc7 100644
--- a/src/libstd/sys/unix/stdio.rs
+++ b/src/libstd/sys/unix/stdio.rs
@@ -70,5 +70,8 @@ impl io::Write for Stderr {
     }
 }
 
-pub const EBADF_ERR: i32 = ::libc::EBADF as i32;
+pub fn is_ebadf(err: &io::Error) -> bool {
+    err.raw_os_error() == Some(libc::EBADF as i32)
+}
+
 pub const STDIN_BUF_SIZE: usize = ::sys_common::io::DEFAULT_BUF_SIZE;
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 6c4a3324296..9da33f5adac 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -87,7 +87,7 @@ impl Thread {
         };
 
         extern fn thread_start(main: *mut libc::c_void) -> *mut libc::c_void {
-            unsafe { start_thread(main); }
+            unsafe { start_thread(main as *mut u8); }
             ptr::null_mut()
         }
     }
@@ -149,7 +149,7 @@ impl Thread {
 
     pub fn sleep(dur: Duration) {
         let mut secs = dur.as_secs();
-        let mut nsecs = dur.subsec_nanos() as libc::c_long;
+        let mut nsecs = dur.subsec_nanos() as _;
 
         // If we're awoken with a signal then the return value will be -1 and
         // nanosleep will fill in `ts` with the remaining time.
diff --git a/src/libstd/sys/unix/time.rs b/src/libstd/sys/unix/time.rs
index c1bea95ce91..837cd7292e2 100644
--- a/src/libstd/sys/unix/time.rs
+++ b/src/libstd/sys/unix/time.rs
@@ -60,7 +60,7 @@ impl Timespec {
         Timespec {
             t: libc::timespec {
                 tv_sec: secs,
-                tv_nsec: nsec as libc::c_long,
+                tv_nsec: nsec as _,
             },
         }
     }
@@ -83,7 +83,7 @@ impl Timespec {
         Timespec {
             t: libc::timespec {
                 tv_sec: secs,
-                tv_nsec: nsec as libc::c_long,
+                tv_nsec: nsec as _,
             },
         }
     }