TL;DR I catch SIG TERM with the signal_hook crate but my ongoing ssh connection fails on the signal and the program exits before my signal handler has a chance to shut down cleanly.
I have a program that is talking to some equipment using SSH from my Mac or a Linux box. Turns out the ssh on the equipment has a problem. If I repeated ssh into it from my program it will eventually fail. When it fails I can connect and log in but having done so it immediately closes the connection. At which point the only way to recover is to power cycle the equipment. This is a major problem as the equipment will be located at a remote inaccessible location.
Now, using ssh to that same equipment from the command line and then exiting cleanly does not have this problem.
So I thought it would help to send a SIG TERM to my program and have it shut down the session cleanly. Basically it should send ESC to stop the program running at the other end and then send "exit\n". At which point the connection closes.
Now I have the problem that although I can catch the SIG TERM with signal_hook and cause a clean shut down, that never happens. Rather communication fails with "Error waiting on socket" and the program immediately exits.
I catch the SIG TERM with this:
fn ctrl_channel() -> Receiver<()> {
const SIGNALS: &[c_int] = &[
SIGTERM, SIGQUIT, SIGINT, SIGTSTP, SIGWINCH, SIGHUP, SIGCHLD, SIGCONT,
];
let mut sigs = match Signals::new(SIGNALS) {
Ok(sigs) => sigs,
Err(e) => {
error!("creating Signals: {e}");
std::process::exit(0);
}
};
let (sender, receiver) = bounded(100);
std::thread::spawn(move || loop {
if let Some(signal) = sigs.into_iter().next() {
error!("Got signal {}", signal);
if let Err(e) = sender.send(()) {
error!("Signal handler thread failed {}", e);
std::process::exit(0);
}
}
});
receiver
}
Then in my programs main loop I check the other end of that channel with
if !ctrl_c_events.is_empty()
I'm reading from the ssh2 channel like so:
channel.read_exact(&mut buf)?
So why do I fail with a socket error rather than? Or why does a SIG TERM even cause a socket error?