Port --no-shell to Windows

This commit is contained in:
Chris Aumann 2017-04-06 23:04:57 +02:00
parent 5a7ccf759b
commit 780b54b34e
5 changed files with 22 additions and 7 deletions

View File

@ -35,7 +35,7 @@ Sends the specified signal (e\.g\. \fBSIGKILL\fR) to the child process\. Default
.
.TP
\fB\-n\fR, \fB\-\-no\-shell\fR
Execute command directly, do not use \fBsh -c\fR\. This is especially useful in combination with \fB--signal\fR, as the signal is then send directly to the specified command\. While \fB--no-shell\fR is a little more performant than the default, it prevents using shell-features like pipes and redirects\.
Execute command directly, do not wrap it in \fBsh -c\fR resp\. \fBcmd.exec /C\R\. This is especially useful in combination with \fB--signal\fR, as the signal is then send directly to the specified command\. While \fB--no-shell\fR is a little more performant than the default, it prevents using shell-features like pipes and redirects\.
.
.TP
\fB\-i\fR, \fB\-\-ignore\fR \fIpattern\fR

View File

@ -89,7 +89,7 @@
<dt><code>-e</code>, <code>--exts</code> <var>extensions</var></dt><dd><p>Comma-separated list of file extensions to filter by. Leading dots are allowed (.rs) are allowed. (This is a shorthand for <code>-f</code>).</p></dd>
<dt><code>-f</code>, <code>--filter</code> <var>pattern</var></dt><dd><p>Ignores modifications from paths that do not match <var>pattern</var>. This option can be specified multiple times, where a match on any given pattern causes the path to trigger <var>command</var>.</p></dd>
<dt><code>-s</code>, <code>--signal</code> <var>SIGNAL</var></dt><dd><p>Sends the specified signal (e.g. <code>SIGKILl</code>) to the child process. Defaults to <code>SIGTERM</code>.</p></dd>
<dt><code>-n</code>, <code>--no-shell</code></dt><dd><p>Execute command directly, do not use <CODE>sh -c</code>. This is especially useful in combination with <code>--signal</code>, as the signal is then send directly to the specified command. While <code>--no-shell</code> is a little more performant than the default, it prevents using shell-features like pipes and redirects.</p></dd>
<dt><code>-n</code>, <code>--no-shell</code></dt><dd><p>Execute command directly, do not wrap it in <CODE>sh -c</code> resp. <code>cmd.exec /C</code>. This is especially useful in combination with <code>--signal</code>, as the signal is then send directly to the specified command. While <code>--no-shell</code> is a little more performant than the default, it prevents using shell-features like pipes and redirects.</p></dd>
<dt><code>-i</code>, <code>--ignore</code> <var>pattern</var></dt><dd><p>Ignores modifications from paths that match <var>pattern</var>. This option can be specified multiple times, and a match on any pattern causes the path to be ignored.</p></dd>
<dt><code>-w</code>, <code>--watch</code> <var>path</var></dt><dd><p>Monitor a specific path for changes. By default, the current working directory is watched. This may be specified multiple times, where a change in any watched directory (and subdirectories) causes <var>command</var> to be executed.</p></dd>
<dt><code>-r</code>, <code>--restart</code></dt><dd><p>Terminates the child process group if it is still running when subsequent file modifications are detected. By default, sends <code>SIGTERM</code>; use <code>--kill</code> to send <code>SIGKILL</code>.</p></dd>

View File

@ -26,7 +26,7 @@ Ignores modifications from paths that do not match <pattern>. This option can be
Sends the specified signal (e.g. `SIGKILL`) to the child process. Defaults to `SIGTERM`.
* `-n`, `--no-shell`:
Execute command directly, do not use `sh -c`. This is especially useful in combination with `--signal`, as the signal is then send directly to the specified command. While `--no-shell` is a little more performant than the default, it prevents using shell-features like pipes and redirects.
Execute command directly, do not wrap it in `sh -c` resp. `cmd.exe /C`. This is especially useful in combination with `--signal`, as the signal is then send directly to the specified command. While `--no-shell` is a little more performant than the default, it prevents using shell-features like pipes and redirects.
* `-i`, `--ignore` <pattern>:
Ignores modifications from paths that match <pattern>. This option can be specified multiple times, and a match on any pattern causes the path to be ignored.

View File

@ -104,7 +104,7 @@ pub fn get_args() -> Args {
.long("force-poll")
.value_name("interval"))
.arg(Arg::with_name("no-shell")
.help("Do not wrap command in 'sh -c'")
.help("Do not wrap command in 'sh -c' resp. 'cmd.exe /C'")
.short("n")
.long("no-shell"))
.arg(Arg::with_name("once").short("1").hidden(true))

View File

@ -139,7 +139,7 @@ mod imp {
}
impl Process {
pub fn new(cmd: &str, updated_paths: Vec<PathBuf>) -> Result<Process> {
pub fn new(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Result<Process> {
use std::os::windows::io::IntoRawHandle;
fn last_err() -> io::Error {
@ -163,8 +163,23 @@ mod imp {
panic!("failed to set job info: {}", last_err());
}
let mut command = Command::new("cmd.exe");
command.arg("/C").arg(cmd);
let mut iter_args = cmd.split_whitespace();
let arg0 = match no_shell {
true => iter_args.next().unwrap(),
false => "cmd.exe",
};
// TODO: There might be a better way of doing this with &str.
// I've had to fall back to String, as I wasn't able to join(" ") a Vec<&str>
// into a &str
let args: Vec<String> = match no_shell {
true => iter_args.map(str::to_string).collect(),
false => vec!["/C".to_string(), iter_args.collect::<Vec<&str>>().join(" ")],
};
let mut command = Command::new(arg0);
command.args(args);
debug!("Assembled command {:?}", command);
if let Some(single_path) = super::get_single_updated_path(&updated_paths) {
command.env("WATCHEXEC_UPDATED_PATH", single_path);