From b1a213f56a7f46ef8ad0259c77299e5a313460b7 Mon Sep 17 00:00:00 2001 From: Fenrir Date: Thu, 6 Oct 2016 16:48:12 -0700 Subject: [PATCH] Remove libc OS error functions We aren't actually using any of newlib's error functionality. All of our errors come from ctrulib functions. --- ctru-sys/src/sys/libc.rs | 20 ---- src/io/error.rs | 211 +++------------------------------------ src/sys/mod.rs | 1 - src/sys/os.rs | 78 --------------- 4 files changed, 13 insertions(+), 297 deletions(-) delete mode 100644 src/sys/os.rs diff --git a/ctru-sys/src/sys/libc.rs b/ctru-sys/src/sys/libc.rs index 3d647fe..743e064 100644 --- a/ctru-sys/src/sys/libc.rs +++ b/ctru-sys/src/sys/libc.rs @@ -1,24 +1,5 @@ pub const STDOUT_FILENO: c_int = 1; -pub const EPERM: c_int = 1; -pub const ENOENT: c_int = 2; -pub const EINTR: c_int = 4; -pub const EAGAIN: c_int = 11; -pub const EACCES: c_int = 13; -pub const EEXIST: c_int = 17; -pub const EINVAL: c_int = 22; -pub const EPIPE: c_int = 32; -pub const EWOULDBLOCK: c_int = EAGAIN; - -pub const EADDRINUSE: c_int = 98; -pub const EADDRNOTAVAIL: c_int = 99; -pub const ECONNABORTED: c_int = 103; -pub const ECONNRESET: c_int = 104; -pub const ENOTCONN: c_int = 107; -pub const ETIMEDOUT: c_int = 110; -pub const ECONNREFUSED: c_int = 111; -pub const EHOSTDOWN: c_int = 112; - #[repr(u8)] pub enum c_void { __variant1, @@ -41,7 +22,6 @@ pub type size_t = usize; pub type ssize_t = isize; extern "C" { - pub fn __errno() -> *const c_int; pub fn memchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; pub fn memrchr(cx: *const c_void, c: c_int, n: size_t) -> *mut c_void; pub fn strlen(cs: *const c_char) -> size_t; diff --git a/src/io/error.rs b/src/io/error.rs index 0fdb78e..edf4894 100644 --- a/src/io/error.rs +++ b/src/io/error.rs @@ -8,12 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use error; +use alloc::boxed::Box; +use core::convert::Into; use core::fmt; +use core::marker::{Send, Sync}; +use core::option::Option::{self, Some, None}; use core::result; -use sys; - -use collections::boxed::Box; +use error; /// A specialized [`Result`](../result/enum.Result.html) type for I/O /// operations. @@ -52,9 +53,7 @@ pub type Result = result::Result; /// /// Errors mostly originate from the underlying OS, but custom instances of /// `Error` can be created with crafted error messages and a particular value of -/// [`ErrorKind`]. -/// -/// [`ErrorKind`]: enum.ErrorKind.html +/// `ErrorKind`. #[derive(Debug)] pub struct Error { repr: Repr, @@ -75,11 +74,7 @@ struct Custom { /// /// This list is intended to grow over time and it is not recommended to /// exhaustively match against it. -/// -/// It is used with the [`io::Error`] type. -/// -/// [`io::Error`]: struct.Error.html -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[derive(Copy, PartialEq, Eq, Clone, Debug)] #[allow(deprecated)] pub enum ErrorKind { /// An entity was not found, often a file. @@ -142,8 +137,7 @@ pub enum ErrorKind { /// read. UnexpectedEof, - /// A marker variant that tells the compiler that users of this enum cannot - /// match it exhaustively. + /// Any I/O error not part of this list. #[doc(hidden)] __Nonexhaustive, } @@ -182,48 +176,7 @@ impl Error { } } - /// Returns an error representing the last OS error which occurred. - /// - /// This function reads the value of `errno` for the target platform (e.g. - /// `GetLastError` on Windows) and will return a corresponding instance of - /// `Error` for the error code. - /// - /// # Examples - /// - /// ``` - /// use std::io::Error; - /// - /// println!("last OS error: {:?}", Error::last_os_error()); - /// ``` - pub fn last_os_error() -> Error { - Error::from_raw_os_error(sys::os::errno() as i32) - } - /// Creates a new instance of an `Error` from a particular OS error code. - /// - /// # Examples - /// - /// On Linux: - /// - /// ``` - /// # if cfg!(target_os = "linux") { - /// use std::io; - /// - /// let error = io::Error::from_raw_os_error(98); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); - /// # } - /// ``` - /// - /// On Windows: - /// - /// ``` - /// # if cfg!(windows) { - /// use std::io; - /// - /// let error = io::Error::from_raw_os_error(10048); - /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse); - /// # } - /// ``` pub fn from_raw_os_error(code: i32) -> Error { Error { repr: Repr::Os(code) } } @@ -233,27 +186,6 @@ impl Error { /// If this `Error` was constructed via `last_os_error` or /// `from_raw_os_error`, then this function will return `Some`, otherwise /// it will return `None`. - /// - /// # Examples - /// - /// ``` - /// use std::io::{Error, ErrorKind}; - /// - /// fn print_os_error(err: &Error) { - /// if let Some(raw_os_err) = err.raw_os_error() { - /// println!("raw OS error: {:?}", raw_os_err); - /// } else { - /// println!("Not an OS error"); - /// } - /// } - /// - /// fn main() { - /// // Will print "raw OS error: ...". - /// print_os_error(&Error::last_os_error()); - /// // Will print "Not an OS error". - /// print_os_error(&Error::new(ErrorKind::Other, "oh no!")); - /// } - /// ``` pub fn raw_os_error(&self) -> Option { match self.repr { Repr::Os(i) => Some(i), @@ -265,27 +197,6 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. - /// - /// # Examples - /// - /// ``` - /// use std::io::{Error, ErrorKind}; - /// - /// fn print_error(err: &Error) { - /// if let Some(inner_err) = err.get_ref() { - /// println!("Inner error: {:?}", inner_err); - /// } else { - /// println!("No inner error"); - /// } - /// } - /// - /// fn main() { - /// // Will print "No inner error". - /// print_error(&Error::last_os_error()); - /// // Will print "Inner error: ...". - /// print_error(&Error::new(ErrorKind::Other, "oh no!")); - /// } - /// ``` pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, @@ -298,63 +209,6 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. - /// - /// # Examples - /// - /// ``` - /// use std::io::{Error, ErrorKind}; - /// use std::{error, fmt}; - /// use std::fmt::Display; - /// - /// #[derive(Debug)] - /// struct MyError { - /// v: String, - /// } - /// - /// impl MyError { - /// fn new() -> MyError { - /// MyError { - /// v: "oh no!".to_owned() - /// } - /// } - /// - /// fn change_message(&mut self, new_message: &str) { - /// self.v = new_message.to_owned(); - /// } - /// } - /// - /// impl error::Error for MyError { - /// fn description(&self) -> &str { &self.v } - /// } - /// - /// impl Display for MyError { - /// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - /// write!(f, "MyError: {}", &self.v) - /// } - /// } - /// - /// fn change_error(mut err: Error) -> Error { - /// if let Some(inner_err) = err.get_mut() { - /// inner_err.downcast_mut::().unwrap().change_message("I've been changed!"); - /// } - /// err - /// } - /// - /// fn print_error(err: &Error) { - /// if let Some(inner_err) = err.get_ref() { - /// println!("Inner error: {}", inner_err); - /// } else { - /// println!("No inner error"); - /// } - /// } - /// - /// fn main() { - /// // Will print "No inner error". - /// print_error(&change_error(Error::last_os_error())); - /// // Will print "Inner error: ...". - /// print_error(&change_error(Error::new(ErrorKind::Other, MyError::new()))); - /// } - /// ``` pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> { match self.repr { Repr::Os(..) => None, @@ -366,27 +220,6 @@ impl Error { /// /// If this `Error` was constructed via `new` then this function will /// return `Some`, otherwise it will return `None`. - /// - /// # Examples - /// - /// ``` - /// use std::io::{Error, ErrorKind}; - /// - /// fn print_error(err: Error) { - /// if let Some(inner_err) = err.into_inner() { - /// println!("Inner error: {}", inner_err); - /// } else { - /// println!("No inner error"); - /// } - /// } - /// - /// fn main() { - /// // Will print "No inner error". - /// print_error(Error::last_os_error()); - /// // Will print "Inner error: ...". - /// print_error(Error::new(ErrorKind::Other, "oh no!")); - /// } - /// ``` pub fn into_inner(self) -> Option> { match self.repr { Repr::Os(..) => None, @@ -395,26 +228,9 @@ impl Error { } /// Returns the corresponding `ErrorKind` for this error. - /// - /// # Examples - /// - /// ``` - /// use std::io::{Error, ErrorKind}; - /// - /// fn print_error(err: Error) { - /// println!("{:?}", err.kind()); - /// } - /// - /// fn main() { - /// // Will print "No inner error". - /// print_error(Error::last_os_error()); - /// // Will print "Inner error: ...". - /// print_error(Error::new(ErrorKind::AddrInUse, "oh no!")); - /// } - /// ``` pub fn kind(&self) -> ErrorKind { match self.repr { - Repr::Os(code) => sys::os::decode_error_kind(code), + Repr::Os(_code) => ErrorKind::Other, Repr::Custom(ref c) => c.kind, } } @@ -424,8 +240,7 @@ 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(), + fmt.debug_struct("Os").field("code", code).finish(), Repr::Custom(ref c) => fmt.debug_tuple("Custom").field(c).finish(), } } @@ -435,8 +250,7 @@ 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) + write!(fmt, "os error {}", code) } Repr::Custom(ref c) => c.error.fmt(fmt), } @@ -486,9 +300,10 @@ fn _assert_error_is_sync_send() { #[cfg(test)] mod test { + use prelude::v1::*; use super::{Error, ErrorKind}; use error; - use core::fmt; + use fmt; use sys::os::error_string; #[test] diff --git a/src/sys/mod.rs b/src/sys/mod.rs index b1b8ce6..86f49e5 100644 --- a/src/sys/mod.rs +++ b/src/sys/mod.rs @@ -22,5 +22,4 @@ pub trait FromInner { fn from_inner(inner: Inner) -> Self; } -pub mod os; pub mod wtf8; diff --git a/src/sys/os.rs b/src/sys/os.rs deleted file mode 100644 index 38038aa..0000000 --- a/src/sys/os.rs +++ /dev/null @@ -1,78 +0,0 @@ -use libctru::libc; -use io::ErrorKind; -use collections::{str, String}; -use collections::borrow::ToOwned; -use ffi::CStr; - -const TMPBUF_SZ: usize = 128; - -pub fn decode_error_kind(errno: i32) -> ErrorKind { - match errno as libc::c_int { - libc::ECONNREFUSED => ErrorKind::ConnectionRefused, - libc::ECONNRESET => ErrorKind::ConnectionReset, - libc::EPERM | libc::EACCES => ErrorKind::PermissionDenied, - libc::EPIPE => ErrorKind::BrokenPipe, - libc::ENOTCONN => ErrorKind::NotConnected, - libc::ECONNABORTED => ErrorKind::ConnectionAborted, - libc::EADDRNOTAVAIL => ErrorKind::AddrNotAvailable, - libc::EADDRINUSE => ErrorKind::AddrInUse, - libc::ENOENT => ErrorKind::NotFound, - libc::EINTR => ErrorKind::Interrupted, - libc::EINVAL => ErrorKind::InvalidInput, - libc::ETIMEDOUT => ErrorKind::TimedOut, - libc::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::WouldBlock, - - _ => ErrorKind::Other, - } -} - -extern "C" { - #[cfg(not(target_os = "dragonfly"))] - #[cfg_attr(any(target_os = "linux", target_os = "emscripten"), - link_name = "__errno_location")] - #[cfg_attr(any(target_os = "bitrig", - target_os = "netbsd", - target_os = "openbsd", - target_os = "android", - target_env = "newlib"), - link_name = "__errno")] - #[cfg_attr(target_os = "solaris", link_name = "___errno")] - #[cfg_attr(any(target_os = "macos", - target_os = "ios", - target_os = "freebsd"), - link_name = "__error")] - fn errno_location() -> *mut libc::c_int; -} - -pub fn errno() -> i32 { - unsafe { (*errno_location()) as i32 } -} - -/// Gets a detailed string description for the given error number. -pub fn error_string(errno: i32) -> String { - extern "C" { - #[cfg_attr(any(target_os = "linux", target_env = "newlib"), - link_name = "__xpg_strerror_r")] - fn strerror_r(errnum: libc::c_int, - buf: *mut libc::c_char, - buflen: libc::size_t) - -> libc::c_int; - } - - let mut buf = [0 as libc::c_char; TMPBUF_SZ]; - - let p = buf.as_mut_ptr(); - unsafe { - if strerror_r(errno as libc::c_int, p, buf.len() as libc::size_t) < 0 { - panic!("strerror_r failure"); - } - - let p = p as *const _; - str::from_utf8(CStr::from_ptr(p).to_bytes()).unwrap().to_owned() - } -}