diff options
-rw-r--r-- | libssh2-sys/lib.rs | 8 | ||||
-rw-r--r-- | src/channel.rs | 10 | ||||
-rw-r--r-- | src/lib.rs | 12 | ||||
-rw-r--r-- | tests/all/channel.rs | 12 |
4 files changed, 41 insertions, 1 deletions
diff --git a/libssh2-sys/lib.rs b/libssh2-sys/lib.rs index 8157dab..2428f15 100644 --- a/libssh2-sys/lib.rs +++ b/libssh2-sys/lib.rs @@ -181,6 +181,10 @@ pub const LIBSSH2_SFTP_S_IFDIR: c_ulong = 0o040000; pub const LIBSSH2_SFTP_S_IFREG: c_ulong = 0o100000; pub const LIBSSH2_SFTP_S_IFLNK: c_ulong = 0o120000; +pub const LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL: c_int = 0; +pub const LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE: c_int = 1; +pub const LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE: c_int = 2; + pub enum LIBSSH2_SESSION {} pub enum LIBSSH2_AGENT {} pub enum LIBSSH2_CHANNEL {} @@ -478,6 +482,10 @@ extern "C" { bound_port: *mut c_int, queue_maxsize: c_int, ) -> *mut LIBSSH2_LISTENER; + pub fn libssh2_channel_handle_extended_data2( + channel: *mut LIBSSH2_CHANNEL, + mode: c_int, + ) -> c_int; // userauth pub fn libssh2_userauth_authenticated(sess: *mut LIBSSH2_SESSION) -> c_int; diff --git a/src/channel.rs b/src/channel.rs index 7086f5d..69b535a 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -5,7 +5,7 @@ use std::io::prelude::*; use std::rc::Rc; use std::slice; -use {raw, Error, SessionInner}; +use {raw, Error, ExtendedData, SessionInner}; /// A channel represents a portion of an SSH connection on which data can be /// read and written. @@ -224,6 +224,14 @@ impl Channel { } } + /// Change how extended data (such as stderr) is handled + pub fn handle_extended_data(&mut self, mode: ExtendedData) -> Result<(), Error> { + unsafe { + let rc = raw::libssh2_channel_handle_extended_data2(self.raw, mode as c_int); + self.sess.rc(rc) + } + } + /// Returns the exit code raised by the process running on the remote host /// at the other end of the named channel. /// @@ -289,3 +289,15 @@ impl From<HostKeyType> for KnownHostKeyFormat { } } } + +/// How to handle extended data streams, such as stderr +#[derive(Copy, Clone, Debug)] +pub enum ExtendedData { + /// Queue extended data for eventual reading + Normal = raw::LIBSSH2_CHANNEL_EXTENDED_DATA_NORMAL as isize, + /// Treat extended data and ordinary data the same. Merge all substreams such that calls to + /// read will pull from all substreams on a first-in/first-out basis. + Merge = raw::LIBSSH2_CHANNEL_EXTENDED_DATA_MERGE as isize, + /// Discard all extended data as it arrives. + Ignore = raw::LIBSSH2_CHANNEL_EXTENDED_DATA_IGNORE as isize, +} diff --git a/tests/all/channel.rs b/tests/all/channel.rs index 9abde76..9d4ec82 100644 --- a/tests/all/channel.rs +++ b/tests/all/channel.rs @@ -65,6 +65,18 @@ fn reading_data() { } #[test] +fn handle_extended_data() { + let sess = ::authed_session(); + let mut channel = sess.channel_session().unwrap(); + channel + .handle_extended_data(ssh2::ExtendedData::Merge) + .unwrap(); + channel.exec("echo foo >&2").unwrap(); + let (output, _) = consume_stdio(&mut channel); + assert_eq!(output, "foo\n"); +} + +#[test] fn writing_data() { let sess = ::authed_session(); let mut channel = sess.channel_session().unwrap(); |