summaryrefslogtreecommitdiff
path: root/src/channel.rs
diff options
context:
space:
mode:
authorWez Furlong <wez@wezfurlong.org>2019-07-23 17:46:37 -0700
committerWez Furlong <wez@wezfurlong.org>2019-07-29 08:55:06 -0700
commiteac5df1d22eea071708db2e57dc0637ceb3fc580 (patch)
treeefb3a436dc599db19c7e517788da8199caeaacf4 /src/channel.rs
parent1bbdfca88957747a9ad2d6010c84abe4189b2439 (diff)
downloadssh2-rs-eac5df1d22eea071708db2e57dc0637ceb3fc580.zip
Channel, Sftp no longer borrow Session
Instead the internal session is kept alive via Rc Refs: https://github.com/alexcrichton/ssh2-rs/issues/53
Diffstat (limited to 'src/channel.rs')
-rw-r--r--src/channel.rs62
1 files changed, 32 insertions, 30 deletions
diff --git a/src/channel.rs b/src/channel.rs
index 85c6576..febf3d6 100644
--- a/src/channel.rs
+++ b/src/channel.rs
@@ -2,10 +2,10 @@ use libc::{c_char, c_int, c_uchar, c_uint, c_ulong, c_void, size_t};
use std::cmp;
use std::io::prelude::*;
use std::io::{self, ErrorKind};
+use std::rc::Rc;
use std::slice;
-use util::SessionBinding;
-use {raw, Error, Session};
+use {raw, Error, SessionInner};
/// A channel represents a portion of an SSH connection on which data can be
/// read and written.
@@ -15,16 +15,33 @@ use {raw, Error, Session};
/// implements the `Reader` and `Writer` traits to send and receive data.
/// Whether or not I/O operations are blocking is mandated by the `blocking`
/// flag on a channel's corresponding `Session`.
-pub struct Channel<'sess> {
+pub struct Channel {
raw: *mut raw::LIBSSH2_CHANNEL,
- sess: &'sess Session,
+ sess: Rc<SessionInner>,
read_limit: Option<u64>,
}
+impl Channel {
+ pub(crate) fn from_raw_opt(
+ raw: *mut raw::LIBSSH2_CHANNEL,
+ sess: &Rc<SessionInner>,
+ ) -> Result<Self, Error> {
+ if raw.is_null() {
+ Err(Error::last_error_raw(sess.raw).unwrap_or_else(Error::unknown))
+ } else {
+ Ok(Self {
+ raw,
+ sess: Rc::clone(sess),
+ read_limit: None,
+ })
+ }
+ }
+}
+
/// A channel can have a number of streams, each identified by an id, each of
/// which implements the `Read` and `Write` traits.
-pub struct Stream<'channel, 'sess: 'channel> {
- channel: &'channel mut Channel<'sess>,
+pub struct Stream<'channel> {
+ channel: &'channel mut Channel,
id: i32,
}
@@ -61,7 +78,7 @@ pub struct WriteWindow {
pub window_size_initial: u32,
}
-impl<'sess> Channel<'sess> {
+impl Channel {
/// Set an environment variable in the remote channel's process space.
///
/// Note that this does not make sense for all channel types and may be
@@ -187,7 +204,7 @@ impl<'sess> Channel<'sess> {
/// Get a handle to the stderr stream of this channel.
///
/// The returned handle implements the `Read` and `Write` traits.
- pub fn stderr<'a>(&'a mut self) -> Stream<'a, 'sess> {
+ pub fn stderr<'a>(&'a mut self) -> Stream<'a> {
self.stream(::EXTENDED_DATA_STDERR)
}
@@ -200,7 +217,7 @@ impl<'sess> Channel<'sess> {
///
/// * FLUSH_EXTENDED_DATA - Flush all extended data substreams
/// * FLUSH_ALL - Flush all substreams
- pub fn stream<'a>(&'a mut self, stream_id: i32) -> Stream<'a, 'sess> {
+ pub fn stream<'a>(&'a mut self, stream_id: i32) -> Stream<'a> {
Stream {
channel: self,
id: stream_id,
@@ -252,7 +269,7 @@ impl<'sess> Channel<'sess> {
}
let slice = slice::from_raw_parts(ptr as *const u8, len as usize);
let ret = slice.to_vec();
- raw::libssh2_free(chan.sess.raw(), ptr as *mut c_void);
+ raw::libssh2_free(chan.sess.raw, ptr as *mut c_void);
String::from_utf8(ret).ok()
}
}
@@ -351,22 +368,7 @@ impl<'sess> Channel<'sess> {
}
}
-impl<'sess> SessionBinding<'sess> for Channel<'sess> {
- type Raw = raw::LIBSSH2_CHANNEL;
-
- unsafe fn from_raw(sess: &'sess Session, raw: *mut raw::LIBSSH2_CHANNEL) -> Channel<'sess> {
- Channel {
- raw: raw,
- sess: sess,
- read_limit: None,
- }
- }
- fn raw(&self) -> *mut raw::LIBSSH2_CHANNEL {
- self.raw
- }
-}
-
-impl<'sess> Write for Channel<'sess> {
+impl Write for Channel {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.stream(0).write(buf)
}
@@ -376,13 +378,13 @@ impl<'sess> Write for Channel<'sess> {
}
}
-impl<'sess> Read for Channel<'sess> {
+impl Read for Channel {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.stream(0).read(buf)
}
}
-impl<'sess> Drop for Channel<'sess> {
+impl Drop for Channel {
fn drop(&mut self) {
unsafe {
let _ = raw::libssh2_channel_free(self.raw);
@@ -390,7 +392,7 @@ impl<'sess> Drop for Channel<'sess> {
}
}
-impl<'channel, 'sess> Read for Stream<'channel, 'sess> {
+impl<'channel> Read for Stream<'channel> {
fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
if self.channel.eof() {
return Ok(0);
@@ -424,7 +426,7 @@ impl<'channel, 'sess> Read for Stream<'channel, 'sess> {
}
}
-impl<'channel, 'sess> Write for Stream<'channel, 'sess> {
+impl<'channel> Write for Stream<'channel> {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
unsafe {
let rc = raw::libssh2_channel_write_ex(