about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstd/sys/windows/process.rs18
-rw-r--r--src/test/run-make/windows-spawn/Makefile14
-rw-r--r--src/test/run-make/windows-spawn/hello.rs13
-rw-r--r--src/test/run-make/windows-spawn/spawn.rs22
4 files changed, 59 insertions, 8 deletions
diff --git a/src/libstd/sys/windows/process.rs b/src/libstd/sys/windows/process.rs
index dfbc1b581ee..0bd0ce73138 100644
--- a/src/libstd/sys/windows/process.rs
+++ b/src/libstd/sys/windows/process.rs
@@ -427,20 +427,22 @@ fn make_command_line(prog: &OsStr, args: &[OsString]) -> io::Result<Vec<u16>> {
     // Encode the command and arguments in a command line string such
     // that the spawned process may recover them using CommandLineToArgvW.
     let mut cmd: Vec<u16> = Vec::new();
-    append_arg(&mut cmd, prog)?;
+    // Always quote the program name so CreateProcess doesn't interpret args as
+    // part of the name if the binary wasn't found first time.
+    append_arg(&mut cmd, prog, true)?;
     for arg in args {
         cmd.push(' ' as u16);
-        append_arg(&mut cmd, arg)?;
+        append_arg(&mut cmd, arg, false)?;
     }
     return Ok(cmd);
 
-    fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr) -> io::Result<()> {
+    fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, force_quotes: bool) -> io::Result<()> {
         // If an argument has 0 characters then we need to quote it to ensure
         // that it actually gets passed through on the command line or otherwise
         // it will be dropped entirely when parsed on the other end.
         ensure_no_nuls(arg)?;
         let arg_bytes = &arg.as_inner().inner.as_inner();
-        let quote = arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t')
+        let quote = force_quotes || arg_bytes.iter().any(|c| *c == b' ' || *c == b'\t')
             || arg_bytes.is_empty();
         if quote {
             cmd.push('"' as u16);
@@ -526,7 +528,7 @@ mod tests {
 
         assert_eq!(
             test_wrapper("prog", &["aaa", "bbb", "ccc"]),
-            "prog aaa bbb ccc"
+            "\"prog\" aaa bbb ccc"
         );
 
         assert_eq!(
@@ -539,15 +541,15 @@ mod tests {
         );
         assert_eq!(
             test_wrapper("echo", &["a b c"]),
-            "echo \"a b c\""
+            "\"echo\" \"a b c\""
         );
         assert_eq!(
             test_wrapper("echo", &["\" \\\" \\", "\\"]),
-            "echo \"\\\" \\\\\\\" \\\\\" \\"
+            "\"echo\" \"\\\" \\\\\\\" \\\\\" \\"
         );
         assert_eq!(
             test_wrapper("\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}", &[]),
-            "\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}"
+            "\"\u{03c0}\u{042f}\u{97f3}\u{00e6}\u{221e}\""
         );
     }
 }
diff --git a/src/test/run-make/windows-spawn/Makefile b/src/test/run-make/windows-spawn/Makefile
new file mode 100644
index 00000000000..f0d4242260f
--- /dev/null
+++ b/src/test/run-make/windows-spawn/Makefile
@@ -0,0 +1,14 @@
+-include ../tools.mk
+
+ifdef IS_WINDOWS
+
+all:
+	$(RUSTC) -o "$(TMPDIR)/hopefullydoesntexist bar.exe" hello.rs
+	$(RUSTC) spawn.rs
+	$(TMPDIR)/spawn.exe
+
+else
+
+all:
+
+endif
diff --git a/src/test/run-make/windows-spawn/hello.rs b/src/test/run-make/windows-spawn/hello.rs
new file mode 100644
index 00000000000..b177f41941d
--- /dev/null
+++ b/src/test/run-make/windows-spawn/hello.rs
@@ -0,0 +1,13 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    println!("Hello World!");
+}
diff --git a/src/test/run-make/windows-spawn/spawn.rs b/src/test/run-make/windows-spawn/spawn.rs
new file mode 100644
index 00000000000..2913cbe2260
--- /dev/null
+++ b/src/test/run-make/windows-spawn/spawn.rs
@@ -0,0 +1,22 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::io::ErrorKind;
+use std::process::Command;
+
+fn main() {
+    // Make sure it doesn't try to run "hopefullydoesntexist bar.exe".
+    assert_eq!(Command::new("hopefullydoesntexist")
+                   .arg("bar")
+                   .spawn()
+                   .unwrap_err()
+                   .kind(),
+               ErrorKind::NotFound);
+}