]> git.lizzy.rs Git - rust.git/blob - src/libstd/process.rs
Alias std::cmp::max/min to Ord::max/min
[rust.git] / src / libstd / process.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! A module for working with processes.
12 //!
13 //! # Examples
14 //!
15 //! Basic usage where we try to execute the `cat` shell command:
16 //!
17 //! ```should_panic
18 //! use std::process::Command;
19 //!
20 //! let mut child = Command::new("/bin/cat")
21 //!                         .arg("file.txt")
22 //!                         .spawn()
23 //!                         .expect("failed to execute child");
24 //!
25 //! let ecode = child.wait()
26 //!                  .expect("failed to wait on child");
27 //!
28 //! assert!(ecode.success());
29 //! ```
30 //!
31 //! Calling a command with input and reading its output:
32 //!
33 //! ```no_run
34 //! use std::process::{Command, Stdio};
35 //! use std::io::Write;
36 //!
37 //! let mut child = Command::new("/bin/cat")
38 //!     .stdin(Stdio::piped())
39 //!     .stdout(Stdio::piped())
40 //!     .spawn()
41 //!     .expect("failed to execute child");
42 //!
43 //! {
44 //!     // limited borrow of stdin
45 //!     let stdin = child.stdin.as_mut().expect("failed to get stdin");
46 //!     stdin.write_all(b"test").expect("failed to write to stdin");
47 //! }
48 //!
49 //! let output = child
50 //!     .wait_with_output()
51 //!     .expect("failed to wait on child");
52 //!
53 //! assert_eq!(b"test", output.stdout.as_slice());
54 //! ```
55
56 #![stable(feature = "process", since = "1.0.0")]
57
58 use io::prelude::*;
59
60 use ffi::OsStr;
61 use fmt;
62 use io;
63 use path::Path;
64 use str;
65 use sys::pipe::{read2, AnonPipe};
66 use sys::process as imp;
67 use sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
68
69 /// Representation of a running or exited child process.
70 ///
71 /// This structure is used to represent and manage child processes. A child
72 /// process is created via the [`Command`] struct, which configures the
73 /// spawning process and can itself be constructed using a builder-style
74 /// interface.
75 ///
76 /// There is no implementation of [`Drop`] for child processes,
77 /// so if you do not ensure the `Child` has exited then it will continue to
78 /// run, even after the `Child` handle to the child process has gone out of
79 /// scope.
80 ///
81 /// Calling [`wait`](#method.wait) (or other functions that wrap around it) will make
82 /// the parent process wait until the child has actually exited before
83 /// continuing.
84 ///
85 /// # Examples
86 ///
87 /// ```should_panic
88 /// use std::process::Command;
89 ///
90 /// let mut child = Command::new("/bin/cat")
91 ///                         .arg("file.txt")
92 ///                         .spawn()
93 ///                         .expect("failed to execute child");
94 ///
95 /// let ecode = child.wait()
96 ///                  .expect("failed to wait on child");
97 ///
98 /// assert!(ecode.success());
99 /// ```
100 ///
101 /// [`Command`]: struct.Command.html
102 /// [`Drop`]: ../../core/ops/trait.Drop.html
103 /// [`wait`]: #method.wait
104 #[stable(feature = "process", since = "1.0.0")]
105 pub struct Child {
106     handle: imp::Process,
107
108     /// The handle for writing to the child's stdin, if it has been captured
109     #[stable(feature = "process", since = "1.0.0")]
110     pub stdin: Option<ChildStdin>,
111
112     /// The handle for reading from the child's stdout, if it has been captured
113     #[stable(feature = "process", since = "1.0.0")]
114     pub stdout: Option<ChildStdout>,
115
116     /// The handle for reading from the child's stderr, if it has been captured
117     #[stable(feature = "process", since = "1.0.0")]
118     pub stderr: Option<ChildStderr>,
119 }
120
121 impl AsInner<imp::Process> for Child {
122     fn as_inner(&self) -> &imp::Process { &self.handle }
123 }
124
125 impl FromInner<(imp::Process, imp::StdioPipes)> for Child {
126     fn from_inner((handle, io): (imp::Process, imp::StdioPipes)) -> Child {
127         Child {
128             handle: handle,
129             stdin: io.stdin.map(ChildStdin::from_inner),
130             stdout: io.stdout.map(ChildStdout::from_inner),
131             stderr: io.stderr.map(ChildStderr::from_inner),
132         }
133     }
134 }
135
136 impl IntoInner<imp::Process> for Child {
137     fn into_inner(self) -> imp::Process { self.handle }
138 }
139
140 #[stable(feature = "std_debug", since = "1.16.0")]
141 impl fmt::Debug for Child {
142     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
143         f.debug_struct("Child")
144             .field("stdin", &self.stdin)
145             .field("stdout", &self.stdout)
146             .field("stderr", &self.stderr)
147             .finish()
148     }
149 }
150
151 /// A handle to a child process's stdin.
152 ///
153 /// This struct is used in the [`stdin`] field on [`Child`].
154 ///
155 /// [`Child`]: struct.Child.html
156 /// [`stdin`]: struct.Child.html#structfield.stdin
157 #[stable(feature = "process", since = "1.0.0")]
158 pub struct ChildStdin {
159     inner: AnonPipe
160 }
161
162 #[stable(feature = "process", since = "1.0.0")]
163 impl Write for ChildStdin {
164     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
165         self.inner.write(buf)
166     }
167
168     fn flush(&mut self) -> io::Result<()> {
169         Ok(())
170     }
171 }
172
173 impl AsInner<AnonPipe> for ChildStdin {
174     fn as_inner(&self) -> &AnonPipe { &self.inner }
175 }
176
177 impl IntoInner<AnonPipe> for ChildStdin {
178     fn into_inner(self) -> AnonPipe { self.inner }
179 }
180
181 impl FromInner<AnonPipe> for ChildStdin {
182     fn from_inner(pipe: AnonPipe) -> ChildStdin {
183         ChildStdin { inner: pipe }
184     }
185 }
186
187 #[stable(feature = "std_debug", since = "1.16.0")]
188 impl fmt::Debug for ChildStdin {
189     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
190         f.pad("ChildStdin { .. }")
191     }
192 }
193
194 /// A handle to a child process's stdout.
195 ///
196 /// This struct is used in the [`stdout`] field on [`Child`].
197 ///
198 /// [`Child`]: struct.Child.html
199 /// [`stdout`]: struct.Child.html#structfield.stdout
200 #[stable(feature = "process", since = "1.0.0")]
201 pub struct ChildStdout {
202     inner: AnonPipe
203 }
204
205 #[stable(feature = "process", since = "1.0.0")]
206 impl Read for ChildStdout {
207     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
208         self.inner.read(buf)
209     }
210     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
211         self.inner.read_to_end(buf)
212     }
213 }
214
215 impl AsInner<AnonPipe> for ChildStdout {
216     fn as_inner(&self) -> &AnonPipe { &self.inner }
217 }
218
219 impl IntoInner<AnonPipe> for ChildStdout {
220     fn into_inner(self) -> AnonPipe { self.inner }
221 }
222
223 impl FromInner<AnonPipe> for ChildStdout {
224     fn from_inner(pipe: AnonPipe) -> ChildStdout {
225         ChildStdout { inner: pipe }
226     }
227 }
228
229 #[stable(feature = "std_debug", since = "1.16.0")]
230 impl fmt::Debug for ChildStdout {
231     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
232         f.pad("ChildStdout { .. }")
233     }
234 }
235
236 /// A handle to a child process's stderr.
237 ///
238 /// This struct is used in the [`stderr`] field on [`Child`].
239 ///
240 /// [`Child`]: struct.Child.html
241 /// [`stderr`]: struct.Child.html#structfield.stderr
242 #[stable(feature = "process", since = "1.0.0")]
243 pub struct ChildStderr {
244     inner: AnonPipe
245 }
246
247 #[stable(feature = "process", since = "1.0.0")]
248 impl Read for ChildStderr {
249     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
250         self.inner.read(buf)
251     }
252     fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
253         self.inner.read_to_end(buf)
254     }
255 }
256
257 impl AsInner<AnonPipe> for ChildStderr {
258     fn as_inner(&self) -> &AnonPipe { &self.inner }
259 }
260
261 impl IntoInner<AnonPipe> for ChildStderr {
262     fn into_inner(self) -> AnonPipe { self.inner }
263 }
264
265 impl FromInner<AnonPipe> for ChildStderr {
266     fn from_inner(pipe: AnonPipe) -> ChildStderr {
267         ChildStderr { inner: pipe }
268     }
269 }
270
271 #[stable(feature = "std_debug", since = "1.16.0")]
272 impl fmt::Debug for ChildStderr {
273     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
274         f.pad("ChildStderr { .. }")
275     }
276 }
277
278 /// A process builder, providing fine-grained control
279 /// over how a new process should be spawned.
280 ///
281 /// A default configuration can be
282 /// generated using `Command::new(program)`, where `program` gives a path to the
283 /// program to be executed. Additional builder methods allow the configuration
284 /// to be changed (for example, by adding arguments) prior to spawning:
285 ///
286 /// ```
287 /// use std::process::Command;
288 ///
289 /// let output = if cfg!(target_os = "windows") {
290 ///     Command::new("cmd")
291 ///             .args(&["/C", "echo hello"])
292 ///             .output()
293 ///             .expect("failed to execute process")
294 /// } else {
295 ///     Command::new("sh")
296 ///             .arg("-c")
297 ///             .arg("echo hello")
298 ///             .output()
299 ///             .expect("failed to execute process")
300 /// };
301 ///
302 /// let hello = output.stdout;
303 /// ```
304 #[stable(feature = "process", since = "1.0.0")]
305 pub struct Command {
306     inner: imp::Command,
307 }
308
309 impl Command {
310     /// Constructs a new `Command` for launching the program at
311     /// path `program`, with the following default configuration:
312     ///
313     /// * No arguments to the program
314     /// * Inherit the current process's environment
315     /// * Inherit the current process's working directory
316     /// * Inherit stdin/stdout/stderr for `spawn` or `status`, but create pipes for `output`
317     ///
318     /// Builder methods are provided to change these defaults and
319     /// otherwise configure the process.
320     ///
321     /// If `program` is not an absolute path, the `PATH` will be searched in
322     /// an OS-defined way.
323     ///
324     /// The search path to be used may be controlled by setting the
325     /// `PATH` environment variable on the Command,
326     /// but this has some implementation limitations on Windows
327     /// (see https://github.com/rust-lang/rust/issues/37519).
328     ///
329     /// # Examples
330     ///
331     /// Basic usage:
332     ///
333     /// ```no_run
334     /// use std::process::Command;
335     ///
336     /// Command::new("sh")
337     ///         .spawn()
338     ///         .expect("sh command failed to start");
339     /// ```
340     #[stable(feature = "process", since = "1.0.0")]
341     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
342         Command { inner: imp::Command::new(program.as_ref()) }
343     }
344
345     /// Add an argument to pass to the program.
346     ///
347     /// Only one argument can be passed per use. So instead of:
348     ///
349     /// ```ignore
350     /// .arg("-C /path/to/repo")
351     /// ```
352     ///
353     /// usage would be:
354     ///
355     /// ```ignore
356     /// .arg("-C")
357     /// .arg("/path/to/repo")
358     /// ```
359     ///
360     /// To pass multiple arguments see [`args`].
361     ///
362     /// [`args`]: #method.args
363     ///
364     /// # Examples
365     ///
366     /// Basic usage:
367     ///
368     /// ```no_run
369     /// use std::process::Command;
370     ///
371     /// Command::new("ls")
372     ///         .arg("-l")
373     ///         .arg("-a")
374     ///         .spawn()
375     ///         .expect("ls command failed to start");
376     /// ```
377     #[stable(feature = "process", since = "1.0.0")]
378     pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
379         self.inner.arg(arg.as_ref());
380         self
381     }
382
383     /// Add multiple arguments to pass to the program.
384     ///
385     /// To pass a single argument see [`arg`].
386     ///
387     /// [`arg`]: #method.arg
388     ///
389     /// # Examples
390     ///
391     /// Basic usage:
392     ///
393     /// ```no_run
394     /// use std::process::Command;
395     ///
396     /// Command::new("ls")
397     ///         .args(&["-l", "-a"])
398     ///         .spawn()
399     ///         .expect("ls command failed to start");
400     /// ```
401     #[stable(feature = "process", since = "1.0.0")]
402     pub fn args<I, S>(&mut self, args: I) -> &mut Command
403         where I: IntoIterator<Item=S>, S: AsRef<OsStr>
404     {
405         for arg in args {
406             self.arg(arg.as_ref());
407         }
408         self
409     }
410
411     /// Inserts or updates an environment variable mapping.
412     ///
413     /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
414     /// and case-sensitive on all other platforms.
415     ///
416     /// # Examples
417     ///
418     /// Basic usage:
419     ///
420     /// ```no_run
421     /// use std::process::Command;
422     ///
423     /// Command::new("ls")
424     ///         .env("PATH", "/bin")
425     ///         .spawn()
426     ///         .expect("ls command failed to start");
427     /// ```
428     #[stable(feature = "process", since = "1.0.0")]
429     pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
430         where K: AsRef<OsStr>, V: AsRef<OsStr>
431     {
432         self.inner.env(key.as_ref(), val.as_ref());
433         self
434     }
435
436     /// Add or update multiple environment variable mappings.
437     ///
438     /// # Examples
439     ///
440     /// Basic usage:
441     ///
442     /// ```no_run
443     /// #![feature(command_envs)]
444     ///
445     /// use std::process::{Command, Stdio};
446     /// use std::env;
447     /// use std::collections::HashMap;
448     ///
449     /// let filtered_env : HashMap<String, String> =
450     ///     env::vars().filter(|&(ref k, _)|
451     ///         k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
452     ///     ).collect();
453     ///
454     /// Command::new("printenv")
455     ///         .stdin(Stdio::null())
456     ///         .stdout(Stdio::inherit())
457     ///         .env_clear()
458     ///         .envs(&filtered_env)
459     ///         .spawn()
460     ///         .expect("printenv failed to start");
461     /// ```
462     #[unstable(feature = "command_envs", issue = "38526")]
463     pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
464         where I: IntoIterator<Item=(K, V)>, K: AsRef<OsStr>, V: AsRef<OsStr>
465     {
466         for (ref key, ref val) in vars {
467             self.inner.env(key.as_ref(), val.as_ref());
468         }
469         self
470     }
471
472     /// Removes an environment variable mapping.
473     ///
474     /// # Examples
475     ///
476     /// Basic usage:
477     ///
478     /// ```no_run
479     /// use std::process::Command;
480     ///
481     /// Command::new("ls")
482     ///         .env_remove("PATH")
483     ///         .spawn()
484     ///         .expect("ls command failed to start");
485     /// ```
486     #[stable(feature = "process", since = "1.0.0")]
487     pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
488         self.inner.env_remove(key.as_ref());
489         self
490     }
491
492     /// Clears the entire environment map for the child process.
493     ///
494     /// # Examples
495     ///
496     /// Basic usage:
497     ///
498     /// ```no_run
499     /// use std::process::Command;
500     ///
501     /// Command::new("ls")
502     ///         .env_clear()
503     ///         .spawn()
504     ///         .expect("ls command failed to start");
505     /// ```
506     #[stable(feature = "process", since = "1.0.0")]
507     pub fn env_clear(&mut self) -> &mut Command {
508         self.inner.env_clear();
509         self
510     }
511
512     /// Sets the working directory for the child process.
513     ///
514     /// # Examples
515     ///
516     /// Basic usage:
517     ///
518     /// ```no_run
519     /// use std::process::Command;
520     ///
521     /// Command::new("ls")
522     ///         .current_dir("/bin")
523     ///         .spawn()
524     ///         .expect("ls command failed to start");
525     /// ```
526     #[stable(feature = "process", since = "1.0.0")]
527     pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {
528         self.inner.cwd(dir.as_ref().as_ref());
529         self
530     }
531
532     /// Configuration for the child process's stdin handle (file descriptor 0).
533     ///
534     /// # Examples
535     ///
536     /// Basic usage:
537     ///
538     /// ```no_run
539     /// use std::process::{Command, Stdio};
540     ///
541     /// Command::new("ls")
542     ///         .stdin(Stdio::null())
543     ///         .spawn()
544     ///         .expect("ls command failed to start");
545     /// ```
546     #[stable(feature = "process", since = "1.0.0")]
547     pub fn stdin(&mut self, cfg: Stdio) -> &mut Command {
548         self.inner.stdin(cfg.0);
549         self
550     }
551
552     /// Configuration for the child process's stdout handle (file descriptor 1).
553     ///
554     /// # Examples
555     ///
556     /// Basic usage:
557     ///
558     /// ```no_run
559     /// use std::process::{Command, Stdio};
560     ///
561     /// Command::new("ls")
562     ///         .stdout(Stdio::null())
563     ///         .spawn()
564     ///         .expect("ls command failed to start");
565     /// ```
566     #[stable(feature = "process", since = "1.0.0")]
567     pub fn stdout(&mut self, cfg: Stdio) -> &mut Command {
568         self.inner.stdout(cfg.0);
569         self
570     }
571
572     /// Configuration for the child process's stderr handle (file descriptor 2).
573     ///
574     /// # Examples
575     ///
576     /// Basic usage:
577     ///
578     /// ```no_run
579     /// use std::process::{Command, Stdio};
580     ///
581     /// Command::new("ls")
582     ///         .stderr(Stdio::null())
583     ///         .spawn()
584     ///         .expect("ls command failed to start");
585     /// ```
586     #[stable(feature = "process", since = "1.0.0")]
587     pub fn stderr(&mut self, cfg: Stdio) -> &mut Command {
588         self.inner.stderr(cfg.0);
589         self
590     }
591
592     /// Executes the command as a child process, returning a handle to it.
593     ///
594     /// By default, stdin, stdout and stderr are inherited from the parent.
595     ///
596     /// # Examples
597     ///
598     /// Basic usage:
599     ///
600     /// ```no_run
601     /// use std::process::Command;
602     ///
603     /// Command::new("ls")
604     ///         .spawn()
605     ///         .expect("ls command failed to start");
606     /// ```
607     #[stable(feature = "process", since = "1.0.0")]
608     pub fn spawn(&mut self) -> io::Result<Child> {
609         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
610     }
611
612     /// Executes the command as a child process, waiting for it to finish and
613     /// collecting all of its output.
614     ///
615     /// By default, stdin, stdout and stderr are captured (and used to
616     /// provide the resulting output).
617     ///
618     /// # Examples
619     ///
620     /// ```should_panic
621     /// use std::process::Command;
622     /// let output = Command::new("/bin/cat")
623     ///                      .arg("file.txt")
624     ///                      .output()
625     ///                      .expect("failed to execute process");
626     ///
627     /// println!("status: {}", output.status);
628     /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
629     /// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
630     ///
631     /// assert!(output.status.success());
632     /// ```
633     #[stable(feature = "process", since = "1.0.0")]
634     pub fn output(&mut self) -> io::Result<Output> {
635         self.inner.spawn(imp::Stdio::MakePipe, false).map(Child::from_inner)
636             .and_then(|p| p.wait_with_output())
637     }
638
639     /// Executes a command as a child process, waiting for it to finish and
640     /// collecting its exit status.
641     ///
642     /// By default, stdin, stdout and stderr are inherited from the parent.
643     ///
644     /// # Examples
645     ///
646     /// ```should_panic
647     /// use std::process::Command;
648     ///
649     /// let status = Command::new("/bin/cat")
650     ///                      .arg("file.txt")
651     ///                      .status()
652     ///                      .expect("failed to execute process");
653     ///
654     /// println!("process exited with: {}", status);
655     ///
656     /// assert!(status.success());
657     /// ```
658     #[stable(feature = "process", since = "1.0.0")]
659     pub fn status(&mut self) -> io::Result<ExitStatus> {
660         self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)
661                   .and_then(|mut p| p.wait())
662     }
663 }
664
665 #[stable(feature = "rust1", since = "1.0.0")]
666 impl fmt::Debug for Command {
667     /// Format the program and arguments of a Command for display. Any
668     /// non-utf8 data is lossily converted using the utf8 replacement
669     /// character.
670     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
671         self.inner.fmt(f)
672     }
673 }
674
675 impl AsInner<imp::Command> for Command {
676     fn as_inner(&self) -> &imp::Command { &self.inner }
677 }
678
679 impl AsInnerMut<imp::Command> for Command {
680     fn as_inner_mut(&mut self) -> &mut imp::Command { &mut self.inner }
681 }
682
683 /// The output of a finished process.
684 #[derive(PartialEq, Eq, Clone)]
685 #[stable(feature = "process", since = "1.0.0")]
686 pub struct Output {
687     /// The status (exit code) of the process.
688     #[stable(feature = "process", since = "1.0.0")]
689     pub status: ExitStatus,
690     /// The data that the process wrote to stdout.
691     #[stable(feature = "process", since = "1.0.0")]
692     pub stdout: Vec<u8>,
693     /// The data that the process wrote to stderr.
694     #[stable(feature = "process", since = "1.0.0")]
695     pub stderr: Vec<u8>,
696 }
697
698 // If either stderr or stdout are valid utf8 strings it prints the valid
699 // strings, otherwise it prints the byte sequence instead
700 #[stable(feature = "process_output_debug", since = "1.7.0")]
701 impl fmt::Debug for Output {
702     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
703
704         let stdout_utf8 = str::from_utf8(&self.stdout);
705         let stdout_debug: &fmt::Debug = match stdout_utf8 {
706             Ok(ref str) => str,
707             Err(_) => &self.stdout
708         };
709
710         let stderr_utf8 = str::from_utf8(&self.stderr);
711         let stderr_debug: &fmt::Debug = match stderr_utf8 {
712             Ok(ref str) => str,
713             Err(_) => &self.stderr
714         };
715
716         fmt.debug_struct("Output")
717             .field("status", &self.status)
718             .field("stdout", stdout_debug)
719             .field("stderr", stderr_debug)
720             .finish()
721     }
722 }
723
724 /// Describes what to do with a standard I/O stream for a child process.
725 #[stable(feature = "process", since = "1.0.0")]
726 pub struct Stdio(imp::Stdio);
727
728 impl Stdio {
729     /// A new pipe should be arranged to connect the parent and child processes.
730     #[stable(feature = "process", since = "1.0.0")]
731     pub fn piped() -> Stdio { Stdio(imp::Stdio::MakePipe) }
732
733     /// The child inherits from the corresponding parent descriptor.
734     #[stable(feature = "process", since = "1.0.0")]
735     pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
736
737     /// This stream will be ignored. This is the equivalent of attaching the
738     /// stream to `/dev/null`
739     #[stable(feature = "process", since = "1.0.0")]
740     pub fn null() -> Stdio { Stdio(imp::Stdio::Null) }
741 }
742
743 impl FromInner<imp::Stdio> for Stdio {
744     fn from_inner(inner: imp::Stdio) -> Stdio {
745         Stdio(inner)
746     }
747 }
748
749 #[stable(feature = "std_debug", since = "1.16.0")]
750 impl fmt::Debug for Stdio {
751     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
752         f.pad("Stdio { .. }")
753     }
754 }
755
756 /// Describes the result of a process after it has terminated.
757 ///
758 /// This `struct` is used to represent the exit status of a child process.
759 /// Child processes are created via the [`Command`] struct and their exit
760 /// status is exposed through the [`status`] method.
761 ///
762 /// [`Command`]: struct.Command.html
763 /// [`status`]: struct.Command.html#method.status
764 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
765 #[stable(feature = "process", since = "1.0.0")]
766 pub struct ExitStatus(imp::ExitStatus);
767
768 impl ExitStatus {
769     /// Was termination successful? Signal termination not considered a success,
770     /// and success is defined as a zero exit status.
771     ///
772     /// # Examples
773     ///
774     /// ```rust,no_run
775     /// use std::process::Command;
776     ///
777     /// let status = Command::new("mkdir")
778     ///                      .arg("projects")
779     ///                      .status()
780     ///                      .expect("failed to execute mkdir");
781     ///
782     /// if status.success() {
783     ///     println!("'projects/' directory created");
784     /// } else {
785     ///     println!("failed to create 'projects/' directory");
786     /// }
787     /// ```
788     #[stable(feature = "process", since = "1.0.0")]
789     pub fn success(&self) -> bool {
790         self.0.success()
791     }
792
793     /// Returns the exit code of the process, if any.
794     ///
795     /// On Unix, this will return `None` if the process was terminated
796     /// by a signal; `std::os::unix` provides an extension trait for
797     /// extracting the signal and other details from the `ExitStatus`.
798     ///
799     /// # Examples
800     ///
801     /// ```no_run
802     /// use std::process::Command;
803     ///
804     /// let status = Command::new("mkdir")
805     ///                      .arg("projects")
806     ///                      .status()
807     ///                      .expect("failed to execute mkdir");
808     ///
809     /// match status.code() {
810     ///     Some(code) => println!("Exited with status code: {}", code),
811     ///     None       => println!("Process terminated by signal")
812     /// }
813     /// ```
814     #[stable(feature = "process", since = "1.0.0")]
815     pub fn code(&self) -> Option<i32> {
816         self.0.code()
817     }
818 }
819
820 impl AsInner<imp::ExitStatus> for ExitStatus {
821     fn as_inner(&self) -> &imp::ExitStatus { &self.0 }
822 }
823
824 impl FromInner<imp::ExitStatus> for ExitStatus {
825     fn from_inner(s: imp::ExitStatus) -> ExitStatus {
826         ExitStatus(s)
827     }
828 }
829
830 #[stable(feature = "process", since = "1.0.0")]
831 impl fmt::Display for ExitStatus {
832     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
833         self.0.fmt(f)
834     }
835 }
836
837 impl Child {
838     /// Forces the child to exit. This is equivalent to sending a
839     /// SIGKILL on unix platforms.
840     ///
841     /// # Examples
842     ///
843     /// Basic usage:
844     ///
845     /// ```no_run
846     /// use std::process::Command;
847     ///
848     /// let mut command = Command::new("yes");
849     /// if let Ok(mut child) = command.spawn() {
850     ///     child.kill().expect("command wasn't running");
851     /// } else {
852     ///     println!("yes command didn't start");
853     /// }
854     /// ```
855     #[stable(feature = "process", since = "1.0.0")]
856     pub fn kill(&mut self) -> io::Result<()> {
857         self.handle.kill()
858     }
859
860     /// Returns the OS-assigned process identifier associated with this child.
861     ///
862     /// # Examples
863     ///
864     /// Basic usage:
865     ///
866     /// ```no_run
867     /// use std::process::Command;
868     ///
869     /// let mut command = Command::new("ls");
870     /// if let Ok(child) = command.spawn() {
871     ///     println!("Child's id is {}", child.id());
872     /// } else {
873     ///     println!("ls command didn't start");
874     /// }
875     /// ```
876     #[stable(feature = "process_id", since = "1.3.0")]
877     pub fn id(&self) -> u32 {
878         self.handle.id()
879     }
880
881     /// Waits for the child to exit completely, returning the status that it
882     /// exited with. This function will continue to have the same return value
883     /// after it has been called at least once.
884     ///
885     /// The stdin handle to the child process, if any, will be closed
886     /// before waiting. This helps avoid deadlock: it ensures that the
887     /// child does not block waiting for input from the parent, while
888     /// the parent waits for the child to exit.
889     ///
890     /// # Examples
891     ///
892     /// Basic usage:
893     ///
894     /// ```no_run
895     /// use std::process::Command;
896     ///
897     /// let mut command = Command::new("ls");
898     /// if let Ok(mut child) = command.spawn() {
899     ///     child.wait().expect("command wasn't running");
900     ///     println!("Child has finished its execution!");
901     /// } else {
902     ///     println!("ls command didn't start");
903     /// }
904     /// ```
905     #[stable(feature = "process", since = "1.0.0")]
906     pub fn wait(&mut self) -> io::Result<ExitStatus> {
907         drop(self.stdin.take());
908         self.handle.wait().map(ExitStatus)
909     }
910
911     /// Attempts to collect the exit status of the child if it has already
912     /// exited.
913     ///
914     /// This function will not block the calling thread and will only advisorily
915     /// check to see if the child process has exited or not. If the child has
916     /// exited then on Unix the process id is reaped. This function is
917     /// guaranteed to repeatedly return a successful exit status so long as the
918     /// child has already exited.
919     ///
920     /// If the child has exited, then `Ok(Some(status))` is returned. If the
921     /// exit status is not available at this time then `Ok(None)` is returned.
922     /// If an error occurs, then that error is returned.
923     ///
924     /// Note that unlike `wait`, this function will not attempt to drop stdin.
925     ///
926     /// # Examples
927     ///
928     /// Basic usage:
929     ///
930     /// ```no_run
931     /// use std::process::Command;
932     ///
933     /// let mut child = Command::new("ls").spawn().unwrap();
934     ///
935     /// match child.try_wait() {
936     ///     Ok(Some(status)) => println!("exited with: {}", status),
937     ///     Ok(None) => {
938     ///         println!("status not ready yet, let's really wait");
939     ///         let res = child.wait();
940     ///         println!("result: {:?}", res);
941     ///     }
942     ///     Err(e) => println!("error attempting to wait: {}", e),
943     /// }
944     /// ```
945     #[stable(feature = "process_try_wait", since = "1.18.0")]
946     pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {
947         Ok(self.handle.try_wait()?.map(ExitStatus))
948     }
949
950     /// Simultaneously waits for the child to exit and collect all remaining
951     /// output on the stdout/stderr handles, returning an `Output`
952     /// instance.
953     ///
954     /// The stdin handle to the child process, if any, will be closed
955     /// before waiting. This helps avoid deadlock: it ensures that the
956     /// child does not block waiting for input from the parent, while
957     /// the parent waits for the child to exit.
958     ///
959     /// By default, stdin, stdout and stderr are inherited from the parent.
960     /// In order to capture the output into this `Result<Output>` it is
961     /// necessary to create new pipes between parent and child. Use
962     /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively.
963     ///
964     /// # Examples
965     ///
966     /// ```should_panic
967     /// use std::process::{Command, Stdio};
968     ///
969     /// let child = Command::new("/bin/cat")
970     ///     .arg("file.txt")
971     ///     .stdout(Stdio::piped())
972     ///     .spawn()
973     ///     .expect("failed to execute child");
974     ///
975     /// let output = child
976     ///     .wait_with_output()
977     ///     .expect("failed to wait on child");
978     ///
979     /// assert!(output.status.success());
980     /// ```
981     ///
982     #[stable(feature = "process", since = "1.0.0")]
983     pub fn wait_with_output(mut self) -> io::Result<Output> {
984         drop(self.stdin.take());
985
986         let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
987         match (self.stdout.take(), self.stderr.take()) {
988             (None, None) => {}
989             (Some(mut out), None) => {
990                 let res = out.read_to_end(&mut stdout);
991                 res.unwrap();
992             }
993             (None, Some(mut err)) => {
994                 let res = err.read_to_end(&mut stderr);
995                 res.unwrap();
996             }
997             (Some(out), Some(err)) => {
998                 let res = read2(out.inner, &mut stdout, err.inner, &mut stderr);
999                 res.unwrap();
1000             }
1001         }
1002
1003         let status = self.wait()?;
1004         Ok(Output {
1005             status: status,
1006             stdout: stdout,
1007             stderr: stderr,
1008         })
1009     }
1010 }
1011
1012 /// Terminates the current process with the specified exit code.
1013 ///
1014 /// This function will never return and will immediately terminate the current
1015 /// process. The exit code is passed through to the underlying OS and will be
1016 /// available for consumption by another process.
1017 ///
1018 /// Note that because this function never returns, and that it terminates the
1019 /// process, no destructors on the current stack or any other thread's stack
1020 /// will be run. If a clean shutdown is needed it is recommended to only call
1021 /// this function at a known point where there are no more destructors left
1022 /// to run.
1023 ///
1024 /// ## Platform-specific behavior
1025 ///
1026 /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
1027 /// will be visible to a parent process inspecting the exit code. On most
1028 /// Unix-like platforms, only the eight least-significant bits are considered.
1029 ///
1030 /// # Examples
1031 ///
1032 /// Due to this function’s behavior regarding destructors, a conventional way
1033 /// to use the function is to extract the actual computation to another
1034 /// function and compute the exit code from its return value:
1035 ///
1036 /// ```
1037 /// use std::io::{self, Write};
1038 ///
1039 /// fn run_app() -> Result<(), ()> {
1040 ///     // Application logic here
1041 ///     Ok(())
1042 /// }
1043 ///
1044 /// fn main() {
1045 ///     ::std::process::exit(match run_app() {
1046 ///        Ok(_) => 0,
1047 ///        Err(err) => {
1048 ///            writeln!(io::stderr(), "error: {:?}", err).unwrap();
1049 ///            1
1050 ///        }
1051 ///     });
1052 /// }
1053 /// ```
1054 ///
1055 /// Due to [platform-specific behavior], the exit code for this example will be
1056 /// `0` on Linux, but `256` on Windows:
1057 ///
1058 /// ```no_run
1059 /// use std::process;
1060 ///
1061 /// process::exit(0x0100);
1062 /// ```
1063 ///
1064 /// [platform-specific behavior]: #platform-specific-behavior
1065 #[stable(feature = "rust1", since = "1.0.0")]
1066 pub fn exit(code: i32) -> ! {
1067     ::sys_common::cleanup();
1068     ::sys::os::exit(code)
1069 }
1070
1071 /// Terminates the process in an abnormal fashion.
1072 ///
1073 /// The function will never return and will immediately terminate the current
1074 /// process in a platform specific "abnormal" manner.
1075 ///
1076 /// Note that because this function never returns, and that it terminates the
1077 /// process, no destructors on the current stack or any other thread's stack
1078 /// will be run. If a clean shutdown is needed it is recommended to only call
1079 /// this function at a known point where there are no more destructors left
1080 /// to run.
1081 ///
1082 /// # Examples
1083 ///
1084 /// ```no_run
1085 /// use std::process;
1086 ///
1087 /// fn main() {
1088 ///     println!("aborting");
1089 ///
1090 ///     process::abort();
1091 ///
1092 ///     // execution never gets here
1093 /// }
1094 /// ```
1095 ///
1096 /// The [`abort`] function terminates the process, so the destructor will not
1097 /// get run on the example below:
1098 ///
1099 /// ```no_run
1100 /// use std::process;
1101 ///
1102 /// struct HasDrop;
1103 ///
1104 /// impl Drop for HasDrop {
1105 ///     fn drop(&mut self) {
1106 ///         println!("This will never be printed!");
1107 ///     }
1108 /// }
1109 ///
1110 /// fn main() {
1111 ///     let _x = HasDrop;
1112 ///     process::abort();
1113 ///     // the destructor implemented for HasDrop will never get run
1114 /// }
1115 /// ```
1116 #[stable(feature = "process_abort", since = "1.17.0")]
1117 pub fn abort() -> ! {
1118     unsafe { ::sys::abort_internal() };
1119 }
1120
1121 #[cfg(all(test, not(target_os = "emscripten")))]
1122 mod tests {
1123     use io::prelude::*;
1124
1125     use io::ErrorKind;
1126     use str;
1127     use super::{Command, Output, Stdio};
1128
1129     // FIXME(#10380) these tests should not all be ignored on android.
1130
1131     #[test]
1132     #[cfg_attr(target_os = "android", ignore)]
1133     fn smoke() {
1134         let p = if cfg!(target_os = "windows") {
1135             Command::new("cmd").args(&["/C", "exit 0"]).spawn()
1136         } else {
1137             Command::new("true").spawn()
1138         };
1139         assert!(p.is_ok());
1140         let mut p = p.unwrap();
1141         assert!(p.wait().unwrap().success());
1142     }
1143
1144     #[test]
1145     #[cfg_attr(target_os = "android", ignore)]
1146     fn smoke_failure() {
1147         match Command::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
1148             Ok(..) => panic!(),
1149             Err(..) => {}
1150         }
1151     }
1152
1153     #[test]
1154     #[cfg_attr(target_os = "android", ignore)]
1155     fn exit_reported_right() {
1156         let p = if cfg!(target_os = "windows") {
1157             Command::new("cmd").args(&["/C", "exit 1"]).spawn()
1158         } else {
1159             Command::new("false").spawn()
1160         };
1161         assert!(p.is_ok());
1162         let mut p = p.unwrap();
1163         assert!(p.wait().unwrap().code() == Some(1));
1164         drop(p.wait());
1165     }
1166
1167     #[test]
1168     #[cfg(unix)]
1169     #[cfg_attr(target_os = "android", ignore)]
1170     fn signal_reported_right() {
1171         use os::unix::process::ExitStatusExt;
1172
1173         let mut p = Command::new("/bin/sh")
1174                             .arg("-c").arg("read a")
1175                             .stdin(Stdio::piped())
1176                             .spawn().unwrap();
1177         p.kill().unwrap();
1178         match p.wait().unwrap().signal() {
1179             Some(9) => {},
1180             result => panic!("not terminated by signal 9 (instead, {:?})",
1181                              result),
1182         }
1183     }
1184
1185     pub fn run_output(mut cmd: Command) -> String {
1186         let p = cmd.spawn();
1187         assert!(p.is_ok());
1188         let mut p = p.unwrap();
1189         assert!(p.stdout.is_some());
1190         let mut ret = String::new();
1191         p.stdout.as_mut().unwrap().read_to_string(&mut ret).unwrap();
1192         assert!(p.wait().unwrap().success());
1193         return ret;
1194     }
1195
1196     #[test]
1197     #[cfg_attr(target_os = "android", ignore)]
1198     fn stdout_works() {
1199         if cfg!(target_os = "windows") {
1200             let mut cmd = Command::new("cmd");
1201             cmd.args(&["/C", "echo foobar"]).stdout(Stdio::piped());
1202             assert_eq!(run_output(cmd), "foobar\r\n");
1203         } else {
1204             let mut cmd = Command::new("echo");
1205             cmd.arg("foobar").stdout(Stdio::piped());
1206             assert_eq!(run_output(cmd), "foobar\n");
1207         }
1208     }
1209
1210     #[test]
1211     #[cfg_attr(any(windows, target_os = "android"), ignore)]
1212     fn set_current_dir_works() {
1213         let mut cmd = Command::new("/bin/sh");
1214         cmd.arg("-c").arg("pwd")
1215            .current_dir("/")
1216            .stdout(Stdio::piped());
1217         assert_eq!(run_output(cmd), "/\n");
1218     }
1219
1220     #[test]
1221     #[cfg_attr(any(windows, target_os = "android"), ignore)]
1222     fn stdin_works() {
1223         let mut p = Command::new("/bin/sh")
1224                             .arg("-c").arg("read line; echo $line")
1225                             .stdin(Stdio::piped())
1226                             .stdout(Stdio::piped())
1227                             .spawn().unwrap();
1228         p.stdin.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
1229         drop(p.stdin.take());
1230         let mut out = String::new();
1231         p.stdout.as_mut().unwrap().read_to_string(&mut out).unwrap();
1232         assert!(p.wait().unwrap().success());
1233         assert_eq!(out, "foobar\n");
1234     }
1235
1236
1237     #[test]
1238     #[cfg_attr(target_os = "android", ignore)]
1239     #[cfg(unix)]
1240     fn uid_works() {
1241         use os::unix::prelude::*;
1242         use libc;
1243         let mut p = Command::new("/bin/sh")
1244                             .arg("-c").arg("true")
1245                             .uid(unsafe { libc::getuid() })
1246                             .gid(unsafe { libc::getgid() })
1247                             .spawn().unwrap();
1248         assert!(p.wait().unwrap().success());
1249     }
1250
1251     #[test]
1252     #[cfg_attr(target_os = "android", ignore)]
1253     #[cfg(unix)]
1254     fn uid_to_root_fails() {
1255         use os::unix::prelude::*;
1256         use libc;
1257
1258         // if we're already root, this isn't a valid test. Most of the bots run
1259         // as non-root though (android is an exception).
1260         if unsafe { libc::getuid() == 0 } { return }
1261         assert!(Command::new("/bin/ls").uid(0).gid(0).spawn().is_err());
1262     }
1263
1264     #[test]
1265     #[cfg_attr(target_os = "android", ignore)]
1266     fn test_process_status() {
1267         let mut status = if cfg!(target_os = "windows") {
1268             Command::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
1269         } else {
1270             Command::new("false").status().unwrap()
1271         };
1272         assert!(status.code() == Some(1));
1273
1274         status = if cfg!(target_os = "windows") {
1275             Command::new("cmd").args(&["/C", "exit 0"]).status().unwrap()
1276         } else {
1277             Command::new("true").status().unwrap()
1278         };
1279         assert!(status.success());
1280     }
1281
1282     #[test]
1283     fn test_process_output_fail_to_start() {
1284         match Command::new("/no-binary-by-this-name-should-exist").output() {
1285             Err(e) => assert_eq!(e.kind(), ErrorKind::NotFound),
1286             Ok(..) => panic!()
1287         }
1288     }
1289
1290     #[test]
1291     #[cfg_attr(target_os = "android", ignore)]
1292     fn test_process_output_output() {
1293         let Output {status, stdout, stderr}
1294              = if cfg!(target_os = "windows") {
1295                  Command::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
1296              } else {
1297                  Command::new("echo").arg("hello").output().unwrap()
1298              };
1299         let output_str = str::from_utf8(&stdout).unwrap();
1300
1301         assert!(status.success());
1302         assert_eq!(output_str.trim().to_string(), "hello");
1303         assert_eq!(stderr, Vec::new());
1304     }
1305
1306     #[test]
1307     #[cfg_attr(target_os = "android", ignore)]
1308     fn test_process_output_error() {
1309         let Output {status, stdout, stderr}
1310              = if cfg!(target_os = "windows") {
1311                  Command::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
1312              } else {
1313                  Command::new("mkdir").arg(".").output().unwrap()
1314              };
1315
1316         assert!(status.code() == Some(1));
1317         assert_eq!(stdout, Vec::new());
1318         assert!(!stderr.is_empty());
1319     }
1320
1321     #[test]
1322     #[cfg_attr(target_os = "android", ignore)]
1323     fn test_finish_once() {
1324         let mut prog = if cfg!(target_os = "windows") {
1325             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1326         } else {
1327             Command::new("false").spawn().unwrap()
1328         };
1329         assert!(prog.wait().unwrap().code() == Some(1));
1330     }
1331
1332     #[test]
1333     #[cfg_attr(target_os = "android", ignore)]
1334     fn test_finish_twice() {
1335         let mut prog = if cfg!(target_os = "windows") {
1336             Command::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1337         } else {
1338             Command::new("false").spawn().unwrap()
1339         };
1340         assert!(prog.wait().unwrap().code() == Some(1));
1341         assert!(prog.wait().unwrap().code() == Some(1));
1342     }
1343
1344     #[test]
1345     #[cfg_attr(target_os = "android", ignore)]
1346     fn test_wait_with_output_once() {
1347         let prog = if cfg!(target_os = "windows") {
1348             Command::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio::piped()).spawn().unwrap()
1349         } else {
1350             Command::new("echo").arg("hello").stdout(Stdio::piped()).spawn().unwrap()
1351         };
1352
1353         let Output {status, stdout, stderr} = prog.wait_with_output().unwrap();
1354         let output_str = str::from_utf8(&stdout).unwrap();
1355
1356         assert!(status.success());
1357         assert_eq!(output_str.trim().to_string(), "hello");
1358         assert_eq!(stderr, Vec::new());
1359     }
1360
1361     #[cfg(all(unix, not(target_os="android")))]
1362     pub fn env_cmd() -> Command {
1363         Command::new("env")
1364     }
1365     #[cfg(target_os="android")]
1366     pub fn env_cmd() -> Command {
1367         let mut cmd = Command::new("/system/bin/sh");
1368         cmd.arg("-c").arg("set");
1369         cmd
1370     }
1371
1372     #[cfg(windows)]
1373     pub fn env_cmd() -> Command {
1374         let mut cmd = Command::new("cmd");
1375         cmd.arg("/c").arg("set");
1376         cmd
1377     }
1378
1379     #[test]
1380     fn test_inherit_env() {
1381         use env;
1382
1383         let result = env_cmd().output().unwrap();
1384         let output = String::from_utf8(result.stdout).unwrap();
1385
1386         for (ref k, ref v) in env::vars() {
1387             // don't check android RANDOM variables
1388             if cfg!(target_os = "android") && *k == "RANDOM" {
1389                 continue
1390             }
1391
1392             // Windows has hidden environment variables whose names start with
1393             // equals signs (`=`). Those do not show up in the output of the
1394             // `set` command.
1395             assert!((cfg!(windows) && k.starts_with("=")) ||
1396                     k.starts_with("DYLD") ||
1397                     output.contains(&format!("{}={}", *k, *v)) ||
1398                     output.contains(&format!("{}='{}'", *k, *v)),
1399                     "output doesn't contain `{}={}`\n{}",
1400                     k, v, output);
1401         }
1402     }
1403
1404     #[test]
1405     fn test_override_env() {
1406         use env;
1407
1408         // In some build environments (such as chrooted Nix builds), `env` can
1409         // only be found in the explicitly-provided PATH env variable, not in
1410         // default places such as /bin or /usr/bin. So we need to pass through
1411         // PATH to our sub-process.
1412         let mut cmd = env_cmd();
1413         cmd.env_clear().env("RUN_TEST_NEW_ENV", "123");
1414         if let Some(p) = env::var_os("PATH") {
1415             cmd.env("PATH", &p);
1416         }
1417         let result = cmd.output().unwrap();
1418         let output = String::from_utf8_lossy(&result.stdout).to_string();
1419
1420         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
1421                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
1422     }
1423
1424     #[test]
1425     fn test_add_to_env() {
1426         let result = env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
1427         let output = String::from_utf8_lossy(&result.stdout).to_string();
1428
1429         assert!(output.contains("RUN_TEST_NEW_ENV=123"),
1430                 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output);
1431     }
1432
1433     // Regression tests for #30858.
1434     #[test]
1435     fn test_interior_nul_in_progname_is_error() {
1436         match Command::new("has-some-\0\0s-inside").spawn() {
1437             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1438             Ok(_) => panic!(),
1439         }
1440     }
1441
1442     #[test]
1443     fn test_interior_nul_in_arg_is_error() {
1444         match Command::new("echo").arg("has-some-\0\0s-inside").spawn() {
1445             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1446             Ok(_) => panic!(),
1447         }
1448     }
1449
1450     #[test]
1451     fn test_interior_nul_in_args_is_error() {
1452         match Command::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
1453             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1454             Ok(_) => panic!(),
1455         }
1456     }
1457
1458     #[test]
1459     fn test_interior_nul_in_current_dir_is_error() {
1460         match Command::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
1461             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1462             Ok(_) => panic!(),
1463         }
1464     }
1465
1466     // Regression tests for #30862.
1467     #[test]
1468     fn test_interior_nul_in_env_key_is_error() {
1469         match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
1470             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1471             Ok(_) => panic!(),
1472         }
1473     }
1474
1475     #[test]
1476     fn test_interior_nul_in_env_value_is_error() {
1477         match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
1478             Err(e) => assert_eq!(e.kind(), ErrorKind::InvalidInput),
1479             Ok(_) => panic!(),
1480         }
1481     }
1482
1483     /// Test that process creation flags work by debugging a process.
1484     /// Other creation flags make it hard or impossible to detect
1485     /// behavioral changes in the process.
1486     #[test]
1487     #[cfg(windows)]
1488     fn test_creation_flags() {
1489         use os::windows::process::CommandExt;
1490         use sys::c::{BOOL, DWORD, INFINITE};
1491         #[repr(C, packed)]
1492         struct DEBUG_EVENT {
1493             pub event_code: DWORD,
1494             pub process_id: DWORD,
1495             pub thread_id: DWORD,
1496             // This is a union in the real struct, but we don't
1497             // need this data for the purposes of this test.
1498             pub _junk: [u8; 164],
1499         }
1500
1501         extern "system" {
1502             fn WaitForDebugEvent(lpDebugEvent: *mut DEBUG_EVENT, dwMilliseconds: DWORD) -> BOOL;
1503             fn ContinueDebugEvent(dwProcessId: DWORD, dwThreadId: DWORD,
1504                                   dwContinueStatus: DWORD) -> BOOL;
1505         }
1506
1507         const DEBUG_PROCESS: DWORD = 1;
1508         const EXIT_PROCESS_DEBUG_EVENT: DWORD = 5;
1509         const DBG_EXCEPTION_NOT_HANDLED: DWORD = 0x80010001;
1510
1511         let mut child = Command::new("cmd")
1512             .creation_flags(DEBUG_PROCESS)
1513             .stdin(Stdio::piped()).spawn().unwrap();
1514         child.stdin.take().unwrap().write_all(b"exit\r\n").unwrap();
1515         let mut events = 0;
1516         let mut event = DEBUG_EVENT {
1517             event_code: 0,
1518             process_id: 0,
1519             thread_id: 0,
1520             _junk: [0; 164],
1521         };
1522         loop {
1523             if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) } == 0 {
1524                 panic!("WaitForDebugEvent failed!");
1525             }
1526             events += 1;
1527
1528             if event.event_code == EXIT_PROCESS_DEBUG_EVENT {
1529                 break;
1530             }
1531
1532             if unsafe { ContinueDebugEvent(event.process_id,
1533                                            event.thread_id,
1534                                            DBG_EXCEPTION_NOT_HANDLED) } == 0 {
1535                 panic!("ContinueDebugEvent failed!");
1536             }
1537         }
1538         assert!(events > 0);
1539     }
1540 }