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