diff --git a/src/librustc_back/tempdir.rs b/src/librustc_back/tempdir.rs index 4d8619a81216f..0e87ba278db21 100644 --- a/src/librustc_back/tempdir.rs +++ b/src/librustc_back/tempdir.rs @@ -61,12 +61,12 @@ impl TempDir { let path = tmpdir.join(&leaf); match fs::create_dir(&path) { Ok(_) => return Ok(TempDir { path: Some(path) }), - Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(ref e) if e.kind() == ErrorKind::AlreadyExists => {} Err(e) => return Err(e) } } - Err(Error::new(ErrorKind::PathAlreadyExists, + Err(Error::new(ErrorKind::AlreadyExists, "too many temporary directories already exist", None)) } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index bd4177861dd42..0650b4d515860 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -35,7 +35,6 @@ #![feature(test)] #![feature(unicode)] #![feature(str_words)] -#![feature(io)] #![feature(file_path)] #![feature(path_ext)] #![feature(path_relative_from)] diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs index 31c270dca6bba..90cb88046e53d 100644 --- a/src/libserialize/lib.rs +++ b/src/libserialize/lib.rs @@ -31,7 +31,6 @@ Core encoding and decoding interfaces. #![feature(collections)] #![feature(core)] #![feature(int_uint)] -#![feature(io)] #![feature(old_path)] #![feature(rustc_private)] #![feature(staged_api)] diff --git a/src/libstd/fs/mod.rs b/src/libstd/fs/mod.rs index ba89b3a0ea63f..80336a0da87aa 100644 --- a/src/libstd/fs/mod.rs +++ b/src/libstd/fs/mod.rs @@ -493,7 +493,7 @@ pub fn copy(from: P, to: Q) -> io::Result { let from = from.as_path(); let to = to.as_path(); if !from.is_file() { - return Err(Error::new(ErrorKind::MismatchedFileTypeForOperation, + return Err(Error::new(ErrorKind::InvalidInput, "the source path is not an existing file", None)) } @@ -1134,7 +1134,7 @@ mod tests { let dir = &tmpdir.join("mkdir_error_twice"); check!(fs::create_dir(dir)); let e = fs::create_dir(dir).err().unwrap(); - assert_eq!(e.kind(), ErrorKind::PathAlreadyExists); + assert_eq!(e.kind(), ErrorKind::AlreadyExists); } #[test] diff --git a/src/libstd/fs/tempdir.rs b/src/libstd/fs/tempdir.rs index c1da77a6668f5..8f32d7a586459 100644 --- a/src/libstd/fs/tempdir.rs +++ b/src/libstd/fs/tempdir.rs @@ -68,12 +68,12 @@ impl TempDir { let path = tmpdir.join(&leaf); match fs::create_dir(&path) { Ok(_) => return Ok(TempDir { path: Some(path) }), - Err(ref e) if e.kind() == ErrorKind::PathAlreadyExists => {} + Err(ref e) if e.kind() == ErrorKind::AlreadyExists => {} Err(e) => return Err(e) } } - Err(Error::new(ErrorKind::PathAlreadyExists, + Err(Error::new(ErrorKind::AlreadyExists, "too many temporary directories already exist", None)) } diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs index 530c672810723..f445ace081e4f 100644 --- a/src/libstd/io/error.rs +++ b/src/libstd/io/error.rs @@ -51,41 +51,53 @@ struct Custom { } /// A list specifying general categories of I/O error. +/// +/// This list is intended to grow over time and it is not recommended to +/// exhaustively match against it. #[derive(Copy, PartialEq, Eq, Clone, Debug)] -#[unstable(feature = "io", - reason = "the interaction between OS error codes and how they map to \ - these names (as well as the names themselves) has not \ - been thoroughly thought out")] +#[stable(feature = "rust1", since = "1.0.0")] pub enum ErrorKind { - /// The file was not found. - FileNotFound, - /// The file permissions disallowed access to this file. + /// An entity was not found, often a file. + #[stable(feature = "rust1", since = "1.0.0")] + NotFound, + /// The operation lacked the necessary privileges to complete. + #[stable(feature = "rust1", since = "1.0.0")] PermissionDenied, /// The connection was refused by the remote server. + #[stable(feature = "rust1", since = "1.0.0")] ConnectionRefused, /// The connection was reset by the remote server. + #[stable(feature = "rust1", since = "1.0.0")] ConnectionReset, /// The connection was aborted (terminated) by the remote server. + #[stable(feature = "rust1", since = "1.0.0")] ConnectionAborted, /// The network operation failed because it was not connected yet. + #[stable(feature = "rust1", since = "1.0.0")] NotConnected, + /// A socket address could not be bound because the address is already in + /// use elsewhere. + #[stable(feature = "rust1", since = "1.0.0")] + AddrInUse, + /// A nonexistent interface was requested or the requested address was not + /// local. + #[stable(feature = "rust1", since = "1.0.0")] + AddrNotAvailable, /// The operation failed because a pipe was closed. + #[stable(feature = "rust1", since = "1.0.0")] BrokenPipe, - /// A file already existed with that name. - PathAlreadyExists, - /// No file exists at that location. - PathDoesntExist, - /// The path did not specify the type of file that this operation required. - /// For example, attempting to copy a directory with the `fs::copy()` - /// operation will fail with this error. - MismatchedFileTypeForOperation, - /// The operation temporarily failed (for example, because a signal was - /// received), and retrying may succeed. - ResourceUnavailable, - /// A parameter was incorrect in a way that caused an I/O error not part of - /// this list. + /// An entity already exists, often a file. + #[stable(feature = "rust1", since = "1.0.0")] + AlreadyExists, + /// The operation needs to block to complete, but the blocking operation was + /// requested to not occur. + #[stable(feature = "rust1", since = "1.0.0")] + WouldBlock, + /// A parameter was incorrect. + #[stable(feature = "rust1", since = "1.0.0")] InvalidInput, /// 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)`. @@ -93,11 +105,23 @@ pub enum ErrorKind { /// 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. + #[stable(feature = "rust1", since = "1.0.0")] WriteZero, - /// This operation was interrupted + /// This operation was interrupted. + /// + /// Interrupted operations can typically be retried. + #[stable(feature = "rust1", since = "1.0.0")] Interrupted, /// Any I/O error not part of this list. + #[stable(feature = "rust1", since = "1.0.0")] Other, + + /// Any I/O error not part of this list. + #[unstable(feature = "std_misc", + reason = "better expressed through extensible enums that this \ + enum cannot be exhaustively matched against")] + #[doc(hidden)] + __Nonexhaustive, } impl Error { @@ -134,6 +158,19 @@ impl Error { Error { repr: Repr::Os(code) } } + /// Returns the OS error that this error represents (if any). + /// + /// If this `Error` was constructed via `last_os_error` then this function + /// will return `Some`, otherwise it will return `None`. + #[unstable(feature = "io", reason = "function was just added and the return \ + type may become an abstract OS error")] + pub fn raw_os_error(&self) -> Option { + match self.repr { + Repr::Os(i) => Some(i), + Repr::Custom(..) => None, + } + } + /// Return the corresponding `ErrorKind` for this error. #[stable(feature = "rust1", since = "1.0.0")] pub fn kind(&self) -> ErrorKind { diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs index 501ba2dc2c178..f263d7d72d35d 100644 --- a/src/libstd/net/tcp.rs +++ b/src/libstd/net/tcp.rs @@ -273,8 +273,7 @@ mod tests { match TcpListener::bind("1.1.1.1:9999") { Ok(..) => panic!(), Err(e) => - // EADDRNOTAVAIL is mapped to ConnectionRefused - assert_eq!(e.kind(), ErrorKind::ConnectionRefused), + assert_eq!(e.kind(), ErrorKind::AddrNotAvailable), } } @@ -282,8 +281,11 @@ mod tests { fn connect_error() { match TcpStream::connect("0.0.0.0:1") { Ok(..) => panic!(), - Err(e) => assert!((e.kind() == ErrorKind::ConnectionRefused) - || (e.kind() == ErrorKind::InvalidInput)), + Err(e) => assert!(e.kind() == ErrorKind::ConnectionRefused || + e.kind() == ErrorKind::InvalidInput || + e.kind() == ErrorKind::AddrInUse || + e.kind() == ErrorKind::AddrNotAvailable, + "bad error: {} {:?}", e, e.kind()), } } @@ -535,7 +537,8 @@ mod tests { Ok(..) => panic!(), Err(e) => { assert!(e.kind() == ErrorKind::ConnectionRefused || - e.kind() == ErrorKind::Other, + e.kind() == ErrorKind::Other || + e.kind() == ErrorKind::AddrInUse, "unknown error: {} {:?}", e, e.kind()); } } diff --git a/src/libstd/process.rs b/src/libstd/process.rs index df8a5d27c7fa0..cda37b19c4868 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -668,7 +668,7 @@ mod tests { #[test] fn test_process_output_fail_to_start() { match Command::new("/no-binary-by-this-name-should-exist").output() { - Err(e) => assert_eq!(e.kind(), ErrorKind::FileNotFound), + Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound), Ok(..) => panic!() } } diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs index a8cee74828d34..5555eec4f3918 100644 --- a/src/libstd/sys/unix/mod.rs +++ b/src/libstd/sys/unix/mod.rs @@ -139,22 +139,19 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::EPIPE => ErrorKind::BrokenPipe, libc::ENOTCONN => ErrorKind::NotConnected, libc::ECONNABORTED => ErrorKind::ConnectionAborted, - libc::EADDRNOTAVAIL => ErrorKind::ConnectionRefused, - libc::EADDRINUSE => ErrorKind::ConnectionRefused, - libc::ENOENT => ErrorKind::FileNotFound, - libc::EISDIR => ErrorKind::InvalidInput, + libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, + libc::EADDRINUSE => ErrorKind::AddrInUse, + libc::ENOENT => ErrorKind::NotFound, libc::EINTR => ErrorKind::Interrupted, libc::EINVAL => ErrorKind::InvalidInput, - libc::ENOTTY => ErrorKind::MismatchedFileTypeForOperation, libc::ETIMEDOUT => ErrorKind::TimedOut, - libc::ECANCELED => ErrorKind::TimedOut, - libc::consts::os::posix88::EEXIST => ErrorKind::PathAlreadyExists, + libc::consts::os::posix88::EEXIST => ErrorKind::AlreadyExists, // These two constants can have the same value on some systems, // but different values on others, so we can't use a match // clause x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => - ErrorKind::ResourceUnavailable, + ErrorKind::WouldBlock, _ => ErrorKind::Other, } diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs index d02fe79fcdb1f..eeaf4ced07239 100644 --- a/src/libstd/sys/windows/mod.rs +++ b/src/libstd/sys/windows/mod.rs @@ -149,25 +149,21 @@ pub fn decode_error_detailed(errno: i32) -> IoError { pub fn decode_error_kind(errno: i32) -> ErrorKind { match errno as libc::c_int { libc::ERROR_ACCESS_DENIED => ErrorKind::PermissionDenied, - libc::ERROR_ALREADY_EXISTS => ErrorKind::PathAlreadyExists, + libc::ERROR_ALREADY_EXISTS => ErrorKind::AlreadyExists, libc::ERROR_BROKEN_PIPE => ErrorKind::BrokenPipe, - libc::ERROR_FILE_NOT_FOUND => ErrorKind::FileNotFound, - libc::ERROR_INVALID_FUNCTION => ErrorKind::InvalidInput, - libc::ERROR_INVALID_HANDLE => ErrorKind::MismatchedFileTypeForOperation, - libc::ERROR_INVALID_NAME => ErrorKind::InvalidInput, - libc::ERROR_NOTHING_TO_TERMINATE => ErrorKind::InvalidInput, + libc::ERROR_FILE_NOT_FOUND => ErrorKind::NotFound, libc::ERROR_NO_DATA => ErrorKind::BrokenPipe, libc::ERROR_OPERATION_ABORTED => ErrorKind::TimedOut, libc::WSAEACCES => ErrorKind::PermissionDenied, - libc::WSAEADDRINUSE => ErrorKind::ConnectionRefused, - libc::WSAEADDRNOTAVAIL => ErrorKind::ConnectionRefused, + libc::WSAEADDRINUSE => ErrorKind::AddrInUse, + libc::WSAEADDRNOTAVAIL => ErrorKind::AddrNotAvailable, libc::WSAECONNABORTED => ErrorKind::ConnectionAborted, libc::WSAECONNREFUSED => ErrorKind::ConnectionRefused, libc::WSAECONNRESET => ErrorKind::ConnectionReset, libc::WSAEINVAL => ErrorKind::InvalidInput, libc::WSAENOTCONN => ErrorKind::NotConnected, - libc::WSAEWOULDBLOCK => ErrorKind::ResourceUnavailable, + libc::WSAEWOULDBLOCK => ErrorKind::WouldBlock, _ => ErrorKind::Other, }