aboutsummaryrefslogtreecommitdiff
path: root/openssl/src/error.rs
diff options
context:
space:
mode:
authorSteven Fackler <[email protected]>2016-08-11 21:01:27 -0700
committerSteven Fackler <[email protected]>2016-08-11 21:01:27 -0700
commit652326003cefe215dbfc838051e6114515cc5190 (patch)
tree22dc99a726321cd8228004c34c40ca4a0648c594 /openssl/src/error.rs
parentMerge branch 'release-v0.7.14' into release (diff)
parentRelease openssl-sys v0.7.15, openssl v0.8.0 (diff)
downloadrust-openssl-openssl-v0.8.0.tar.xz
rust-openssl-openssl-v0.8.0.zip
Merge branch 'release-v0.7.15-sys-v0.8.0' into releaseopenssl-v0.8.0openssl-sys-v0.7.15
Diffstat (limited to 'openssl/src/error.rs')
-rw-r--r--openssl/src/error.rs137
1 files changed, 137 insertions, 0 deletions
diff --git a/openssl/src/error.rs b/openssl/src/error.rs
new file mode 100644
index 00000000..5fa542c2
--- /dev/null
+++ b/openssl/src/error.rs
@@ -0,0 +1,137 @@
+use libc::c_ulong;
+use std::fmt;
+use std::error;
+use std::ffi::CStr;
+use std::io;
+use std::str;
+
+use ffi;
+
+#[derive(Debug)]
+pub struct ErrorStack(Vec<Error>);
+
+impl ErrorStack {
+ /// Returns the contents of the OpenSSL error stack.
+ pub fn get() -> ErrorStack {
+ let mut vec = vec![];
+ while let Some(err) = Error::get() {
+ vec.push(err);
+ }
+ ErrorStack(vec)
+ }
+}
+
+impl ErrorStack {
+ /// Returns the errors in the stack.
+ pub fn errors(&self) -> &[Error] {
+ &self.0
+ }
+}
+
+impl fmt::Display for ErrorStack {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ let mut first = true;
+ for err in &self.0 {
+ if first {
+ try!(fmt.write_str(", "));
+ first = false;
+ }
+ try!(write!(fmt, "{}", err));
+ }
+ Ok(())
+ }
+}
+
+impl error::Error for ErrorStack {
+ fn description(&self) -> &str {
+ "An OpenSSL error stack"
+ }
+}
+
+impl From<ErrorStack> for io::Error {
+ fn from(e: ErrorStack) -> io::Error {
+ io::Error::new(io::ErrorKind::Other, e)
+ }
+}
+
+/// An error reported from OpenSSL.
+pub struct Error(c_ulong);
+
+impl Error {
+ /// Returns the first error on the OpenSSL error stack.
+ pub fn get() -> Option<Error> {
+ ffi::init();
+
+ match unsafe { ffi::ERR_get_error() } {
+ 0 => None,
+ err => Some((Error(err))),
+ }
+ }
+
+ /// Returns the raw OpenSSL error code for this error.
+ pub fn error_code(&self) -> c_ulong {
+ self.0
+ }
+
+ /// Returns the name of the library reporting the error.
+ pub fn library(&self) -> &'static str {
+ get_lib(self.0)
+ }
+
+ /// Returns the name of the function reporting the error.
+ pub fn function(&self) -> &'static str {
+ get_func(self.0)
+ }
+
+ /// Returns the reason for the error.
+ pub fn reason(&self) -> &'static str {
+ get_reason(self.0)
+ }
+}
+
+impl fmt::Debug for Error {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.debug_struct("Error")
+ .field("library", &self.library())
+ .field("function", &self.function())
+ .field("reason", &self.reason())
+ .finish()
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.write_str(&self.reason())
+ }
+}
+
+impl error::Error for Error {
+ fn description(&self) -> &str {
+ "An OpenSSL error"
+ }
+}
+
+fn get_lib(err: c_ulong) -> &'static str {
+ unsafe {
+ let cstr = ffi::ERR_lib_error_string(err);
+ let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
+ str::from_utf8(bytes).unwrap()
+ }
+}
+
+fn get_func(err: c_ulong) -> &'static str {
+ unsafe {
+ let cstr = ffi::ERR_func_error_string(err);
+ let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
+ str::from_utf8(bytes).unwrap()
+ }
+}
+
+fn get_reason(err: c_ulong) -> &'static str {
+ unsafe {
+ let cstr = ffi::ERR_reason_error_string(err);
+ let bytes = CStr::from_ptr(cstr as *const _).to_bytes();
+ str::from_utf8(bytes).unwrap()
+ }
+}
+