From 59ce6cc1cb9a6ee3dcde05af58979d2e189870db Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Wed, 24 Jul 2019 12:41:13 -0700 Subject: Map EAGAIN errors appropriately When the channel is set to non-blocking mode, take care to map the underlying ssh2 error code to the WouldBlock error kind so that embedding applications can correctly handle that situation. --- src/channel.rs | 8 ++++---- src/error.rs | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/channel.rs b/src/channel.rs index febf3d6..03bbba0 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -1,7 +1,7 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t}; use std::cmp; +use std::io; use std::io::prelude::*; -use std::io::{self, ErrorKind}; use std::rc::Rc; use std::slice; @@ -421,7 +421,7 @@ impl<'channel> Read for Stream<'channel> { } Ok(n) } - Err(e) => Err(io::Error::new(ErrorKind::Other, e)), + Err(e) => Err(e.into()), } } } @@ -437,7 +437,7 @@ impl<'channel> Write for Stream<'channel> { ); self.channel.sess.rc(rc as c_int).map(|()| rc as usize) } - .map_err(|e| io::Error::new(ErrorKind::Other, e)) + .map_err(Into::into) } fn flush(&mut self) -> io::Result<()> { @@ -445,6 +445,6 @@ impl<'channel> Write for Stream<'channel> { let rc = raw::libssh2_channel_flush_ex(self.channel.raw, self.id as c_int); self.channel.sess.rc(rc) } - .map_err(|e| io::Error::new(ErrorKind::Other, e)) + .map_err(Into::into) } } diff --git a/src/error.rs b/src/error.rs index d5dd397..916cc51 100644 --- a/src/error.rs +++ b/src/error.rs @@ -139,6 +139,16 @@ impl Error { } } +impl From for std::io::Error { + fn from(err: Error) -> std::io::Error { + let kind = match err.code { + raw::LIBSSH2_ERROR_EAGAIN => std::io::ErrorKind::WouldBlock, + _ => std::io::ErrorKind::Other, + }; + std::io::Error::new(kind, err.msg) + } +} + impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{}] {}", self.code, self.msg) -- cgit v1.2.3