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.
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.
11 //! A module for working with processes.
15 //! Basic usage where we try to execute the `cat` shell command:
18 //! use std::process::Command;
20 //! let mut child = Command::new("/bin/cat")
23 //! .expect("failed to execute child");
25 //! let ecode = child.wait()
26 //! .expect("failed to wait on child");
28 //! assert!(ecode.success());
31 //! Calling a command with input and reading its output:
34 //! use std::process::{Command, Stdio};
35 //! use std::io::Write;
37 //! let mut child = Command::new("/bin/cat")
38 //! .stdin(Stdio::piped())
39 //! .stdout(Stdio::piped())
41 //! .expect("failed to execute child");
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");
49 //! let output = child
50 //! .wait_with_output()
51 //! .expect("failed to wait on child");
53 //! assert_eq!(b"test", output.stdout.as_slice());
56 #![stable(feature = "process", since = "1.0.0")]
65 use sys
::pipe
::{read2, AnonPipe}
;
66 use sys
::process
as imp
;
67 use sys_common
::{AsInner, AsInnerMut, FromInner, IntoInner}
;
69 /// Representation of a running or exited child process.
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
79 /// use std::process::Command;
81 /// let mut child = Command::new("/bin/cat")
84 /// .expect("failed to execute child");
86 /// let ecode = child.wait()
87 /// .expect("failed to wait on child");
89 /// assert!(ecode.success());
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
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
103 /// [`Command`]: struct.Command.html
104 /// [`Drop`]: ../../core/ops/trait.Drop.html
105 /// [`wait`]: #method.wait
106 #[stable(feature = "process", since = "1.0.0")]
108 handle
: imp
::Process
,
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
>,
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
>,
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
>,
123 impl AsInner
<imp
::Process
> for Child
{
124 fn as_inner(&self) -> &imp
::Process { &self.handle }
127 impl FromInner
<(imp
::Process
, imp
::StdioPipes
)> for Child
{
128 fn from_inner((handle
, io
): (imp
::Process
, imp
::StdioPipes
)) -> Child
{
131 stdin
: io
.stdin
.map(ChildStdin
::from_inner
),
132 stdout
: io
.stdout
.map(ChildStdout
::from_inner
),
133 stderr
: io
.stderr
.map(ChildStderr
::from_inner
),
138 impl IntoInner
<imp
::Process
> for Child
{
139 fn into_inner(self) -> imp
::Process { self.handle }
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
)
153 /// A handle to a child process's stdin. This struct is used in the [`stdin`]
154 /// field on [`Child`].
156 /// [`Child`]: struct.Child.html
157 /// [`stdin`]: struct.Child.html#structfield.stdin
158 #[stable(feature = "process", since = "1.0.0")]
159 pub struct ChildStdin
{
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
)
169 fn flush(&mut self) -> io
::Result
<()> {
174 impl AsInner
<AnonPipe
> for ChildStdin
{
175 fn as_inner(&self) -> &AnonPipe { &self.inner }
178 impl IntoInner
<AnonPipe
> for ChildStdin
{
179 fn into_inner(self) -> AnonPipe { self.inner }
182 impl FromInner
<AnonPipe
> for ChildStdin
{
183 fn from_inner(pipe
: AnonPipe
) -> ChildStdin
{
184 ChildStdin { inner: pipe }
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 { .. }")
195 /// A handle to a child process's stdout. This struct is used in the [`stdout`]
196 /// field on [`Child`].
198 /// [`Child`]: struct.Child.html
199 /// [`stdout`]: struct.Child.html#structfield.stdout
200 #[stable(feature = "process", since = "1.0.0")]
201 pub struct ChildStdout
{
205 #[stable(feature = "process", since = "1.0.0")]
206 impl Read
for ChildStdout
{
207 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
210 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
211 self.inner
.read_to_end(buf
)
215 impl AsInner
<AnonPipe
> for ChildStdout
{
216 fn as_inner(&self) -> &AnonPipe { &self.inner }
219 impl IntoInner
<AnonPipe
> for ChildStdout
{
220 fn into_inner(self) -> AnonPipe { self.inner }
223 impl FromInner
<AnonPipe
> for ChildStdout
{
224 fn from_inner(pipe
: AnonPipe
) -> ChildStdout
{
225 ChildStdout { inner: pipe }
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 { .. }")
236 /// A handle to a child process's stderr. This struct is used in the [`stderr`]
237 /// field on [`Child`].
239 /// [`Child`]: struct.Child.html
240 /// [`stderr`]: struct.Child.html#structfield.stderr
241 #[stable(feature = "process", since = "1.0.0")]
242 pub struct ChildStderr
{
246 #[stable(feature = "process", since = "1.0.0")]
247 impl Read
for ChildStderr
{
248 fn read(&mut self, buf
: &mut [u8]) -> io
::Result
<usize> {
251 fn read_to_end(&mut self, buf
: &mut Vec
<u8>) -> io
::Result
<usize> {
252 self.inner
.read_to_end(buf
)
256 impl AsInner
<AnonPipe
> for ChildStderr
{
257 fn as_inner(&self) -> &AnonPipe { &self.inner }
260 impl IntoInner
<AnonPipe
> for ChildStderr
{
261 fn into_inner(self) -> AnonPipe { self.inner }
264 impl FromInner
<AnonPipe
> for ChildStderr
{
265 fn from_inner(pipe
: AnonPipe
) -> ChildStderr
{
266 ChildStderr { inner: pipe }
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 { .. }")
277 /// A process builder, providing fine-grained control
278 /// over how a new process should be spawned.
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:
286 /// use std::process::Command;
288 /// let output = if cfg!(target_os = "windows") {
289 /// Command::new("cmd")
290 /// .args(&["/C", "echo hello"])
292 /// .expect("failed to execute process")
294 /// Command::new("sh")
296 /// .arg("echo hello")
298 /// .expect("failed to execute process")
301 /// let hello = output.stdout;
303 #[stable(feature = "process", since = "1.0.0")]
309 /// Constructs a new `Command` for launching the program at
310 /// path `program`, with the following default configuration:
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`
317 /// Builder methods are provided to change these defaults and
318 /// otherwise configure the process.
320 /// If `program` is not an absolute path, the `PATH` will be searched in
321 /// an OS-defined way.
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).
333 /// use std::process::Command;
335 /// Command::new("sh")
337 /// .expect("sh command failed to start");
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()) }
344 /// Add an argument to pass to the program.
351 /// use std::process::Command;
353 /// Command::new("ls")
357 /// .expect("ls command failed to start");
359 #[stable(feature = "process", since = "1.0.0")]
360 pub fn arg
<S
: AsRef
<OsStr
>>(&mut self, arg
: S
) -> &mut Command
{
361 self.inner
.arg(arg
.as_ref());
365 /// Add multiple arguments to pass to the program.
372 /// use std::process::Command;
374 /// Command::new("ls")
375 /// .args(&["-l", "-a"])
377 /// .expect("ls command failed to start");
379 #[stable(feature = "process", since = "1.0.0")]
380 pub fn args
<I
, S
>(&mut self, args
: I
) -> &mut Command
381 where I
: IntoIterator
<Item
=S
>, S
: AsRef
<OsStr
>
384 self.arg(arg
.as_ref());
389 /// Inserts or updates an environment variable mapping.
391 /// Note that environment variable names are case-insensitive (but case-preserving) on Windows,
392 /// and case-sensitive on all other platforms.
399 /// use std::process::Command;
401 /// Command::new("ls")
402 /// .env("PATH", "/bin")
404 /// .expect("ls command failed to start");
406 #[stable(feature = "process", since = "1.0.0")]
407 pub fn env
<K
, V
>(&mut self, key
: K
, val
: V
) -> &mut Command
408 where K
: AsRef
<OsStr
>, V
: AsRef
<OsStr
>
410 self.inner
.env(key
.as_ref(), val
.as_ref());
414 /// Add or update multiple environment variable mappings.
420 /// use std::process::{Command, Stdio};
422 /// use std::collections::HashMap;
424 /// let filtered_env : HashMap<String, String> =
425 /// env::vars().filter(|&(ref k, _)|
426 /// k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH"
429 /// Command::new("printenv")
430 /// .stdin(Stdio::null())
431 /// .stdout(Stdio::inherit())
433 /// .envs(&filtered_env)
435 /// .expect("printenv failed to start");
437 #[unstable(feature = "command_envs", issue = "38526")]
438 pub fn envs
<I
, K
, V
>(&mut self, vars
: I
) -> &mut Command
439 where I
: IntoIterator
<Item
=(K
, V
)>, K
: AsRef
<OsStr
>, V
: AsRef
<OsStr
>
441 for (ref key
, ref val
) in vars
{
442 self.inner
.env(key
.as_ref(), val
.as_ref());
447 /// Removes an environment variable mapping.
454 /// use std::process::Command;
456 /// Command::new("ls")
457 /// .env_remove("PATH")
459 /// .expect("ls command failed to start");
461 #[stable(feature = "process", since = "1.0.0")]
462 pub fn env_remove
<K
: AsRef
<OsStr
>>(&mut self, key
: K
) -> &mut Command
{
463 self.inner
.env_remove(key
.as_ref());
467 /// Clears the entire environment map for the child process.
474 /// use std::process::Command;
476 /// Command::new("ls")
479 /// .expect("ls command failed to start");
481 #[stable(feature = "process", since = "1.0.0")]
482 pub fn env_clear(&mut self) -> &mut Command
{
483 self.inner
.env_clear();
487 /// Sets the working directory for the child process.
494 /// use std::process::Command;
496 /// Command::new("ls")
497 /// .current_dir("/bin")
499 /// .expect("ls command failed to start");
501 #[stable(feature = "process", since = "1.0.0")]
502 pub fn current_dir
<P
: AsRef
<Path
>>(&mut self, dir
: P
) -> &mut Command
{
503 self.inner
.cwd(dir
.as_ref().as_ref());
507 /// Configuration for the child process's stdin handle (file descriptor 0).
514 /// use std::process::{Command, Stdio};
516 /// Command::new("ls")
517 /// .stdin(Stdio::null())
519 /// .expect("ls command failed to start");
521 #[stable(feature = "process", since = "1.0.0")]
522 pub fn stdin(&mut self, cfg
: Stdio
) -> &mut Command
{
523 self.inner
.stdin(cfg
.0);
527 /// Configuration for the child process's stdout handle (file descriptor 1).
534 /// use std::process::{Command, Stdio};
536 /// Command::new("ls")
537 /// .stdout(Stdio::null())
539 /// .expect("ls command failed to start");
541 #[stable(feature = "process", since = "1.0.0")]
542 pub fn stdout(&mut self, cfg
: Stdio
) -> &mut Command
{
543 self.inner
.stdout(cfg
.0);
547 /// Configuration for the child process's stderr handle (file descriptor 2).
554 /// use std::process::{Command, Stdio};
556 /// Command::new("ls")
557 /// .stderr(Stdio::null())
559 /// .expect("ls command failed to start");
561 #[stable(feature = "process", since = "1.0.0")]
562 pub fn stderr(&mut self, cfg
: Stdio
) -> &mut Command
{
563 self.inner
.stderr(cfg
.0);
567 /// Executes the command as a child process, returning a handle to it.
569 /// By default, stdin, stdout and stderr are inherited from the parent.
576 /// use std::process::Command;
578 /// Command::new("ls")
580 /// .expect("ls command failed to start");
582 #[stable(feature = "process", since = "1.0.0")]
583 pub fn spawn(&mut self) -> io
::Result
<Child
> {
584 self.inner
.spawn(imp
::Stdio
::Inherit
, true).map(Child
::from_inner
)
587 /// Executes the command as a child process, waiting for it to finish and
588 /// collecting all of its output.
590 /// By default, stdin, stdout and stderr are captured (and used to
591 /// provide the resulting output).
596 /// use std::process::Command;
597 /// let output = Command::new("/bin/cat")
600 /// .expect("failed to execute process");
602 /// println!("status: {}", output.status);
603 /// println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
604 /// println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
606 /// assert!(output.status.success());
608 #[stable(feature = "process", since = "1.0.0")]
609 pub fn output(&mut self) -> io
::Result
<Output
> {
610 self.inner
.spawn(imp
::Stdio
::MakePipe
, false).map(Child
::from_inner
)
611 .and_then(|p
| p
.wait_with_output())
614 /// Executes a command as a child process, waiting for it to finish and
615 /// collecting its exit status.
617 /// By default, stdin, stdout and stderr are inherited from the parent.
622 /// use std::process::Command;
624 /// let status = Command::new("/bin/cat")
627 /// .expect("failed to execute process");
629 /// println!("process exited with: {}", status);
631 /// assert!(status.success());
633 #[stable(feature = "process", since = "1.0.0")]
634 pub fn status(&mut self) -> io
::Result
<ExitStatus
> {
635 self.inner
.spawn(imp
::Stdio
::Inherit
, true).map(Child
::from_inner
)
636 .and_then(|mut p
| p
.wait())
640 #[stable(feature = "rust1", since = "1.0.0")]
641 impl fmt
::Debug
for Command
{
642 /// Format the program and arguments of a Command for display. Any
643 /// non-utf8 data is lossily converted using the utf8 replacement
645 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
650 impl AsInner
<imp
::Command
> for Command
{
651 fn as_inner(&self) -> &imp
::Command { &self.inner }
654 impl AsInnerMut
<imp
::Command
> for Command
{
655 fn as_inner_mut(&mut self) -> &mut imp
::Command { &mut self.inner }
658 /// The output of a finished process.
659 #[derive(PartialEq, Eq, Clone)]
660 #[stable(feature = "process", since = "1.0.0")]
662 /// The status (exit code) of the process.
663 #[stable(feature = "process", since = "1.0.0")]
664 pub status
: ExitStatus
,
665 /// The data that the process wrote to stdout.
666 #[stable(feature = "process", since = "1.0.0")]
668 /// The data that the process wrote to stderr.
669 #[stable(feature = "process", since = "1.0.0")]
673 // If either stderr or stdout are valid utf8 strings it prints the valid
674 // strings, otherwise it prints the byte sequence instead
675 #[stable(feature = "process_output_debug", since = "1.7.0")]
676 impl fmt
::Debug
for Output
{
677 fn fmt(&self, fmt
: &mut fmt
::Formatter
) -> fmt
::Result
{
679 let stdout_utf8
= str::from_utf8(&self.stdout
);
680 let stdout_debug
: &fmt
::Debug
= match stdout_utf8
{
682 Err(_
) => &self.stdout
685 let stderr_utf8
= str::from_utf8(&self.stderr
);
686 let stderr_debug
: &fmt
::Debug
= match stderr_utf8
{
688 Err(_
) => &self.stderr
691 fmt
.debug_struct("Output")
692 .field("status", &self.status
)
693 .field("stdout", stdout_debug
)
694 .field("stderr", stderr_debug
)
699 /// Describes what to do with a standard I/O stream for a child process.
700 #[stable(feature = "process", since = "1.0.0")]
701 pub struct Stdio(imp
::Stdio
);
704 /// A new pipe should be arranged to connect the parent and child processes.
705 #[stable(feature = "process", since = "1.0.0")]
706 pub fn piped() -> Stdio { Stdio(imp::Stdio::MakePipe) }
708 /// The child inherits from the corresponding parent descriptor.
709 #[stable(feature = "process", since = "1.0.0")]
710 pub fn inherit() -> Stdio { Stdio(imp::Stdio::Inherit) }
712 /// This stream will be ignored. This is the equivalent of attaching the
713 /// stream to `/dev/null`
714 #[stable(feature = "process", since = "1.0.0")]
715 pub fn null() -> Stdio { Stdio(imp::Stdio::Null) }
718 impl FromInner
<imp
::Stdio
> for Stdio
{
719 fn from_inner(inner
: imp
::Stdio
) -> Stdio
{
724 #[stable(feature = "std_debug", since = "1.16.0")]
725 impl fmt
::Debug
for Stdio
{
726 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
727 f
.pad("Stdio { .. }")
731 /// Describes the result of a process after it has terminated.
732 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
733 #[stable(feature = "process", since = "1.0.0")]
734 pub struct ExitStatus(imp
::ExitStatus
);
737 /// Was termination successful? Signal termination not considered a success,
738 /// and success is defined as a zero exit status.
743 /// use std::process::Command;
745 /// let status = Command::new("mkdir")
748 /// .expect("failed to execute mkdir");
750 /// if status.success() {
751 /// println!("'projects/' directory created");
753 /// println!("failed to create 'projects/' directory");
756 #[stable(feature = "process", since = "1.0.0")]
757 pub fn success(&self) -> bool
{
761 /// Returns the exit code of the process, if any.
763 /// On Unix, this will return `None` if the process was terminated
764 /// by a signal; `std::os::unix` provides an extension trait for
765 /// extracting the signal and other details from the `ExitStatus`.
766 #[stable(feature = "process", since = "1.0.0")]
767 pub fn code(&self) -> Option
<i32> {
772 impl AsInner
<imp
::ExitStatus
> for ExitStatus
{
773 fn as_inner(&self) -> &imp
::ExitStatus { &self.0 }
776 impl FromInner
<imp
::ExitStatus
> for ExitStatus
{
777 fn from_inner(s
: imp
::ExitStatus
) -> ExitStatus
{
782 #[stable(feature = "process", since = "1.0.0")]
783 impl fmt
::Display
for ExitStatus
{
784 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
790 /// Forces the child to exit. This is equivalent to sending a
791 /// SIGKILL on unix platforms.
798 /// use std::process::Command;
800 /// let mut command = Command::new("yes");
801 /// if let Ok(mut child) = command.spawn() {
802 /// child.kill().expect("command wasn't running");
804 /// println!("yes command didn't start");
807 #[stable(feature = "process", since = "1.0.0")]
808 pub fn kill(&mut self) -> io
::Result
<()> {
812 /// Returns the OS-assigned process identifier associated with this child.
819 /// use std::process::Command;
821 /// let mut command = Command::new("ls");
822 /// if let Ok(child) = command.spawn() {
823 /// println!("Child's id is {}", child.id());
825 /// println!("ls command didn't start");
828 #[stable(feature = "process_id", since = "1.3.0")]
829 pub fn id(&self) -> u32 {
833 /// Waits for the child to exit completely, returning the status that it
834 /// exited with. This function will continue to have the same return value
835 /// after it has been called at least once.
837 /// The stdin handle to the child process, if any, will be closed
838 /// before waiting. This helps avoid deadlock: it ensures that the
839 /// child does not block waiting for input from the parent, while
840 /// the parent waits for the child to exit.
847 /// use std::process::Command;
849 /// let mut command = Command::new("ls");
850 /// if let Ok(mut child) = command.spawn() {
851 /// child.wait().expect("command wasn't running");
852 /// println!("Child has finished its execution!");
854 /// println!("ls command didn't start");
857 #[stable(feature = "process", since = "1.0.0")]
858 pub fn wait(&mut self) -> io
::Result
<ExitStatus
> {
859 drop(self.stdin
.take());
860 self.handle
.wait().map(ExitStatus
)
863 /// Attempts to collect the exit status of the child if it has already
866 /// This function will not block the calling thread and will only advisorily
867 /// check to see if the child process has exited or not. If the child has
868 /// exited then on Unix the process id is reaped. This function is
869 /// guaranteed to repeatedly return a successful exit status so long as the
870 /// child has already exited.
872 /// If the child has exited, then `Ok(Some(status))` is returned. If the
873 /// exit status is not available at this time then `Ok(None)` is returned.
874 /// If an error occurs, then that error is returned.
876 /// Note that unlike `wait`, this function will not attempt to drop stdin.
883 /// #![feature(process_try_wait)]
885 /// use std::process::Command;
887 /// let mut child = Command::new("ls").spawn().unwrap();
889 /// match child.try_wait() {
890 /// Ok(Some(status)) => println!("exited with: {}", status),
892 /// println!("status not ready yet, let's really wait");
893 /// let res = child.wait();
894 /// println!("result: {:?}", res);
896 /// Err(e) => println!("error attempting to wait: {}", e),
899 #[unstable(feature = "process_try_wait", issue = "38903")]
900 pub fn try_wait(&mut self) -> io
::Result
<Option
<ExitStatus
>> {
901 Ok(self.handle
.try_wait()?
.map(ExitStatus
))
904 /// Simultaneously waits for the child to exit and collect all remaining
905 /// output on the stdout/stderr handles, returning an `Output`
908 /// The stdin handle to the child process, if any, will be closed
909 /// before waiting. This helps avoid deadlock: it ensures that the
910 /// child does not block waiting for input from the parent, while
911 /// the parent waits for the child to exit.
913 /// By default, stdin, stdout and stderr are inherited from the parent.
914 /// In order to capture the output into this `Result<Output>` it is
915 /// necessary to create new pipes between parent and child. Use
916 /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively.
921 /// use std::process::{Command, Stdio};
923 /// let child = Command::new("/bin/cat")
925 /// .stdout(Stdio::piped())
927 /// .expect("failed to execute child");
929 /// let output = child
930 /// .wait_with_output()
931 /// .expect("failed to wait on child");
933 /// assert!(output.status.success());
936 #[stable(feature = "process", since = "1.0.0")]
937 pub fn wait_with_output(mut self) -> io
::Result
<Output
> {
938 drop(self.stdin
.take());
940 let (mut stdout
, mut stderr
) = (Vec
::new(), Vec
::new());
941 match (self.stdout
.take(), self.stderr
.take()) {
943 (Some(mut out
), None
) => {
944 let res
= out
.read_to_end(&mut stdout
);
947 (None
, Some(mut err
)) => {
948 let res
= err
.read_to_end(&mut stderr
);
951 (Some(out
), Some(err
)) => {
952 let res
= read2(out
.inner
, &mut stdout
, err
.inner
, &mut stderr
);
957 let status
= self.wait()?
;
966 /// Terminates the current process with the specified exit code.
968 /// This function will never return and will immediately terminate the current
969 /// process. The exit code is passed through to the underlying OS and will be
970 /// available for consumption by another process.
972 /// Note that because this function never returns, and that it terminates the
973 /// process, no destructors on the current stack or any other thread's stack
974 /// will be run. If a clean shutdown is needed it is recommended to only call
975 /// this function at a known point where there are no more destructors left
978 /// ## Platform-specific behavior
980 /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
981 /// will be visible to a parent process inspecting the exit code. On most
982 /// Unix-like platforms, only the eight least-significant bits are considered.
986 /// Due to this function’s behavior regarding destructors, a conventional way
987 /// to use the function is to extract the actual computation to another
988 /// function and compute the exit code from its return value:
991 /// use std::io::{self, Write};
993 /// fn run_app() -> Result<(), ()> {
994 /// // Application logic here
999 /// ::std::process::exit(match run_app() {
1002 /// writeln!(io::stderr(), "error: {:?}", err).unwrap();
1009 /// Due to [platform-specific behavior], the exit code for this example will be
1010 /// `0` on Linux, but `256` on Windows:
1013 /// use std::process;
1015 /// process::exit(0x0f00);
1018 /// [platform-specific behavior]: #platform-specific-behavior
1019 #[stable(feature = "rust1", since = "1.0.0")]
1020 pub fn exit(code
: i32) -> ! {
1021 ::sys_common
::cleanup();
1022 ::sys
::os
::exit(code
)
1025 /// Terminates the process in an abnormal fashion.
1027 /// The function will never return and will immediately terminate the current
1028 /// process in a platform specific "abnormal" manner.
1030 /// Note that because this function never returns, and that it terminates the
1031 /// process, no destructors on the current stack or any other thread's stack
1032 /// will be run. If a clean shutdown is needed it is recommended to only call
1033 /// this function at a known point where there are no more destructors left
1035 #[stable(feature = "process_abort", since = "1.17.0")]
1036 pub fn abort() -> ! {
1037 unsafe { ::sys::abort_internal() }
;
1040 #[cfg(all(test, not(target_os = "emscripten")))]
1046 use super::{Command, Output, Stdio}
;
1048 // FIXME(#10380) these tests should not all be ignored on android.
1051 #[cfg_attr(target_os = "android", ignore)]
1053 let p
= if cfg
!(target_os
= "windows") {
1054 Command
::new("cmd").args(&["/C", "exit 0"]).spawn()
1056 Command
::new("true").spawn()
1059 let mut p
= p
.unwrap();
1060 assert
!(p
.wait().unwrap().success());
1064 #[cfg_attr(target_os = "android", ignore)]
1065 fn smoke_failure() {
1066 match Command
::new("if-this-is-a-binary-then-the-world-has-ended").spawn() {
1073 #[cfg_attr(target_os = "android", ignore)]
1074 fn exit_reported_right() {
1075 let p
= if cfg
!(target_os
= "windows") {
1076 Command
::new("cmd").args(&["/C", "exit 1"]).spawn()
1078 Command
::new("false").spawn()
1081 let mut p
= p
.unwrap();
1082 assert
!(p
.wait().unwrap().code() == Some(1));
1088 #[cfg_attr(target_os = "android", ignore)]
1089 fn signal_reported_right() {
1090 use os
::unix
::process
::ExitStatusExt
;
1092 let mut p
= Command
::new("/bin/sh")
1093 .arg("-c").arg("read a")
1094 .stdin(Stdio
::piped())
1097 match p
.wait().unwrap().signal() {
1099 result
=> panic
!("not terminated by signal 9 (instead, {:?})",
1104 pub fn run_output(mut cmd
: Command
) -> String
{
1105 let p
= cmd
.spawn();
1107 let mut p
= p
.unwrap();
1108 assert
!(p
.stdout
.is_some());
1109 let mut ret
= String
::new();
1110 p
.stdout
.as_mut().unwrap().read_to_string(&mut ret
).unwrap();
1111 assert
!(p
.wait().unwrap().success());
1116 #[cfg_attr(target_os = "android", ignore)]
1118 if cfg
!(target_os
= "windows") {
1119 let mut cmd
= Command
::new("cmd");
1120 cmd
.args(&["/C", "echo foobar"]).stdout(Stdio
::piped());
1121 assert_eq
!(run_output(cmd
), "foobar\r\n");
1123 let mut cmd
= Command
::new("echo");
1124 cmd
.arg("foobar").stdout(Stdio
::piped());
1125 assert_eq
!(run_output(cmd
), "foobar\n");
1130 #[cfg_attr(any(windows, target_os = "android"), ignore)]
1131 fn set_current_dir_works() {
1132 let mut cmd
= Command
::new("/bin/sh");
1133 cmd
.arg("-c").arg("pwd")
1135 .stdout(Stdio
::piped());
1136 assert_eq
!(run_output(cmd
), "/\n");
1140 #[cfg_attr(any(windows, target_os = "android"), ignore)]
1142 let mut p
= Command
::new("/bin/sh")
1143 .arg("-c").arg("read line; echo $line")
1144 .stdin(Stdio
::piped())
1145 .stdout(Stdio
::piped())
1147 p
.stdin
.as_mut().unwrap().write("foobar".as_bytes()).unwrap();
1148 drop(p
.stdin
.take());
1149 let mut out
= String
::new();
1150 p
.stdout
.as_mut().unwrap().read_to_string(&mut out
).unwrap();
1151 assert
!(p
.wait().unwrap().success());
1152 assert_eq
!(out
, "foobar\n");
1157 #[cfg_attr(target_os = "android", ignore)]
1160 use os
::unix
::prelude
::*;
1162 let mut p
= Command
::new("/bin/sh")
1163 .arg("-c").arg("true")
1164 .uid(unsafe { libc::getuid() }
)
1165 .gid(unsafe { libc::getgid() }
)
1167 assert
!(p
.wait().unwrap().success());
1171 #[cfg_attr(target_os = "android", ignore)]
1173 fn uid_to_root_fails() {
1174 use os
::unix
::prelude
::*;
1177 // if we're already root, this isn't a valid test. Most of the bots run
1178 // as non-root though (android is an exception).
1179 if unsafe { libc::getuid() == 0 } { return }
1180 assert
!(Command
::new("/bin/ls").uid(0).gid(0).spawn().is_err());
1184 #[cfg_attr(target_os = "android", ignore)]
1185 fn test_process_status() {
1186 let mut status
= if cfg
!(target_os
= "windows") {
1187 Command
::new("cmd").args(&["/C", "exit 1"]).status().unwrap()
1189 Command
::new("false").status().unwrap()
1191 assert
!(status
.code() == Some(1));
1193 status
= if cfg
!(target_os
= "windows") {
1194 Command
::new("cmd").args(&["/C", "exit 0"]).status().unwrap()
1196 Command
::new("true").status().unwrap()
1198 assert
!(status
.success());
1202 fn test_process_output_fail_to_start() {
1203 match Command
::new("/no-binary-by-this-name-should-exist").output() {
1204 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::NotFound
),
1210 #[cfg_attr(target_os = "android", ignore)]
1211 fn test_process_output_output() {
1212 let Output {status, stdout, stderr}
1213 = if cfg
!(target_os
= "windows") {
1214 Command
::new("cmd").args(&["/C", "echo hello"]).output().unwrap()
1216 Command
::new("echo").arg("hello").output().unwrap()
1218 let output_str
= str::from_utf8(&stdout
).unwrap();
1220 assert
!(status
.success());
1221 assert_eq
!(output_str
.trim().to_string(), "hello");
1222 assert_eq
!(stderr
, Vec
::new());
1226 #[cfg_attr(target_os = "android", ignore)]
1227 fn test_process_output_error() {
1228 let Output {status, stdout, stderr}
1229 = if cfg
!(target_os
= "windows") {
1230 Command
::new("cmd").args(&["/C", "mkdir ."]).output().unwrap()
1232 Command
::new("mkdir").arg(".").output().unwrap()
1235 assert
!(status
.code() == Some(1));
1236 assert_eq
!(stdout
, Vec
::new());
1237 assert
!(!stderr
.is_empty());
1241 #[cfg_attr(target_os = "android", ignore)]
1242 fn test_finish_once() {
1243 let mut prog
= if cfg
!(target_os
= "windows") {
1244 Command
::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1246 Command
::new("false").spawn().unwrap()
1248 assert
!(prog
.wait().unwrap().code() == Some(1));
1252 #[cfg_attr(target_os = "android", ignore)]
1253 fn test_finish_twice() {
1254 let mut prog
= if cfg
!(target_os
= "windows") {
1255 Command
::new("cmd").args(&["/C", "exit 1"]).spawn().unwrap()
1257 Command
::new("false").spawn().unwrap()
1259 assert
!(prog
.wait().unwrap().code() == Some(1));
1260 assert
!(prog
.wait().unwrap().code() == Some(1));
1264 #[cfg_attr(target_os = "android", ignore)]
1265 fn test_wait_with_output_once() {
1266 let prog
= if cfg
!(target_os
= "windows") {
1267 Command
::new("cmd").args(&["/C", "echo hello"]).stdout(Stdio
::piped()).spawn().unwrap()
1269 Command
::new("echo").arg("hello").stdout(Stdio
::piped()).spawn().unwrap()
1272 let Output {status, stdout, stderr}
= prog
.wait_with_output().unwrap();
1273 let output_str
= str::from_utf8(&stdout
).unwrap();
1275 assert
!(status
.success());
1276 assert_eq
!(output_str
.trim().to_string(), "hello");
1277 assert_eq
!(stderr
, Vec
::new());
1280 #[cfg(all(unix, not(target_os="android")))]
1281 pub fn env_cmd() -> Command
{
1284 #[cfg(target_os="android")]
1285 pub fn env_cmd() -> Command
{
1286 let mut cmd
= Command
::new("/system/bin/sh");
1287 cmd
.arg("-c").arg("set");
1292 pub fn env_cmd() -> Command
{
1293 let mut cmd
= Command
::new("cmd");
1294 cmd
.arg("/c").arg("set");
1299 fn test_inherit_env() {
1302 let result
= env_cmd().output().unwrap();
1303 let output
= String
::from_utf8(result
.stdout
).unwrap();
1305 for (ref k
, ref v
) in env
::vars() {
1306 // don't check android RANDOM variables
1307 if cfg
!(target_os
= "android") && *k
== "RANDOM" {
1311 // Windows has hidden environment variables whose names start with
1312 // equals signs (`=`). Those do not show up in the output of the
1314 assert
!((cfg
!(windows
) && k
.starts_with("=")) ||
1315 k
.starts_with("DYLD") ||
1316 output
.contains(&format
!("{}={}", *k
, *v
)) ||
1317 output
.contains(&format
!("{}='{}'", *k
, *v
)),
1318 "output doesn't contain `{}={}`\n{}",
1324 fn test_override_env() {
1327 // In some build environments (such as chrooted Nix builds), `env` can
1328 // only be found in the explicitly-provided PATH env variable, not in
1329 // default places such as /bin or /usr/bin. So we need to pass through
1330 // PATH to our sub-process.
1331 let mut cmd
= env_cmd();
1332 cmd
.env_clear().env("RUN_TEST_NEW_ENV", "123");
1333 if let Some(p
) = env
::var_os("PATH") {
1334 cmd
.env("PATH", &p
);
1336 let result
= cmd
.output().unwrap();
1337 let output
= String
::from_utf8_lossy(&result
.stdout
).to_string();
1339 assert
!(output
.contains("RUN_TEST_NEW_ENV=123"),
1340 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output
);
1344 fn test_add_to_env() {
1345 let result
= env_cmd().env("RUN_TEST_NEW_ENV", "123").output().unwrap();
1346 let output
= String
::from_utf8_lossy(&result
.stdout
).to_string();
1348 assert
!(output
.contains("RUN_TEST_NEW_ENV=123"),
1349 "didn't find RUN_TEST_NEW_ENV inside of:\n\n{}", output
);
1352 // Regression tests for #30858.
1354 fn test_interior_nul_in_progname_is_error() {
1355 match Command
::new("has-some-\0\0s-inside").spawn() {
1356 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1362 fn test_interior_nul_in_arg_is_error() {
1363 match Command
::new("echo").arg("has-some-\0\0s-inside").spawn() {
1364 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1370 fn test_interior_nul_in_args_is_error() {
1371 match Command
::new("echo").args(&["has-some-\0\0s-inside"]).spawn() {
1372 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1378 fn test_interior_nul_in_current_dir_is_error() {
1379 match Command
::new("echo").current_dir("has-some-\0\0s-inside").spawn() {
1380 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1385 // Regression tests for #30862.
1387 fn test_interior_nul_in_env_key_is_error() {
1388 match env_cmd().env("has-some-\0\0s-inside", "value").spawn() {
1389 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1395 fn test_interior_nul_in_env_value_is_error() {
1396 match env_cmd().env("key", "has-some-\0\0s-inside").spawn() {
1397 Err(e
) => assert_eq
!(e
.kind(), ErrorKind
::InvalidInput
),
1402 /// Test that process creation flags work by debugging a process.
1403 /// Other creation flags make it hard or impossible to detect
1404 /// behavioral changes in the process.
1407 fn test_creation_flags() {
1408 use os
::windows
::process
::CommandExt
;
1409 use sys
::c
::{BOOL, DWORD, INFINITE}
;
1411 struct DEBUG_EVENT
{
1412 pub event_code
: DWORD
,
1413 pub process_id
: DWORD
,
1414 pub thread_id
: DWORD
,
1415 // This is a union in the real struct, but we don't
1416 // need this data for the purposes of this test.
1417 pub _junk
: [u8; 164],
1421 fn WaitForDebugEvent(lpDebugEvent
: *mut DEBUG_EVENT
, dwMilliseconds
: DWORD
) -> BOOL
;
1422 fn ContinueDebugEvent(dwProcessId
: DWORD
, dwThreadId
: DWORD
,
1423 dwContinueStatus
: DWORD
) -> BOOL
;
1426 const DEBUG_PROCESS
: DWORD
= 1;
1427 const EXIT_PROCESS_DEBUG_EVENT
: DWORD
= 5;
1428 const DBG_EXCEPTION_NOT_HANDLED
: DWORD
= 0x80010001;
1430 let mut child
= Command
::new("cmd")
1431 .creation_flags(DEBUG_PROCESS
)
1432 .stdin(Stdio
::piped()).spawn().unwrap();
1433 child
.stdin
.take().unwrap().write_all(b
"exit\r\n").unwrap();
1435 let mut event
= DEBUG_EVENT
{
1442 if unsafe { WaitForDebugEvent(&mut event as *mut DEBUG_EVENT, INFINITE) }
== 0 {
1443 panic
!("WaitForDebugEvent failed!");
1447 if event
.event_code
== EXIT_PROCESS_DEBUG_EVENT
{
1451 if unsafe { ContinueDebugEvent(event
.process_id
,
1453 DBG_EXCEPTION_NOT_HANDLED
) } == 0 {
1454 panic
!("ContinueDebugEvent failed!");
1457 assert
!(events
> 0);