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