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