summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/error.rs25
-rw-r--r--src/session.rs31
2 files changed, 31 insertions, 25 deletions
diff --git a/src/error.rs b/src/error.rs
index ade9001..c5b7543 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -3,6 +3,7 @@ use std::error;
use std::ffi::NulError;
use std::fmt;
use std::io;
+use std::ptr::null_mut;
use std::str;
use {raw, Session};
@@ -30,6 +31,30 @@ impl Error {
}
}
+ /// Given a libssh2 error return code, generate an Error object that
+ /// encapsulates that error code and the error reason.
+ /// The error reason is extracted from the Session and is used if the
+ /// session contains the same error code as that provided.
+ /// If the error code doesn't match then an approximation of the error
+ /// reason is used instead of the error message stored in the Session.
+ pub fn from_session_error(sess: &Session, rc: libc::c_int) -> Error {
+ Self::from_session_error_raw(sess.raw(), rc)
+ }
+
+ #[doc(hidden)]
+ pub fn from_session_error_raw(raw: *mut raw::LIBSSH2_SESSION, rc: libc::c_int) -> Error {
+ static STATIC: () = ();
+ unsafe {
+ let mut msg = null_mut();
+ let res = raw::libssh2_session_last_error(raw, &mut msg, null_mut(), 0);
+ if res != rc {
+ return Self::from_errno(rc);
+ }
+ let s = ::opt_bytes(&STATIC, msg).unwrap();
+ Error::new(rc, str::from_utf8(s).unwrap())
+ }
+ }
+
/// Generate the last error that occurred for a `Session`.
///
/// Returns `None` if there was no last error.
diff --git a/src/session.rs b/src/session.rs
index a8e5dc3..d0049c5 100644
--- a/src/session.rs
+++ b/src/session.rs
@@ -230,16 +230,7 @@ impl Session {
)
})?;
- let res = handshake(self.inner.raw, stream);
- self.rc(res)?;
- if res < 0 {
- // There are some kex related errors that don't set the
- // last error on the session object and that will not cause
- // the `rc` function to emit an error.
- // Let's ensure that we indicate an error in this situation.
- return Err(Error::new(res, "Error during handshake"));
- }
- Ok(())
+ self.rc(handshake(self.inner.raw, stream))
}
}
@@ -601,10 +592,10 @@ impl Session {
let mut ptr = 0 as *mut _;
let rc = raw::libssh2_session_supported_algs(self.inner.raw, method_type, &mut ptr);
if rc <= 0 {
- try!(self.rc(rc))
+ self.rc(rc)?;
}
for i in 0..(rc as isize) {
- let s = ::opt_bytes(&STATIC, *ptr.offset(i)).unwrap();;
+ let s = ::opt_bytes(&STATIC, *ptr.offset(i)).unwrap();
let s = str::from_utf8(s).unwrap();
ret.push(s);
}
@@ -881,7 +872,7 @@ impl Session {
pub fn keepalive_send(&self) -> Result<u32, Error> {
let mut ret = 0;
let rc = unsafe { raw::libssh2_keepalive_send(self.inner.raw, &mut ret) };
- try!(self.rc(rc));
+ self.rc(rc)?;
Ok(ret as u32)
}
@@ -912,14 +903,7 @@ impl Session {
/// Translate a return code into a Rust-`Result`.
pub fn rc(&self, rc: c_int) -> Result<(), Error> {
- if rc >= 0 {
- Ok(())
- } else {
- match Error::last_error(self) {
- Some(e) => Err(e),
- None => Ok(()),
- }
- }
+ self.inner.rc(rc)
}
}
@@ -929,10 +913,7 @@ impl SessionInner {
if rc >= 0 {
Ok(())
} else {
- match Error::last_error_raw(self.raw) {
- Some(e) => Err(e),
- None => Ok(()),
- }
+ Err(Error::from_session_error_raw(self.raw, rc))
}
}
}