ssh remoting: Kill SSH master process when dropping client (#18331)

Thorsten Ball and Bennet created

This was a process leak. Since we use `.spawn()`, the process continued
to run in the background, even if our `SshClientState` was dropped.

Means we need to manually clean it up.

Release Notes:

- N/A

Co-authored-by: Bennet <bennet@zed.dev>

Change summary

crates/remote/src/ssh_session.rs | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)

Detailed changes

crates/remote/src/ssh_session.rs 🔗

@@ -56,7 +56,7 @@ pub struct SshSession {
 
 struct SshClientState {
     socket: SshSocket,
-    _master_process: process::Child,
+    master_process: process::Child,
     _temp_dir: TempDir,
 }
 
@@ -593,7 +593,7 @@ impl SshClientState {
                 connection_options,
                 socket_path,
             },
-            _master_process: master_process,
+            master_process,
             _temp_dir: temp_dir,
         })
     }
@@ -716,6 +716,14 @@ impl SshClientState {
     }
 }
 
+impl Drop for SshClientState {
+    fn drop(&mut self) {
+        if let Err(error) = self.master_process.kill() {
+            log::error!("failed to kill SSH master process: {}", error);
+        }
+    }
+}
+
 impl SshSocket {
     fn ssh_command<S: AsRef<OsStr>>(&self, program: S) -> process::Command {
         let mut command = process::Command::new("ssh");