Merge branch 'master' into redox
This commit is contained in:
commit
0bb9a95907
896 changed files with 53004 additions and 8585 deletions
|
|
@ -11,6 +11,7 @@
|
|||
use self::Entry::*;
|
||||
use self::VacantEntryState::*;
|
||||
|
||||
use cell::Cell;
|
||||
use borrow::Borrow;
|
||||
use cmp::max;
|
||||
use fmt::{self, Debug};
|
||||
|
|
@ -2049,24 +2050,21 @@ impl RandomState {
|
|||
// many hash maps are created on a thread. To solve this performance
|
||||
// trap we cache the first set of randomly generated keys per-thread.
|
||||
//
|
||||
// In doing this, however, we lose the property that all hash maps have
|
||||
// nondeterministic iteration order as all of those created on the same
|
||||
// thread would have the same hash keys. This property has been nice in
|
||||
// the past as it allows for maximal flexibility in the implementation
|
||||
// of `HashMap` itself.
|
||||
//
|
||||
// The constraint here (if there even is one) is just that maps created
|
||||
// on the same thread have the same iteration order, and that *may* be
|
||||
// relied upon even though it is not a documented guarantee at all of
|
||||
// the `HashMap` type. In any case we've decided that this is reasonable
|
||||
// for now, so caching keys thread-locally seems fine.
|
||||
thread_local!(static KEYS: (u64, u64) = {
|
||||
// Later in #36481 it was discovered that exposing a deterministic
|
||||
// iteration order allows a form of DOS attack. To counter that we
|
||||
// increment one of the seeds on every RandomState creation, giving
|
||||
// every corresponding HashMap a different iteration order.
|
||||
thread_local!(static KEYS: Cell<(u64, u64)> = {
|
||||
let r = rand::OsRng::new();
|
||||
let mut r = r.expect("failed to create an OS RNG");
|
||||
(r.gen(), r.gen())
|
||||
Cell::new((r.gen(), r.gen()))
|
||||
});
|
||||
|
||||
KEYS.with(|&(k0, k1)| RandomState { k0: k0, k1: k1 })
|
||||
KEYS.with(|keys| {
|
||||
let (k0, k1) = keys.get();
|
||||
keys.set((k0.wrapping_add(1), k1));
|
||||
RandomState { k0: k0, k1: k1 }
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -686,7 +686,7 @@ impl ToOwned for CStr {
|
|||
type Owned = CString;
|
||||
|
||||
fn to_owned(&self) -> CString {
|
||||
unsafe { CString::from_vec_unchecked(self.to_bytes().to_vec()) }
|
||||
CString { inner: self.to_bytes_with_nul().to_vec().into_boxed_slice() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ use error;
|
|||
use fmt;
|
||||
use result;
|
||||
use sys;
|
||||
use convert::From;
|
||||
|
||||
/// A specialized [`Result`](../result/enum.Result.html) type for I/O
|
||||
/// operations.
|
||||
|
|
@ -62,6 +63,7 @@ pub struct Error {
|
|||
|
||||
enum Repr {
|
||||
Os(i32),
|
||||
Simple(ErrorKind),
|
||||
Custom(Box<Custom>),
|
||||
}
|
||||
|
||||
|
|
@ -124,23 +126,28 @@ pub enum ErrorKind {
|
|||
InvalidInput,
|
||||
/// Data not valid for the operation were encountered.
|
||||
///
|
||||
/// Unlike `InvalidInput`, this typically means that the operation
|
||||
/// Unlike [`InvalidInput`], this typically means that the operation
|
||||
/// parameters were valid, however the error was caused by malformed
|
||||
/// input data.
|
||||
///
|
||||
/// For example, a function that reads a file into a string will error with
|
||||
/// `InvalidData` if the file's contents are not valid UTF-8.
|
||||
///
|
||||
/// [`InvalidInput`]: #variant.InvalidInput
|
||||
#[stable(feature = "io_invalid_data", since = "1.2.0")]
|
||||
InvalidData,
|
||||
/// The I/O operation's timeout expired, causing it to be canceled.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
TimedOut,
|
||||
/// An error returned when an operation could not be completed because a
|
||||
/// call to `write` returned `Ok(0)`.
|
||||
/// call to [`write()`] returned [`Ok(0)`].
|
||||
///
|
||||
/// This typically means that an operation could only succeed if it wrote a
|
||||
/// particular number of bytes but only a smaller number of bytes could be
|
||||
/// written.
|
||||
///
|
||||
/// [`write()`]: ../../std/io/trait.Write.html#tymethod.write
|
||||
/// [`Ok(0)`]: ../../std/io/type.Result.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
WriteZero,
|
||||
/// This operation was interrupted.
|
||||
|
|
@ -171,6 +178,43 @@ pub enum ErrorKind {
|
|||
__Nonexhaustive,
|
||||
}
|
||||
|
||||
impl ErrorKind {
|
||||
fn as_str(&self) -> &'static str {
|
||||
match *self {
|
||||
ErrorKind::NotFound => "entity not found",
|
||||
ErrorKind::PermissionDenied => "permission denied",
|
||||
ErrorKind::ConnectionRefused => "connection refused",
|
||||
ErrorKind::ConnectionReset => "connection reset",
|
||||
ErrorKind::ConnectionAborted => "connection aborted",
|
||||
ErrorKind::NotConnected => "not connected",
|
||||
ErrorKind::AddrInUse => "address in use",
|
||||
ErrorKind::AddrNotAvailable => "address not available",
|
||||
ErrorKind::BrokenPipe => "broken pipe",
|
||||
ErrorKind::AlreadyExists => "entity already exists",
|
||||
ErrorKind::WouldBlock => "operation would block",
|
||||
ErrorKind::InvalidInput => "invalid input parameter",
|
||||
ErrorKind::InvalidData => "invalid data",
|
||||
ErrorKind::TimedOut => "timed out",
|
||||
ErrorKind::WriteZero => "write zero",
|
||||
ErrorKind::Interrupted => "operation interrupted",
|
||||
ErrorKind::Other => "other os error",
|
||||
ErrorKind::UnexpectedEof => "unexpected end of file",
|
||||
ErrorKind::__Nonexhaustive => unreachable!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Intended for use for errors not exposed to the user, where allocating onto
|
||||
/// the heap (for normal construction via Error::new) is too costly.
|
||||
#[stable(feature = "io_error_from_errorkind", since = "1.14.0")]
|
||||
impl From<ErrorKind> for Error {
|
||||
fn from(kind: ErrorKind) -> Error {
|
||||
Error {
|
||||
repr: Repr::Simple(kind)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Error {
|
||||
/// Creates a new I/O error from a known kind of error as well as an
|
||||
/// arbitrary error payload.
|
||||
|
|
@ -285,6 +329,7 @@ impl Error {
|
|||
match self.repr {
|
||||
Repr::Os(i) => Some(i),
|
||||
Repr::Custom(..) => None,
|
||||
Repr::Simple(..) => None,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,6 +362,7 @@ impl Error {
|
|||
pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
|
||||
match self.repr {
|
||||
Repr::Os(..) => None,
|
||||
Repr::Simple(..) => None,
|
||||
Repr::Custom(ref c) => Some(&*c.error),
|
||||
}
|
||||
}
|
||||
|
|
@ -387,6 +433,7 @@ impl Error {
|
|||
pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
|
||||
match self.repr {
|
||||
Repr::Os(..) => None,
|
||||
Repr::Simple(..) => None,
|
||||
Repr::Custom(ref mut c) => Some(&mut *c.error),
|
||||
}
|
||||
}
|
||||
|
|
@ -420,6 +467,7 @@ impl Error {
|
|||
pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
|
||||
match self.repr {
|
||||
Repr::Os(..) => None,
|
||||
Repr::Simple(..) => None,
|
||||
Repr::Custom(c) => Some(c.error)
|
||||
}
|
||||
}
|
||||
|
|
@ -447,6 +495,7 @@ impl Error {
|
|||
match self.repr {
|
||||
Repr::Os(code) => sys::decode_error_kind(code),
|
||||
Repr::Custom(ref c) => c.kind,
|
||||
Repr::Simple(kind) => kind,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -458,6 +507,7 @@ impl fmt::Debug for Repr {
|
|||
fmt.debug_struct("Os").field("code", code)
|
||||
.field("message", &sys::os::error_string(*code)).finish(),
|
||||
Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(),
|
||||
Repr::Simple(kind) => fmt.debug_tuple("Kind").field(&kind).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -471,6 +521,7 @@ impl fmt::Display for Error {
|
|||
write!(fmt, "{} (os error {})", detail, code)
|
||||
}
|
||||
Repr::Custom(ref c) => c.error.fmt(fmt),
|
||||
Repr::Simple(kind) => write!(fmt, "{}", kind.as_str()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -479,27 +530,7 @@ impl fmt::Display for Error {
|
|||
impl error::Error for Error {
|
||||
fn description(&self) -> &str {
|
||||
match self.repr {
|
||||
Repr::Os(..) => match self.kind() {
|
||||
ErrorKind::NotFound => "entity not found",
|
||||
ErrorKind::PermissionDenied => "permission denied",
|
||||
ErrorKind::ConnectionRefused => "connection refused",
|
||||
ErrorKind::ConnectionReset => "connection reset",
|
||||
ErrorKind::ConnectionAborted => "connection aborted",
|
||||
ErrorKind::NotConnected => "not connected",
|
||||
ErrorKind::AddrInUse => "address in use",
|
||||
ErrorKind::AddrNotAvailable => "address not available",
|
||||
ErrorKind::BrokenPipe => "broken pipe",
|
||||
ErrorKind::AlreadyExists => "entity already exists",
|
||||
ErrorKind::WouldBlock => "operation would block",
|
||||
ErrorKind::InvalidInput => "invalid input parameter",
|
||||
ErrorKind::InvalidData => "invalid data",
|
||||
ErrorKind::TimedOut => "timed out",
|
||||
ErrorKind::WriteZero => "write zero",
|
||||
ErrorKind::Interrupted => "operation interrupted",
|
||||
ErrorKind::Other => "other os error",
|
||||
ErrorKind::UnexpectedEof => "unexpected end of file",
|
||||
ErrorKind::__Nonexhaustive => unreachable!()
|
||||
},
|
||||
Repr::Os(..) | Repr::Simple(..) => self.kind().as_str(),
|
||||
Repr::Custom(ref c) => c.error.description(),
|
||||
}
|
||||
}
|
||||
|
|
@ -507,6 +538,7 @@ impl error::Error for Error {
|
|||
fn cause(&self) -> Option<&error::Error> {
|
||||
match self.repr {
|
||||
Repr::Os(..) => None,
|
||||
Repr::Simple(..) => None,
|
||||
Repr::Custom(ref c) => c.error.cause(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
//! of other types, and you can implement them for your types too. As such,
|
||||
//! you'll see a few different types of I/O throughout the documentation in
|
||||
//! this module: [`File`]s, [`TcpStream`]s, and sometimes even [`Vec<T>`]s. For
|
||||
//! example, `Read` adds a `read()` method, which we can use on `File`s:
|
||||
//! example, [`Read`] adds a [`read()`] method, which we can use on `File`s:
|
||||
//!
|
||||
//! ```
|
||||
//! use std::io;
|
||||
|
|
@ -251,6 +251,7 @@
|
|||
//! [`Lines`]: struct.Lines.html
|
||||
//! [`io::Result`]: type.Result.html
|
||||
//! [`try!`]: ../macro.try.html
|
||||
//! [`read()`]: trait.Read.html#tymethod.read
|
||||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
@ -814,19 +815,23 @@ pub trait Read {
|
|||
///
|
||||
/// Implementors of the `Write` trait are sometimes called 'writers'.
|
||||
///
|
||||
/// Writers are defined by two required methods, `write()` and `flush()`:
|
||||
/// Writers are defined by two required methods, [`write()`] and [`flush()`]:
|
||||
///
|
||||
/// * The `write()` method will attempt to write some data into the object,
|
||||
/// * The [`write()`] method will attempt to write some data into the object,
|
||||
/// returning how many bytes were successfully written.
|
||||
///
|
||||
/// * The `flush()` method is useful for adaptors and explicit buffers
|
||||
/// * The [`flush()`] method is useful for adaptors and explicit buffers
|
||||
/// themselves for ensuring that all buffered data has been pushed out to the
|
||||
/// 'true sink'.
|
||||
///
|
||||
/// Writers are intended to be composable with one another. Many implementors
|
||||
/// throughout `std::io` take and provide types which implement the `Write`
|
||||
/// throughout [`std::io`] take and provide types which implement the `Write`
|
||||
/// trait.
|
||||
///
|
||||
/// [`write()`]: #tymethod.write
|
||||
/// [`flush()`]: #tymethod.flush
|
||||
/// [`std::io`]: index.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
@ -1475,10 +1480,10 @@ impl<T: BufRead, U: BufRead> BufRead for Chain<T, U> {
|
|||
|
||||
/// Reader adaptor which limits the bytes read from an underlying reader.
|
||||
///
|
||||
/// This struct is generally created by calling [`take()`][take] on a reader.
|
||||
/// Please see the documentation of `take()` for more details.
|
||||
/// This struct is generally created by calling [`take()`] on a reader.
|
||||
/// Please see the documentation of [`take()`] for more details.
|
||||
///
|
||||
/// [take]: trait.Read.html#method.take
|
||||
/// [`take()`]: trait.Read.html#method.take
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Take<T> {
|
||||
inner: T,
|
||||
|
|
@ -1491,8 +1496,10 @@ impl<T> Take<T> {
|
|||
///
|
||||
/// # Note
|
||||
///
|
||||
/// This instance may reach EOF after reading fewer bytes than indicated by
|
||||
/// this method if the underlying `Read` instance reaches EOF.
|
||||
/// This instance may reach `EOF` after reading fewer bytes than indicated by
|
||||
/// this method if the underlying [`Read`] instance reaches EOF.
|
||||
///
|
||||
/// [`Read`]: ../../std/io/trait.Read.html
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
|
|||
|
|
@ -324,10 +324,11 @@ impl<'a> BufRead for StdinLock<'a> {
|
|||
///
|
||||
/// Each handle shares a global buffer of data to be written to the standard
|
||||
/// output stream. Access is also synchronized via a lock and explicit control
|
||||
/// over locking is available via the `lock` method.
|
||||
/// over locking is available via the [`lock()`] method.
|
||||
///
|
||||
/// Created by the [`io::stdout`] method.
|
||||
///
|
||||
/// [`lock()`]: #method.lock
|
||||
/// [`io::stdout`]: fn.stdout.html
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub struct Stdout {
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@
|
|||
#![feature(const_fn)]
|
||||
#![feature(core_float)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(dotdot_in_tuple_patterns)]
|
||||
#![cfg_attr(stage0, feature(dotdot_in_tuple_patterns))]
|
||||
#![feature(dropck_parametricity)]
|
||||
#![feature(float_extras)]
|
||||
#![feature(float_from_str_radix)]
|
||||
|
|
|
|||
|
|
@ -67,6 +67,9 @@ impl UdpSocket {
|
|||
///
|
||||
/// Address type can be any implementor of `ToSocketAddrs` trait. See its
|
||||
/// documentation for concrete examples.
|
||||
/// This will return an error when the IP version of the local socket
|
||||
/// does not match that returned from `ToSocketAddrs`
|
||||
/// See https://github.com/rust-lang/rust/issues/34202 for more details.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A)
|
||||
-> io::Result<usize> {
|
||||
|
|
|
|||
|
|
@ -1173,6 +1173,13 @@ impl From<OsString> for PathBuf {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "from_path_buf_for_os_string", since = "1.14.0")]
|
||||
impl From<PathBuf> for OsString {
|
||||
fn from(path_buf : PathBuf) -> OsString {
|
||||
path_buf.inner
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl From<String> for PathBuf {
|
||||
fn from(s: String) -> PathBuf {
|
||||
|
|
@ -1283,13 +1290,6 @@ impl AsRef<OsStr> for PathBuf {
|
|||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Into<OsString> for PathBuf {
|
||||
fn into(self) -> OsString {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
|
||||
/// A slice of a path (akin to [`str`]).
|
||||
///
|
||||
/// This type supports a number of operations for inspecting a path, including
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
//! integration code in `std::sys_common`. See that module's
|
||||
//! documentation for details.
|
||||
//!
|
||||
//! In the future it would be desirable for the indepedent
|
||||
//! In the future it would be desirable for the independent
|
||||
//! implementations of this module to be extracted to their own crates
|
||||
//! that `std` can link to, thus enabling their implementation
|
||||
//! out-of-tree via crate replacement. Though due to the complex
|
||||
|
|
|
|||
|
|
@ -350,11 +350,19 @@ mod imp {
|
|||
|
||||
#[link(name = "magenta")]
|
||||
extern {
|
||||
fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize;
|
||||
fn mx_cprng_draw(buffer: *mut u8, len: usize, actual: *mut usize) -> i32;
|
||||
}
|
||||
|
||||
fn getrandom(buf: &mut [u8]) -> isize {
|
||||
unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) }
|
||||
fn getrandom(buf: &mut [u8]) -> Result<usize, i32> {
|
||||
unsafe {
|
||||
let mut actual = 0;
|
||||
let status = mx_cprng_draw(buf.as_mut_ptr(), buf.len(), &mut actual);
|
||||
if status == 0 {
|
||||
Ok(actual)
|
||||
} else {
|
||||
Err(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct OsRng {
|
||||
|
|
@ -381,12 +389,16 @@ mod imp {
|
|||
let mut buf = v;
|
||||
while !buf.is_empty() {
|
||||
let ret = getrandom(buf);
|
||||
if ret < 0 {
|
||||
panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
|
||||
ret, buf.len());
|
||||
match ret {
|
||||
Err(err) => {
|
||||
panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
|
||||
err, buf.len())
|
||||
}
|
||||
Ok(actual) => {
|
||||
let move_buf = buf;
|
||||
buf = &mut move_buf[(actual as usize)..];
|
||||
}
|
||||
}
|
||||
let move_buf = buf;
|
||||
buf = &mut move_buf[(ret as usize)..];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
//! Platform-independent platform abstraction
|
||||
//!
|
||||
//! This is the platform-independent portion of the standard libraries
|
||||
//! This is the platform-independent portion of the standard library's
|
||||
//! platform abstraction layer, whereas `std::sys` is the
|
||||
//! platform-specific portion.
|
||||
//!
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue