summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWez Furlong <wez@wezfurlong.org>2019-08-01 21:32:35 -0700
committerWez Furlong <wez@wezfurlong.org>2019-08-02 10:12:40 -0700
commit16cb2862ff01ba4a703cda59dfadbad443aa5738 (patch)
tree47bf5c40979d733196b192e6f819b184f9c38322
parentc49581f85ad9c3ad0e5b7595f5c7d6e72ea9a61b (diff)
downloadssh2-rs-16cb2862ff01ba4a703cda59dfadbad443aa5738.zip
handle_extended_data
Add a function to configure how extended data streams are to be handled. This allows for merging stderr to stdout, or discarding it.
-rw-r--r--libssh2-sys/lib.rs8
-rw-r--r--src/channel.rs10
-rw-r--r--src/lib.rs12
-rw-r--r--tests/all/channel.rs12
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.
///
diff --git a/src/lib.rs b/src/lib.rs
index db3591a..dd02a67 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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();