Skip to content

Commit

Permalink
Use raw_arg for CMD on Windows
Browse files Browse the repository at this point in the history
CMD uses special handling for arguments to passed to /C. Unfortunately,
this causes errors with quoted program names in these arguments.

This commit implements a workaround: When CMD is requested, we build a
std::process::Command and pass the the argument to /C using the special
std::os::windows::process::CommandExt::raw_arg method. The StdCommand is
then converted to a TokioCommand and returned.

Once tokio-rs/tokio#5810 is fixed, this workaround can be removed.

Fixes watchexec#613
  • Loading branch information
korrat committed Jun 23, 2023
1 parent 2a3a3de commit aedea71
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
18 changes: 13 additions & 5 deletions crates/lib/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,21 @@ impl Command {
args,
command,
} => {
if command.is_empty() {
return Err(RuntimeError::CommandShellEmptyCommand);
}

let (shcmd, shcliopt) = match shell {
#[cfg(windows)]
Shell::Cmd => ("cmd.exe", "/C"),
Shell::Cmd => {
use std::os::windows::process::CommandExt as _;
use std::process::Command as StdCommand;

// TODO this is a workaround until TokioCommand has a raw_arg method. See tokio-rs/tokio#5810.
let mut std_command = StdCommand::new("cmd.exe");
std_command.args(args).arg("/C").raw_arg(command);
return Ok(TokioCommand::from(std_command));
}

#[cfg(windows)]
Shell::Powershell => ("powershell.exe", "-Command"),
Expand All @@ -117,10 +129,6 @@ impl Command {
}
};

if command.is_empty() {
return Err(RuntimeError::CommandShellEmptyCommand);
}

let mut c = TokioCommand::new(shcmd);
c.args(args);
c.arg(shcliopt).arg(command);
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/src/command/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ async fn windows_shell_cmd() -> Result<(), std::io::Error> {
assert!(Command::Shell {
shell: Shell::Cmd,
args: Vec::new(),
command: "echo hi".into()
command: r#""echo" hi"#.into()
}
.to_spawnable()
.unwrap()
Expand Down

0 comments on commit aedea71

Please sign in to comment.