So I was tinkering around with running two commands on two shells on one SSH connection and I saw something I have never seen Rust do before, segfault with no explanation. This in Debian in WSL in Windows:
$ ./target/release/experiment
SSH dual session experimet.
Connected.
Authenticated.
Chan 1: [76, 105, 110, 117, 120, 32, 83, 109, 97, 114, 116, 84, 114, 97, 102, 102, 105, 99, 32, 52, 46, 57, 46, 48, 45, 56, 45, 97, 109, 100, 54, 52, 32, 35, 49, 32, 83, 77, 80, 32, 68, 101, 98, 105, 97, 110, 32, 52, 46, 57]
Segmentation fault (core dumped)
$
Here is the code:
use std::io::prelude::*;
use std::net::{TcpStream};
use ssh2::Session;
use std::thread;
fn main () {
println!("SSH dual session experiment.");
let tcp = TcpStream::connect(address).unwrap();
println!("Connected.");
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password(user, password).unwrap();
println!("Authenticated.");
let commands = vec!["./gstat", "./dlstat"];
let mut threads = Vec::<std::thread::JoinHandle<_>>::new();
for command in commands {
let mut channel = sess.channel_session().unwrap();
channel.shell();
threads.push(thread::spawn(move || {
channel.write_fmt(format_args!("{}\n", command)).unwrap();
loop {
let mut buf = vec![0u8; 50];
channel.read(&mut buf).unwrap();
println!("Chan {} : {:?}", command, buf);
println!("{}", channel.exit_status().unwrap());
}
}));
}
}
Of course what is missing there is the joining the threads before exiting.
for thread in threads {
thread.join();
}