remote(wsl): Execute commands on wsl without spawning a shell (#39357)

Lukas Wirth created

Closes https://github.com/zed-industries/zed/issues/39091

Release Notes:

- Fixed wsl connection failing if user's shell prints to stdout on
startup

Change summary

crates/remote/src/transport/wsl.rs | 40 +++++++++++++++++--------------
1 file changed, 22 insertions(+), 18 deletions(-)

Detailed changes

crates/remote/src/transport/wsl.rs 🔗

@@ -473,6 +473,27 @@ async fn windows_path_to_wsl_path_impl(
     run_wsl_command_impl(options, "wslpath", &["-u", &source]).await
 }
 
+async fn run_wsl_command_impl(
+    options: &WslConnectionOptions,
+    program: &str,
+    args: &[&str],
+) -> Result<String> {
+    let output = wsl_command_impl(options, program, args).output().await?;
+
+    if !output.status.success() {
+        return Err(anyhow!(
+            "Command '{}' failed: {}",
+            program,
+            String::from_utf8_lossy(&output.stderr).trim()
+        ));
+    }
+
+    Ok(String::from_utf8_lossy(&output.stdout).trim().to_owned())
+}
+
+/// Creates a new `wsl.exe` command that runs the given program with the given arguments.
+///
+/// If `exec` is true, the command will be executed in the WSL environment without spawning a new shell.
 fn wsl_command_impl(
     options: &WslConnectionOptions,
     program: &str,
@@ -492,26 +513,9 @@ fn wsl_command_impl(
         .arg(&options.distro_name)
         .arg("--cd")
         .arg("~")
+        .arg("--exec")
         .arg(program)
         .args(args);
 
     command
 }
-
-async fn run_wsl_command_impl(
-    options: &WslConnectionOptions,
-    program: &str,
-    args: &[&str],
-) -> Result<String> {
-    let output = wsl_command_impl(options, program, args).output().await?;
-
-    if !output.status.success() {
-        return Err(anyhow!(
-            "Command '{}' failed: {}",
-            program,
-            String::from_utf8_lossy(&output.stderr).trim()
-        ));
-    }
-
-    Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
-}