Loading openssl-sys/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08; pub const CRYPTO_LOCK: c_int = 1; pub const ERR_TXT_MALLOCED: c_int = 0x01; pub const ERR_TXT_STRING: c_int = 0x02; pub const ERR_LIB_PEM: c_int = 9; pub const PEM_R_NO_START_LINE: c_int = 108; Loading Loading @@ -1542,6 +1545,7 @@ extern { pub fn ERR_peek_last_error() -> c_ulong; pub fn ERR_get_error() -> c_ulong; pub fn ERR_get_error_line_data(file: *mut *const c_char, line: *mut c_int, data: *mut *const c_char, flags: *mut c_int) -> c_ulong; pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char; pub fn ERR_func_error_string(err: c_ulong) -> *const c_char; pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char; Loading openssl/src/error.rs +79 −17 Original line number Diff line number Diff line use libc::c_ulong; use libc::{c_ulong, c_char, c_int}; use std::fmt; use std::error; use std::ffi::CStr; use std::io; use std::str; use std::ptr; use std::borrow::Cow; use ffi; Loading Loading @@ -62,28 +64,63 @@ impl From<ErrorStack> for fmt::Error { /// An error reported from OpenSSL. #[derive(Clone)] pub struct Error(c_ulong); pub struct Error { code: c_ulong, file: *const c_char, line: c_int, data: Option<Cow<'static, str>>, } unsafe impl Sync for Error {} unsafe impl Send for Error {} impl Error { /// Returns the first error on the OpenSSL error stack. pub fn get() -> Option<Error> { unsafe { ffi::init(); match unsafe { ffi::ERR_get_error() } { let mut file = ptr::null(); let mut line = 0; let mut data = ptr::null(); let mut flags = 0; match ffi::ERR_get_error_line_data(&mut file, &mut line, &mut data, &mut flags) { 0 => None, err => Some(Error(err)), code => { // The memory referenced by data is only valid until that slot is overwritten // in the error stack, so we'll need to copy it off if it's dynamic let data = if flags & ffi::ERR_TXT_STRING != 0 { let bytes = CStr::from_ptr(data as *const _).to_bytes(); let data = str::from_utf8(bytes).unwrap(); let data = if flags & ffi::ERR_TXT_MALLOCED != 0 { Cow::Owned(data.to_string()) } else { Cow::Borrowed(data) }; Some(data) } else { None }; Some(Error { code: code, file: file, line: line, data: data, }) } } } } /// Returns the raw OpenSSL error code for this error. pub fn code(&self) -> c_ulong { self.0 self.code } /// Returns the name of the library reporting the error, if available. pub fn library(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_lib_error_string(self.0); let cstr = ffi::ERR_lib_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -95,7 +132,7 @@ impl Error { /// Returns the name of the function reporting the error. pub fn function(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_func_error_string(self.0); let cstr = ffi::ERR_func_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -107,7 +144,7 @@ impl Error { /// Returns the reason for the error. pub fn reason(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_reason_error_string(self.0); let cstr = ffi::ERR_reason_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -115,6 +152,25 @@ impl Error { Some(str::from_utf8(bytes).unwrap()) } } /// Returns the name of the source file which encountered the error. pub fn file(&self) -> &'static str { unsafe { assert!(!self.file.is_null()); let bytes = CStr::from_ptr(self.file as *const _).to_bytes(); str::from_utf8(bytes).unwrap() } } /// Returns the line in the source file which encountered the error. pub fn line(&self) -> c_int { self.line } /// Returns additional data describing the error. pub fn data(&self) -> Option<&str> { self.data.as_ref().map(|s| &**s) } } impl fmt::Debug for Error { Loading @@ -130,30 +186,36 @@ impl fmt::Debug for Error { if let Some(reason) = self.reason() { builder.field("reason", &reason); } builder.field("file", &self.file()); builder.field("line", &self.line()); if let Some(data) = self.data() { builder.field("data", &data); } builder.finish() } } impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "error:{:08X}", self.0)); try!(write!(fmt, "error:{:08X}", self.code())); match self.library() { Some(l) => try!(write!(fmt, ":{}", l)), None => try!(write!(fmt, ":lib({})", ffi::ERR_GET_LIB(self.0))), None => try!(write!(fmt, ":lib({})", ffi::ERR_GET_LIB(self.code()))), } match self.function() { Some(f) => try!(write!(fmt, ":{}", f)), None => try!(write!(fmt, ":func({})", ffi::ERR_GET_FUNC(self.0))), None => try!(write!(fmt, ":func({})", ffi::ERR_GET_FUNC(self.code()))), } match self.reason() { Some(r) => write!(fmt, ":{}", r), None => write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.0)), Some(r) => try!(write!(fmt, ":{}", r)), None => try!(write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.code()))), } write!(fmt, ":{}:{}:{}", self.file(), self.line(), self.data().unwrap_or("")) } } impl error::Error for Error { fn description(&self) -> &str { "An OpenSSL error" "an OpenSSL error" } } Loading
openssl-sys/src/lib.rs +4 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,9 @@ pub const BIO_FLAGS_SHOULD_RETRY: c_int = 0x08; pub const CRYPTO_LOCK: c_int = 1; pub const ERR_TXT_MALLOCED: c_int = 0x01; pub const ERR_TXT_STRING: c_int = 0x02; pub const ERR_LIB_PEM: c_int = 9; pub const PEM_R_NO_START_LINE: c_int = 108; Loading Loading @@ -1542,6 +1545,7 @@ extern { pub fn ERR_peek_last_error() -> c_ulong; pub fn ERR_get_error() -> c_ulong; pub fn ERR_get_error_line_data(file: *mut *const c_char, line: *mut c_int, data: *mut *const c_char, flags: *mut c_int) -> c_ulong; pub fn ERR_lib_error_string(err: c_ulong) -> *const c_char; pub fn ERR_func_error_string(err: c_ulong) -> *const c_char; pub fn ERR_reason_error_string(err: c_ulong) -> *const c_char; Loading
openssl/src/error.rs +79 −17 Original line number Diff line number Diff line use libc::c_ulong; use libc::{c_ulong, c_char, c_int}; use std::fmt; use std::error; use std::ffi::CStr; use std::io; use std::str; use std::ptr; use std::borrow::Cow; use ffi; Loading Loading @@ -62,28 +64,63 @@ impl From<ErrorStack> for fmt::Error { /// An error reported from OpenSSL. #[derive(Clone)] pub struct Error(c_ulong); pub struct Error { code: c_ulong, file: *const c_char, line: c_int, data: Option<Cow<'static, str>>, } unsafe impl Sync for Error {} unsafe impl Send for Error {} impl Error { /// Returns the first error on the OpenSSL error stack. pub fn get() -> Option<Error> { unsafe { ffi::init(); match unsafe { ffi::ERR_get_error() } { let mut file = ptr::null(); let mut line = 0; let mut data = ptr::null(); let mut flags = 0; match ffi::ERR_get_error_line_data(&mut file, &mut line, &mut data, &mut flags) { 0 => None, err => Some(Error(err)), code => { // The memory referenced by data is only valid until that slot is overwritten // in the error stack, so we'll need to copy it off if it's dynamic let data = if flags & ffi::ERR_TXT_STRING != 0 { let bytes = CStr::from_ptr(data as *const _).to_bytes(); let data = str::from_utf8(bytes).unwrap(); let data = if flags & ffi::ERR_TXT_MALLOCED != 0 { Cow::Owned(data.to_string()) } else { Cow::Borrowed(data) }; Some(data) } else { None }; Some(Error { code: code, file: file, line: line, data: data, }) } } } } /// Returns the raw OpenSSL error code for this error. pub fn code(&self) -> c_ulong { self.0 self.code } /// Returns the name of the library reporting the error, if available. pub fn library(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_lib_error_string(self.0); let cstr = ffi::ERR_lib_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -95,7 +132,7 @@ impl Error { /// Returns the name of the function reporting the error. pub fn function(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_func_error_string(self.0); let cstr = ffi::ERR_func_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -107,7 +144,7 @@ impl Error { /// Returns the reason for the error. pub fn reason(&self) -> Option<&'static str> { unsafe { let cstr = ffi::ERR_reason_error_string(self.0); let cstr = ffi::ERR_reason_error_string(self.code); if cstr.is_null() { return None; } Loading @@ -115,6 +152,25 @@ impl Error { Some(str::from_utf8(bytes).unwrap()) } } /// Returns the name of the source file which encountered the error. pub fn file(&self) -> &'static str { unsafe { assert!(!self.file.is_null()); let bytes = CStr::from_ptr(self.file as *const _).to_bytes(); str::from_utf8(bytes).unwrap() } } /// Returns the line in the source file which encountered the error. pub fn line(&self) -> c_int { self.line } /// Returns additional data describing the error. pub fn data(&self) -> Option<&str> { self.data.as_ref().map(|s| &**s) } } impl fmt::Debug for Error { Loading @@ -130,30 +186,36 @@ impl fmt::Debug for Error { if let Some(reason) = self.reason() { builder.field("reason", &reason); } builder.field("file", &self.file()); builder.field("line", &self.line()); if let Some(data) = self.data() { builder.field("data", &data); } builder.finish() } } impl fmt::Display for Error { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { try!(write!(fmt, "error:{:08X}", self.0)); try!(write!(fmt, "error:{:08X}", self.code())); match self.library() { Some(l) => try!(write!(fmt, ":{}", l)), None => try!(write!(fmt, ":lib({})", ffi::ERR_GET_LIB(self.0))), None => try!(write!(fmt, ":lib({})", ffi::ERR_GET_LIB(self.code()))), } match self.function() { Some(f) => try!(write!(fmt, ":{}", f)), None => try!(write!(fmt, ":func({})", ffi::ERR_GET_FUNC(self.0))), None => try!(write!(fmt, ":func({})", ffi::ERR_GET_FUNC(self.code()))), } match self.reason() { Some(r) => write!(fmt, ":{}", r), None => write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.0)), Some(r) => try!(write!(fmt, ":{}", r)), None => try!(write!(fmt, ":reason({})", ffi::ERR_GET_FUNC(self.code()))), } write!(fmt, ":{}:{}:{}", self.file(), self.line(), self.data().unwrap_or("")) } } impl error::Error for Error { fn description(&self) -> &str { "An OpenSSL error" "an OpenSSL error" } }