1 | //! A module for working with processes. |
2 | //! |
3 | //! This module is mostly concerned with spawning and interacting with child |
4 | //! processes, but it also provides [`abort`] and [`exit`] for terminating the |
5 | //! current process. |
6 | //! |
7 | //! # Spawning a process |
8 | //! |
9 | //! The [`Command`] struct is used to configure and spawn processes: |
10 | //! |
11 | //! ```no_run |
12 | //! use std::process::Command; |
13 | //! |
14 | //! let output = Command::new("echo" ) |
15 | //! .arg("Hello world" ) |
16 | //! .output() |
17 | //! .expect("Failed to execute command" ); |
18 | //! |
19 | //! assert_eq!(b"Hello world \n" , output.stdout.as_slice()); |
20 | //! ``` |
21 | //! |
22 | //! Several methods on [`Command`], such as [`spawn`] or [`output`], can be used |
23 | //! to spawn a process. In particular, [`output`] spawns the child process and |
24 | //! waits until the process terminates, while [`spawn`] will return a [`Child`] |
25 | //! that represents the spawned child process. |
26 | //! |
27 | //! # Handling I/O |
28 | //! |
29 | //! The [`stdout`], [`stdin`], and [`stderr`] of a child process can be |
30 | //! configured by passing an [`Stdio`] to the corresponding method on |
31 | //! [`Command`]. Once spawned, they can be accessed from the [`Child`]. For |
32 | //! example, piping output from one command into another command can be done |
33 | //! like so: |
34 | //! |
35 | //! ```no_run |
36 | //! use std::process::{Command, Stdio}; |
37 | //! |
38 | //! // stdout must be configured with `Stdio::piped` in order to use |
39 | //! // `echo_child.stdout` |
40 | //! let echo_child = Command::new("echo" ) |
41 | //! .arg("Oh no, a tpyo!" ) |
42 | //! .stdout(Stdio::piped()) |
43 | //! .spawn() |
44 | //! .expect("Failed to start echo process" ); |
45 | //! |
46 | //! // Note that `echo_child` is moved here, but we won't be needing |
47 | //! // `echo_child` anymore |
48 | //! let echo_out = echo_child.stdout.expect("Failed to open echo stdout" ); |
49 | //! |
50 | //! let mut sed_child = Command::new("sed" ) |
51 | //! .arg("s/tpyo/typo/" ) |
52 | //! .stdin(Stdio::from(echo_out)) |
53 | //! .stdout(Stdio::piped()) |
54 | //! .spawn() |
55 | //! .expect("Failed to start sed process" ); |
56 | //! |
57 | //! let output = sed_child.wait_with_output().expect("Failed to wait on sed" ); |
58 | //! assert_eq!(b"Oh no, a typo! \n" , output.stdout.as_slice()); |
59 | //! ``` |
60 | //! |
61 | //! Note that [`ChildStderr`] and [`ChildStdout`] implement [`Read`] and |
62 | //! [`ChildStdin`] implements [`Write`]: |
63 | //! |
64 | //! ```no_run |
65 | //! use std::process::{Command, Stdio}; |
66 | //! use std::io::Write; |
67 | //! |
68 | //! let mut child = Command::new("/bin/cat" ) |
69 | //! .stdin(Stdio::piped()) |
70 | //! .stdout(Stdio::piped()) |
71 | //! .spawn() |
72 | //! .expect("failed to execute child" ); |
73 | //! |
74 | //! // If the child process fills its stdout buffer, it may end up |
75 | //! // waiting until the parent reads the stdout, and not be able to |
76 | //! // read stdin in the meantime, causing a deadlock. |
77 | //! // Writing from another thread ensures that stdout is being read |
78 | //! // at the same time, avoiding the problem. |
79 | //! let mut stdin = child.stdin.take().expect("failed to get stdin" ); |
80 | //! std::thread::spawn(move || { |
81 | //! stdin.write_all(b"test" ).expect("failed to write to stdin" ); |
82 | //! }); |
83 | //! |
84 | //! let output = child |
85 | //! .wait_with_output() |
86 | //! .expect("failed to wait on child" ); |
87 | //! |
88 | //! assert_eq!(b"test" , output.stdout.as_slice()); |
89 | //! ``` |
90 | //! |
91 | //! # Windows argument splitting |
92 | //! |
93 | //! On Unix systems arguments are passed to a new process as an array of strings, |
94 | //! but on Windows arguments are passed as a single commandline string and it is |
95 | //! up to the child process to parse it into an array. Therefore the parent and |
96 | //! child processes must agree on how the commandline string is encoded. |
97 | //! |
98 | //! Most programs use the standard C run-time `argv`, which in practice results |
99 | //! in consistent argument handling. However, some programs have their own way of |
100 | //! parsing the commandline string. In these cases using [`arg`] or [`args`] may |
101 | //! result in the child process seeing a different array of arguments than the |
102 | //! parent process intended. |
103 | //! |
104 | //! Two ways of mitigating this are: |
105 | //! |
106 | //! * Validate untrusted input so that only a safe subset is allowed. |
107 | //! * Use [`raw_arg`] to build a custom commandline. This bypasses the escaping |
108 | //! rules used by [`arg`] so should be used with due caution. |
109 | //! |
110 | //! `cmd.exe` and `.bat` files use non-standard argument parsing and are especially |
111 | //! vulnerable to malicious input as they may be used to run arbitrary shell |
112 | //! commands. Untrusted arguments should be restricted as much as possible. |
113 | //! For examples on handling this see [`raw_arg`]. |
114 | //! |
115 | //! ### Batch file special handling |
116 | //! |
117 | //! On Windows, `Command` uses the Windows API function [`CreateProcessW`] to |
118 | //! spawn new processes. An undocumented feature of this function is that |
119 | //! when given a `.bat` file as the application to run, it will automatically |
120 | //! convert that into running `cmd.exe /c` with the batch file as the next argument. |
121 | //! |
122 | //! For historical reasons Rust currently preserves this behavior when using |
123 | //! [`Command::new`], and escapes the arguments according to `cmd.exe` rules. |
124 | //! Due to the complexity of `cmd.exe` argument handling, it might not be |
125 | //! possible to safely escape some special characters, and using them will result |
126 | //! in an error being returned at process spawn. The set of unescapeable |
127 | //! special characters might change between releases. |
128 | //! |
129 | //! Also note that running batch scripts in this way may be removed in the |
130 | //! future and so should not be relied upon. |
131 | //! |
132 | //! [`spawn`]: Command::spawn |
133 | //! [`output`]: Command::output |
134 | //! |
135 | //! [`stdout`]: Command::stdout |
136 | //! [`stdin`]: Command::stdin |
137 | //! [`stderr`]: Command::stderr |
138 | //! |
139 | //! [`Write`]: io::Write |
140 | //! [`Read`]: io::Read |
141 | //! |
142 | //! [`arg`]: Command::arg |
143 | //! [`args`]: Command::args |
144 | //! [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg |
145 | //! |
146 | //! [`CreateProcessW`]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw |
147 | |
148 | #![stable (feature = "process" , since = "1.0.0" )] |
149 | #![deny (unsafe_op_in_unsafe_fn)] |
150 | |
151 | #[cfg (all( |
152 | test, |
153 | not(any( |
154 | target_os = "emscripten" , |
155 | target_os = "wasi" , |
156 | target_env = "sgx" , |
157 | target_os = "xous" , |
158 | target_os = "trusty" , |
159 | )) |
160 | ))] |
161 | mod tests; |
162 | |
163 | use crate::convert::Infallible; |
164 | use crate::ffi::OsStr; |
165 | use crate::io::prelude::*; |
166 | use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut}; |
167 | use crate::num::NonZero; |
168 | use crate::path::Path; |
169 | use crate::sys::pipe::{AnonPipe, read2}; |
170 | use crate::sys::process as imp; |
171 | use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner}; |
172 | use crate::{fmt, fs, str}; |
173 | |
174 | /// Representation of a running or exited child process. |
175 | /// |
176 | /// This structure is used to represent and manage child processes. A child |
177 | /// process is created via the [`Command`] struct, which configures the |
178 | /// spawning process and can itself be constructed using a builder-style |
179 | /// interface. |
180 | /// |
181 | /// There is no implementation of [`Drop`] for child processes, |
182 | /// so if you do not ensure the `Child` has exited then it will continue to |
183 | /// run, even after the `Child` handle to the child process has gone out of |
184 | /// scope. |
185 | /// |
186 | /// Calling [`wait`] (or other functions that wrap around it) will make |
187 | /// the parent process wait until the child has actually exited before |
188 | /// continuing. |
189 | /// |
190 | /// # Warning |
191 | /// |
192 | /// On some systems, calling [`wait`] or similar is necessary for the OS to |
193 | /// release resources. A process that terminated but has not been waited on is |
194 | /// still around as a "zombie". Leaving too many zombies around may exhaust |
195 | /// global resources (for example process IDs). |
196 | /// |
197 | /// The standard library does *not* automatically wait on child processes (not |
198 | /// even if the `Child` is dropped), it is up to the application developer to do |
199 | /// so. As a consequence, dropping `Child` handles without waiting on them first |
200 | /// is not recommended in long-running applications. |
201 | /// |
202 | /// # Examples |
203 | /// |
204 | /// ```should_panic |
205 | /// use std::process::Command; |
206 | /// |
207 | /// let mut child = Command::new("/bin/cat" ) |
208 | /// .arg("file.txt" ) |
209 | /// .spawn() |
210 | /// .expect("failed to execute child" ); |
211 | /// |
212 | /// let ecode = child.wait().expect("failed to wait on child" ); |
213 | /// |
214 | /// assert!(ecode.success()); |
215 | /// ``` |
216 | /// |
217 | /// [`wait`]: Child::wait |
218 | #[stable (feature = "process" , since = "1.0.0" )] |
219 | #[cfg_attr (not(test), rustc_diagnostic_item = "Child" )] |
220 | pub struct Child { |
221 | pub(crate) handle: imp::Process, |
222 | |
223 | /// The handle for writing to the child's standard input (stdin), if it |
224 | /// has been captured. You might find it helpful to do |
225 | /// |
226 | /// ```ignore (incomplete) |
227 | /// let stdin = child.stdin.take().expect("handle present" ); |
228 | /// ``` |
229 | /// |
230 | /// to avoid partially moving the `child` and thus blocking yourself from calling |
231 | /// functions on `child` while using `stdin`. |
232 | #[stable (feature = "process" , since = "1.0.0" )] |
233 | pub stdin: Option<ChildStdin>, |
234 | |
235 | /// The handle for reading from the child's standard output (stdout), if it |
236 | /// has been captured. You might find it helpful to do |
237 | /// |
238 | /// ```ignore (incomplete) |
239 | /// let stdout = child.stdout.take().expect("handle present" ); |
240 | /// ``` |
241 | /// |
242 | /// to avoid partially moving the `child` and thus blocking yourself from calling |
243 | /// functions on `child` while using `stdout`. |
244 | #[stable (feature = "process" , since = "1.0.0" )] |
245 | pub stdout: Option<ChildStdout>, |
246 | |
247 | /// The handle for reading from the child's standard error (stderr), if it |
248 | /// has been captured. You might find it helpful to do |
249 | /// |
250 | /// ```ignore (incomplete) |
251 | /// let stderr = child.stderr.take().expect("handle present" ); |
252 | /// ``` |
253 | /// |
254 | /// to avoid partially moving the `child` and thus blocking yourself from calling |
255 | /// functions on `child` while using `stderr`. |
256 | #[stable (feature = "process" , since = "1.0.0" )] |
257 | pub stderr: Option<ChildStderr>, |
258 | } |
259 | |
260 | /// Allows extension traits within `std`. |
261 | #[unstable (feature = "sealed" , issue = "none" )] |
262 | impl crate::sealed::Sealed for Child {} |
263 | |
264 | impl AsInner<imp::Process> for Child { |
265 | #[inline ] |
266 | fn as_inner(&self) -> &imp::Process { |
267 | &self.handle |
268 | } |
269 | } |
270 | |
271 | impl FromInner<(imp::Process, imp::StdioPipes)> for Child { |
272 | fn from_inner((handle: Process, io: StdioPipes): (imp::Process, imp::StdioPipes)) -> Child { |
273 | Child { |
274 | handle, |
275 | stdin: io.stdin.map(ChildStdin::from_inner), |
276 | stdout: io.stdout.map(ChildStdout::from_inner), |
277 | stderr: io.stderr.map(ChildStderr::from_inner), |
278 | } |
279 | } |
280 | } |
281 | |
282 | impl IntoInner<imp::Process> for Child { |
283 | fn into_inner(self) -> imp::Process { |
284 | self.handle |
285 | } |
286 | } |
287 | |
288 | #[stable (feature = "std_debug" , since = "1.16.0" )] |
289 | impl fmt::Debug for Child { |
290 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
291 | f&mut DebugStruct<'_, '_>.debug_struct("Child" ) |
292 | .field("stdin" , &self.stdin) |
293 | .field("stdout" , &self.stdout) |
294 | .field(name:"stderr" , &self.stderr) |
295 | .finish_non_exhaustive() |
296 | } |
297 | } |
298 | |
299 | /// A handle to a child process's standard input (stdin). |
300 | /// |
301 | /// This struct is used in the [`stdin`] field on [`Child`]. |
302 | /// |
303 | /// When an instance of `ChildStdin` is [dropped], the `ChildStdin`'s underlying |
304 | /// file handle will be closed. If the child process was blocked on input prior |
305 | /// to being dropped, it will become unblocked after dropping. |
306 | /// |
307 | /// [`stdin`]: Child::stdin |
308 | /// [dropped]: Drop |
309 | #[stable (feature = "process" , since = "1.0.0" )] |
310 | pub struct ChildStdin { |
311 | inner: AnonPipe, |
312 | } |
313 | |
314 | // In addition to the `impl`s here, `ChildStdin` also has `impl`s for |
315 | // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and |
316 | // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and |
317 | // `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and |
318 | // `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows. |
319 | |
320 | #[stable (feature = "process" , since = "1.0.0" )] |
321 | impl Write for ChildStdin { |
322 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
323 | (&*self).write(buf) |
324 | } |
325 | |
326 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
327 | (&*self).write_vectored(bufs) |
328 | } |
329 | |
330 | fn is_write_vectored(&self) -> bool { |
331 | io::Write::is_write_vectored(&&*self) |
332 | } |
333 | |
334 | #[inline ] |
335 | fn flush(&mut self) -> io::Result<()> { |
336 | (&*self).flush() |
337 | } |
338 | } |
339 | |
340 | #[stable (feature = "write_mt" , since = "1.48.0" )] |
341 | impl Write for &ChildStdin { |
342 | fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
343 | self.inner.write(buf) |
344 | } |
345 | |
346 | fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> { |
347 | self.inner.write_vectored(bufs) |
348 | } |
349 | |
350 | fn is_write_vectored(&self) -> bool { |
351 | self.inner.is_write_vectored() |
352 | } |
353 | |
354 | #[inline ] |
355 | fn flush(&mut self) -> io::Result<()> { |
356 | Ok(()) |
357 | } |
358 | } |
359 | |
360 | impl AsInner<AnonPipe> for ChildStdin { |
361 | #[inline ] |
362 | fn as_inner(&self) -> &AnonPipe { |
363 | &self.inner |
364 | } |
365 | } |
366 | |
367 | impl IntoInner<AnonPipe> for ChildStdin { |
368 | fn into_inner(self) -> AnonPipe { |
369 | self.inner |
370 | } |
371 | } |
372 | |
373 | impl FromInner<AnonPipe> for ChildStdin { |
374 | fn from_inner(pipe: AnonPipe) -> ChildStdin { |
375 | ChildStdin { inner: pipe } |
376 | } |
377 | } |
378 | |
379 | #[stable (feature = "std_debug" , since = "1.16.0" )] |
380 | impl fmt::Debug for ChildStdin { |
381 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
382 | f.debug_struct(name:"ChildStdin" ).finish_non_exhaustive() |
383 | } |
384 | } |
385 | |
386 | /// A handle to a child process's standard output (stdout). |
387 | /// |
388 | /// This struct is used in the [`stdout`] field on [`Child`]. |
389 | /// |
390 | /// When an instance of `ChildStdout` is [dropped], the `ChildStdout`'s |
391 | /// underlying file handle will be closed. |
392 | /// |
393 | /// [`stdout`]: Child::stdout |
394 | /// [dropped]: Drop |
395 | #[stable (feature = "process" , since = "1.0.0" )] |
396 | pub struct ChildStdout { |
397 | inner: AnonPipe, |
398 | } |
399 | |
400 | // In addition to the `impl`s here, `ChildStdout` also has `impl`s for |
401 | // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and |
402 | // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and |
403 | // `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and |
404 | // `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows. |
405 | |
406 | #[stable (feature = "process" , since = "1.0.0" )] |
407 | impl Read for ChildStdout { |
408 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
409 | self.inner.read(buf) |
410 | } |
411 | |
412 | fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { |
413 | self.inner.read_buf(buf) |
414 | } |
415 | |
416 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
417 | self.inner.read_vectored(bufs) |
418 | } |
419 | |
420 | #[inline ] |
421 | fn is_read_vectored(&self) -> bool { |
422 | self.inner.is_read_vectored() |
423 | } |
424 | |
425 | fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
426 | self.inner.read_to_end(buf) |
427 | } |
428 | } |
429 | |
430 | impl AsInner<AnonPipe> for ChildStdout { |
431 | #[inline ] |
432 | fn as_inner(&self) -> &AnonPipe { |
433 | &self.inner |
434 | } |
435 | } |
436 | |
437 | impl IntoInner<AnonPipe> for ChildStdout { |
438 | fn into_inner(self) -> AnonPipe { |
439 | self.inner |
440 | } |
441 | } |
442 | |
443 | impl FromInner<AnonPipe> for ChildStdout { |
444 | fn from_inner(pipe: AnonPipe) -> ChildStdout { |
445 | ChildStdout { inner: pipe } |
446 | } |
447 | } |
448 | |
449 | #[stable (feature = "std_debug" , since = "1.16.0" )] |
450 | impl fmt::Debug for ChildStdout { |
451 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
452 | f.debug_struct(name:"ChildStdout" ).finish_non_exhaustive() |
453 | } |
454 | } |
455 | |
456 | /// A handle to a child process's stderr. |
457 | /// |
458 | /// This struct is used in the [`stderr`] field on [`Child`]. |
459 | /// |
460 | /// When an instance of `ChildStderr` is [dropped], the `ChildStderr`'s |
461 | /// underlying file handle will be closed. |
462 | /// |
463 | /// [`stderr`]: Child::stderr |
464 | /// [dropped]: Drop |
465 | #[stable (feature = "process" , since = "1.0.0" )] |
466 | pub struct ChildStderr { |
467 | inner: AnonPipe, |
468 | } |
469 | |
470 | // In addition to the `impl`s here, `ChildStderr` also has `impl`s for |
471 | // `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and |
472 | // `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and |
473 | // `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and |
474 | // `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows. |
475 | |
476 | #[stable (feature = "process" , since = "1.0.0" )] |
477 | impl Read for ChildStderr { |
478 | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
479 | self.inner.read(buf) |
480 | } |
481 | |
482 | fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> io::Result<()> { |
483 | self.inner.read_buf(buf) |
484 | } |
485 | |
486 | fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> { |
487 | self.inner.read_vectored(bufs) |
488 | } |
489 | |
490 | #[inline ] |
491 | fn is_read_vectored(&self) -> bool { |
492 | self.inner.is_read_vectored() |
493 | } |
494 | |
495 | fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { |
496 | self.inner.read_to_end(buf) |
497 | } |
498 | } |
499 | |
500 | impl AsInner<AnonPipe> for ChildStderr { |
501 | #[inline ] |
502 | fn as_inner(&self) -> &AnonPipe { |
503 | &self.inner |
504 | } |
505 | } |
506 | |
507 | impl IntoInner<AnonPipe> for ChildStderr { |
508 | fn into_inner(self) -> AnonPipe { |
509 | self.inner |
510 | } |
511 | } |
512 | |
513 | impl FromInner<AnonPipe> for ChildStderr { |
514 | fn from_inner(pipe: AnonPipe) -> ChildStderr { |
515 | ChildStderr { inner: pipe } |
516 | } |
517 | } |
518 | |
519 | #[stable (feature = "std_debug" , since = "1.16.0" )] |
520 | impl fmt::Debug for ChildStderr { |
521 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
522 | f.debug_struct(name:"ChildStderr" ).finish_non_exhaustive() |
523 | } |
524 | } |
525 | |
526 | /// A process builder, providing fine-grained control |
527 | /// over how a new process should be spawned. |
528 | /// |
529 | /// A default configuration can be |
530 | /// generated using `Command::new(program)`, where `program` gives a path to the |
531 | /// program to be executed. Additional builder methods allow the configuration |
532 | /// to be changed (for example, by adding arguments) prior to spawning: |
533 | /// |
534 | /// ``` |
535 | /// use std::process::Command; |
536 | /// |
537 | /// let output = if cfg!(target_os = "windows" ) { |
538 | /// Command::new("cmd" ) |
539 | /// .args(["/C" , "echo hello" ]) |
540 | /// .output() |
541 | /// .expect("failed to execute process" ) |
542 | /// } else { |
543 | /// Command::new("sh" ) |
544 | /// .arg("-c" ) |
545 | /// .arg("echo hello" ) |
546 | /// .output() |
547 | /// .expect("failed to execute process" ) |
548 | /// }; |
549 | /// |
550 | /// let hello = output.stdout; |
551 | /// ``` |
552 | /// |
553 | /// `Command` can be reused to spawn multiple processes. The builder methods |
554 | /// change the command without needing to immediately spawn the process. |
555 | /// |
556 | /// ```no_run |
557 | /// use std::process::Command; |
558 | /// |
559 | /// let mut echo_hello = Command::new("sh" ); |
560 | /// echo_hello.arg("-c" ).arg("echo hello" ); |
561 | /// let hello_1 = echo_hello.output().expect("failed to execute process" ); |
562 | /// let hello_2 = echo_hello.output().expect("failed to execute process" ); |
563 | /// ``` |
564 | /// |
565 | /// Similarly, you can call builder methods after spawning a process and then |
566 | /// spawn a new process with the modified settings. |
567 | /// |
568 | /// ```no_run |
569 | /// use std::process::Command; |
570 | /// |
571 | /// let mut list_dir = Command::new("ls" ); |
572 | /// |
573 | /// // Execute `ls` in the current directory of the program. |
574 | /// list_dir.status().expect("process failed to execute" ); |
575 | /// |
576 | /// println!(); |
577 | /// |
578 | /// // Change `ls` to execute in the root directory. |
579 | /// list_dir.current_dir("/" ); |
580 | /// |
581 | /// // And then execute `ls` again but in the root directory. |
582 | /// list_dir.status().expect("process failed to execute" ); |
583 | /// ``` |
584 | #[stable (feature = "process" , since = "1.0.0" )] |
585 | #[cfg_attr (not(test), rustc_diagnostic_item = "Command" )] |
586 | pub struct Command { |
587 | inner: imp::Command, |
588 | } |
589 | |
590 | /// Allows extension traits within `std`. |
591 | #[unstable (feature = "sealed" , issue = "none" )] |
592 | impl crate::sealed::Sealed for Command {} |
593 | |
594 | impl Command { |
595 | /// Constructs a new `Command` for launching the program at |
596 | /// path `program`, with the following default configuration: |
597 | /// |
598 | /// * No arguments to the program |
599 | /// * Inherit the current process's environment |
600 | /// * Inherit the current process's working directory |
601 | /// * Inherit stdin/stdout/stderr for [`spawn`] or [`status`], but create pipes for [`output`] |
602 | /// |
603 | /// [`spawn`]: Self::spawn |
604 | /// [`status`]: Self::status |
605 | /// [`output`]: Self::output |
606 | /// |
607 | /// Builder methods are provided to change these defaults and |
608 | /// otherwise configure the process. |
609 | /// |
610 | /// If `program` is not an absolute path, the `PATH` will be searched in |
611 | /// an OS-defined way. |
612 | /// |
613 | /// The search path to be used may be controlled by setting the |
614 | /// `PATH` environment variable on the Command, |
615 | /// but this has some implementation limitations on Windows |
616 | /// (see issue #37519). |
617 | /// |
618 | /// # Platform-specific behavior |
619 | /// |
620 | /// Note on Windows: For executable files with the .exe extension, |
621 | /// it can be omitted when specifying the program for this Command. |
622 | /// However, if the file has a different extension, |
623 | /// a filename including the extension needs to be provided, |
624 | /// otherwise the file won't be found. |
625 | /// |
626 | /// # Examples |
627 | /// |
628 | /// ```no_run |
629 | /// use std::process::Command; |
630 | /// |
631 | /// Command::new("sh" ) |
632 | /// .spawn() |
633 | /// .expect("sh command failed to start" ); |
634 | /// ``` |
635 | /// |
636 | /// # Caveats |
637 | /// |
638 | /// [`Command::new`] is only intended to accept the path of the program. If you pass a program |
639 | /// path along with arguments like `Command::new("ls -l").spawn()`, it will try to search for |
640 | /// `ls -l` literally. The arguments need to be passed separately, such as via [`arg`] or |
641 | /// [`args`]. |
642 | /// |
643 | /// ```no_run |
644 | /// use std::process::Command; |
645 | /// |
646 | /// Command::new("ls" ) |
647 | /// .arg("-l" ) // arg passed separately |
648 | /// .spawn() |
649 | /// .expect("ls command failed to start" ); |
650 | /// ``` |
651 | /// |
652 | /// [`arg`]: Self::arg |
653 | /// [`args`]: Self::args |
654 | #[stable (feature = "process" , since = "1.0.0" )] |
655 | pub fn new<S: AsRef<OsStr>>(program: S) -> Command { |
656 | Command { inner: imp::Command::new(program.as_ref()) } |
657 | } |
658 | |
659 | /// Adds an argument to pass to the program. |
660 | /// |
661 | /// Only one argument can be passed per use. So instead of: |
662 | /// |
663 | /// ```no_run |
664 | /// # std::process::Command::new("sh" ) |
665 | /// .arg("-C /path/to/repo" ) |
666 | /// # ; |
667 | /// ``` |
668 | /// |
669 | /// usage would be: |
670 | /// |
671 | /// ```no_run |
672 | /// # std::process::Command::new("sh" ) |
673 | /// .arg("-C" ) |
674 | /// .arg("/path/to/repo" ) |
675 | /// # ; |
676 | /// ``` |
677 | /// |
678 | /// To pass multiple arguments see [`args`]. |
679 | /// |
680 | /// [`args`]: Command::args |
681 | /// |
682 | /// Note that the argument is not passed through a shell, but given |
683 | /// literally to the program. This means that shell syntax like quotes, |
684 | /// escaped characters, word splitting, glob patterns, variable substitution, |
685 | /// etc. have no effect. |
686 | /// |
687 | /// <div class="warning"> |
688 | /// |
689 | /// On Windows, use caution with untrusted inputs. Most applications use the |
690 | /// standard convention for decoding arguments passed to them. These are safe to |
691 | /// use with `arg`. However, some applications such as `cmd.exe` and `.bat` files |
692 | /// use a non-standard way of decoding arguments. They are therefore vulnerable |
693 | /// to malicious input. |
694 | /// |
695 | /// In the case of `cmd.exe` this is especially important because a malicious |
696 | /// argument can potentially run arbitrary shell commands. |
697 | /// |
698 | /// See [Windows argument splitting][windows-args] for more details |
699 | /// or [`raw_arg`] for manually implementing non-standard argument encoding. |
700 | /// |
701 | /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg |
702 | /// [windows-args]: crate::process#windows-argument-splitting |
703 | /// |
704 | /// </div> |
705 | /// |
706 | /// # Examples |
707 | /// |
708 | /// ```no_run |
709 | /// use std::process::Command; |
710 | /// |
711 | /// Command::new("ls" ) |
712 | /// .arg("-l" ) |
713 | /// .arg("-a" ) |
714 | /// .spawn() |
715 | /// .expect("ls command failed to start" ); |
716 | /// ``` |
717 | #[stable (feature = "process" , since = "1.0.0" )] |
718 | pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command { |
719 | self.inner.arg(arg.as_ref()); |
720 | self |
721 | } |
722 | |
723 | /// Adds multiple arguments to pass to the program. |
724 | /// |
725 | /// To pass a single argument see [`arg`]. |
726 | /// |
727 | /// [`arg`]: Command::arg |
728 | /// |
729 | /// Note that the arguments are not passed through a shell, but given |
730 | /// literally to the program. This means that shell syntax like quotes, |
731 | /// escaped characters, word splitting, glob patterns, variable substitution, etc. |
732 | /// have no effect. |
733 | /// |
734 | /// <div class="warning"> |
735 | /// |
736 | /// On Windows, use caution with untrusted inputs. Most applications use the |
737 | /// standard convention for decoding arguments passed to them. These are safe to |
738 | /// use with `arg`. However, some applications such as `cmd.exe` and `.bat` files |
739 | /// use a non-standard way of decoding arguments. They are therefore vulnerable |
740 | /// to malicious input. |
741 | /// |
742 | /// In the case of `cmd.exe` this is especially important because a malicious |
743 | /// argument can potentially run arbitrary shell commands. |
744 | /// |
745 | /// See [Windows argument splitting][windows-args] for more details |
746 | /// or [`raw_arg`] for manually implementing non-standard argument encoding. |
747 | /// |
748 | /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg |
749 | /// [windows-args]: crate::process#windows-argument-splitting |
750 | /// |
751 | /// </div> |
752 | /// |
753 | /// # Examples |
754 | /// |
755 | /// ```no_run |
756 | /// use std::process::Command; |
757 | /// |
758 | /// Command::new("ls" ) |
759 | /// .args(["-l" , "-a" ]) |
760 | /// .spawn() |
761 | /// .expect("ls command failed to start" ); |
762 | /// ``` |
763 | #[stable (feature = "process" , since = "1.0.0" )] |
764 | pub fn args<I, S>(&mut self, args: I) -> &mut Command |
765 | where |
766 | I: IntoIterator<Item = S>, |
767 | S: AsRef<OsStr>, |
768 | { |
769 | for arg in args { |
770 | self.arg(arg.as_ref()); |
771 | } |
772 | self |
773 | } |
774 | |
775 | /// Inserts or updates an explicit environment variable mapping. |
776 | /// |
777 | /// This method allows you to add an environment variable mapping to the spawned process or |
778 | /// overwrite a previously set value. You can use [`Command::envs`] to set multiple environment |
779 | /// variables simultaneously. |
780 | /// |
781 | /// Child processes will inherit environment variables from their parent process by default. |
782 | /// Environment variables explicitly set using [`Command::env`] take precedence over inherited |
783 | /// variables. You can disable environment variable inheritance entirely using |
784 | /// [`Command::env_clear`] or for a single key using [`Command::env_remove`]. |
785 | /// |
786 | /// Note that environment variable names are case-insensitive (but |
787 | /// case-preserving) on Windows and case-sensitive on all other platforms. |
788 | /// |
789 | /// # Examples |
790 | /// |
791 | /// ```no_run |
792 | /// use std::process::Command; |
793 | /// |
794 | /// Command::new("ls" ) |
795 | /// .env("PATH" , "/bin" ) |
796 | /// .spawn() |
797 | /// .expect("ls command failed to start" ); |
798 | /// ``` |
799 | #[stable (feature = "process" , since = "1.0.0" )] |
800 | pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command |
801 | where |
802 | K: AsRef<OsStr>, |
803 | V: AsRef<OsStr>, |
804 | { |
805 | self.inner.env_mut().set(key.as_ref(), val.as_ref()); |
806 | self |
807 | } |
808 | |
809 | /// Inserts or updates multiple explicit environment variable mappings. |
810 | /// |
811 | /// This method allows you to add multiple environment variable mappings to the spawned process |
812 | /// or overwrite previously set values. You can use [`Command::env`] to set a single environment |
813 | /// variable. |
814 | /// |
815 | /// Child processes will inherit environment variables from their parent process by default. |
816 | /// Environment variables explicitly set using [`Command::envs`] take precedence over inherited |
817 | /// variables. You can disable environment variable inheritance entirely using |
818 | /// [`Command::env_clear`] or for a single key using [`Command::env_remove`]. |
819 | /// |
820 | /// Note that environment variable names are case-insensitive (but case-preserving) on Windows |
821 | /// and case-sensitive on all other platforms. |
822 | /// |
823 | /// # Examples |
824 | /// |
825 | /// ```no_run |
826 | /// use std::process::{Command, Stdio}; |
827 | /// use std::env; |
828 | /// use std::collections::HashMap; |
829 | /// |
830 | /// let filtered_env : HashMap<String, String> = |
831 | /// env::vars().filter(|&(ref k, _)| |
832 | /// k == "TERM" || k == "TZ" || k == "LANG" || k == "PATH" |
833 | /// ).collect(); |
834 | /// |
835 | /// Command::new("printenv" ) |
836 | /// .stdin(Stdio::null()) |
837 | /// .stdout(Stdio::inherit()) |
838 | /// .env_clear() |
839 | /// .envs(&filtered_env) |
840 | /// .spawn() |
841 | /// .expect("printenv failed to start" ); |
842 | /// ``` |
843 | #[stable (feature = "command_envs" , since = "1.19.0" )] |
844 | pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command |
845 | where |
846 | I: IntoIterator<Item = (K, V)>, |
847 | K: AsRef<OsStr>, |
848 | V: AsRef<OsStr>, |
849 | { |
850 | for (ref key, ref val) in vars { |
851 | self.inner.env_mut().set(key.as_ref(), val.as_ref()); |
852 | } |
853 | self |
854 | } |
855 | |
856 | /// Removes an explicitly set environment variable and prevents inheriting it from a parent |
857 | /// process. |
858 | /// |
859 | /// This method will remove the explicit value of an environment variable set via |
860 | /// [`Command::env`] or [`Command::envs`]. In addition, it will prevent the spawned child |
861 | /// process from inheriting that environment variable from its parent process. |
862 | /// |
863 | /// After calling [`Command::env_remove`], the value associated with its key from |
864 | /// [`Command::get_envs`] will be [`None`]. |
865 | /// |
866 | /// To clear all explicitly set environment variables and disable all environment variable |
867 | /// inheritance, you can use [`Command::env_clear`]. |
868 | /// |
869 | /// # Examples |
870 | /// |
871 | /// Prevent any inherited `GIT_DIR` variable from changing the target of the `git` command, |
872 | /// while allowing all other variables, like `GIT_AUTHOR_NAME`. |
873 | /// |
874 | /// ```no_run |
875 | /// use std::process::Command; |
876 | /// |
877 | /// Command::new("git" ) |
878 | /// .arg("commit" ) |
879 | /// .env_remove("GIT_DIR" ) |
880 | /// .spawn()?; |
881 | /// # std::io::Result::Ok(()) |
882 | /// ``` |
883 | #[stable (feature = "process" , since = "1.0.0" )] |
884 | pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command { |
885 | self.inner.env_mut().remove(key.as_ref()); |
886 | self |
887 | } |
888 | |
889 | /// Clears all explicitly set environment variables and prevents inheriting any parent process |
890 | /// environment variables. |
891 | /// |
892 | /// This method will remove all explicitly added environment variables set via [`Command::env`] |
893 | /// or [`Command::envs`]. In addition, it will prevent the spawned child process from inheriting |
894 | /// any environment variable from its parent process. |
895 | /// |
896 | /// After calling [`Command::env_clear`], the iterator from [`Command::get_envs`] will be |
897 | /// empty. |
898 | /// |
899 | /// You can use [`Command::env_remove`] to clear a single mapping. |
900 | /// |
901 | /// # Examples |
902 | /// |
903 | /// The behavior of `sort` is affected by `LANG` and `LC_*` environment variables. |
904 | /// Clearing the environment makes `sort`'s behavior independent of the parent processes' language. |
905 | /// |
906 | /// ```no_run |
907 | /// use std::process::Command; |
908 | /// |
909 | /// Command::new("sort" ) |
910 | /// .arg("file.txt" ) |
911 | /// .env_clear() |
912 | /// .spawn()?; |
913 | /// # std::io::Result::Ok(()) |
914 | /// ``` |
915 | #[stable (feature = "process" , since = "1.0.0" )] |
916 | pub fn env_clear(&mut self) -> &mut Command { |
917 | self.inner.env_mut().clear(); |
918 | self |
919 | } |
920 | |
921 | /// Sets the working directory for the child process. |
922 | /// |
923 | /// # Platform-specific behavior |
924 | /// |
925 | /// If the program path is relative (e.g., `"./script.sh"`), it's ambiguous |
926 | /// whether it should be interpreted relative to the parent's working |
927 | /// directory or relative to `current_dir`. The behavior in this case is |
928 | /// platform specific and unstable, and it's recommended to use |
929 | /// [`canonicalize`] to get an absolute program path instead. |
930 | /// |
931 | /// # Examples |
932 | /// |
933 | /// ```no_run |
934 | /// use std::process::Command; |
935 | /// |
936 | /// Command::new("ls" ) |
937 | /// .current_dir("/bin" ) |
938 | /// .spawn() |
939 | /// .expect("ls command failed to start" ); |
940 | /// ``` |
941 | /// |
942 | /// [`canonicalize`]: crate::fs::canonicalize |
943 | #[stable (feature = "process" , since = "1.0.0" )] |
944 | pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command { |
945 | self.inner.cwd(dir.as_ref().as_ref()); |
946 | self |
947 | } |
948 | |
949 | /// Configuration for the child process's standard input (stdin) handle. |
950 | /// |
951 | /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and |
952 | /// defaults to [`piped`] when used with [`output`]. |
953 | /// |
954 | /// [`inherit`]: Stdio::inherit |
955 | /// [`piped`]: Stdio::piped |
956 | /// [`spawn`]: Self::spawn |
957 | /// [`status`]: Self::status |
958 | /// [`output`]: Self::output |
959 | /// |
960 | /// # Examples |
961 | /// |
962 | /// ```no_run |
963 | /// use std::process::{Command, Stdio}; |
964 | /// |
965 | /// Command::new("ls" ) |
966 | /// .stdin(Stdio::null()) |
967 | /// .spawn() |
968 | /// .expect("ls command failed to start" ); |
969 | /// ``` |
970 | #[stable (feature = "process" , since = "1.0.0" )] |
971 | pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command { |
972 | self.inner.stdin(cfg.into().0); |
973 | self |
974 | } |
975 | |
976 | /// Configuration for the child process's standard output (stdout) handle. |
977 | /// |
978 | /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and |
979 | /// defaults to [`piped`] when used with [`output`]. |
980 | /// |
981 | /// [`inherit`]: Stdio::inherit |
982 | /// [`piped`]: Stdio::piped |
983 | /// [`spawn`]: Self::spawn |
984 | /// [`status`]: Self::status |
985 | /// [`output`]: Self::output |
986 | /// |
987 | /// # Examples |
988 | /// |
989 | /// ```no_run |
990 | /// use std::process::{Command, Stdio}; |
991 | /// |
992 | /// Command::new("ls" ) |
993 | /// .stdout(Stdio::null()) |
994 | /// .spawn() |
995 | /// .expect("ls command failed to start" ); |
996 | /// ``` |
997 | #[stable (feature = "process" , since = "1.0.0" )] |
998 | pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command { |
999 | self.inner.stdout(cfg.into().0); |
1000 | self |
1001 | } |
1002 | |
1003 | /// Configuration for the child process's standard error (stderr) handle. |
1004 | /// |
1005 | /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and |
1006 | /// defaults to [`piped`] when used with [`output`]. |
1007 | /// |
1008 | /// [`inherit`]: Stdio::inherit |
1009 | /// [`piped`]: Stdio::piped |
1010 | /// [`spawn`]: Self::spawn |
1011 | /// [`status`]: Self::status |
1012 | /// [`output`]: Self::output |
1013 | /// |
1014 | /// # Examples |
1015 | /// |
1016 | /// ```no_run |
1017 | /// use std::process::{Command, Stdio}; |
1018 | /// |
1019 | /// Command::new("ls" ) |
1020 | /// .stderr(Stdio::null()) |
1021 | /// .spawn() |
1022 | /// .expect("ls command failed to start" ); |
1023 | /// ``` |
1024 | #[stable (feature = "process" , since = "1.0.0" )] |
1025 | pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command { |
1026 | self.inner.stderr(cfg.into().0); |
1027 | self |
1028 | } |
1029 | |
1030 | /// Executes the command as a child process, returning a handle to it. |
1031 | /// |
1032 | /// By default, stdin, stdout and stderr are inherited from the parent. |
1033 | /// |
1034 | /// # Examples |
1035 | /// |
1036 | /// ```no_run |
1037 | /// use std::process::Command; |
1038 | /// |
1039 | /// Command::new("ls" ) |
1040 | /// .spawn() |
1041 | /// .expect("ls command failed to start" ); |
1042 | /// ``` |
1043 | #[stable (feature = "process" , since = "1.0.0" )] |
1044 | pub fn spawn(&mut self) -> io::Result<Child> { |
1045 | self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner) |
1046 | } |
1047 | |
1048 | /// Executes the command as a child process, waiting for it to finish and |
1049 | /// collecting all of its output. |
1050 | /// |
1051 | /// By default, stdout and stderr are captured (and used to provide the |
1052 | /// resulting output). Stdin is not inherited from the parent and any |
1053 | /// attempt by the child process to read from the stdin stream will result |
1054 | /// in the stream immediately closing. |
1055 | /// |
1056 | /// # Examples |
1057 | /// |
1058 | /// ```should_panic |
1059 | /// use std::process::Command; |
1060 | /// use std::io::{self, Write}; |
1061 | /// let output = Command::new("/bin/cat" ) |
1062 | /// .arg("file.txt" ) |
1063 | /// .output()?; |
1064 | /// |
1065 | /// println!("status: {}" , output.status); |
1066 | /// io::stdout().write_all(&output.stdout)?; |
1067 | /// io::stderr().write_all(&output.stderr)?; |
1068 | /// |
1069 | /// assert!(output.status.success()); |
1070 | /// # io::Result::Ok(()) |
1071 | /// ``` |
1072 | #[stable (feature = "process" , since = "1.0.0" )] |
1073 | pub fn output(&mut self) -> io::Result<Output> { |
1074 | let (status, stdout, stderr) = imp::output(&mut self.inner)?; |
1075 | Ok(Output { status: ExitStatus(status), stdout, stderr }) |
1076 | } |
1077 | |
1078 | /// Executes a command as a child process, waiting for it to finish and |
1079 | /// collecting its status. |
1080 | /// |
1081 | /// By default, stdin, stdout and stderr are inherited from the parent. |
1082 | /// |
1083 | /// # Examples |
1084 | /// |
1085 | /// ```should_panic |
1086 | /// use std::process::Command; |
1087 | /// |
1088 | /// let status = Command::new("/bin/cat" ) |
1089 | /// .arg("file.txt" ) |
1090 | /// .status() |
1091 | /// .expect("failed to execute process" ); |
1092 | /// |
1093 | /// println!("process finished with: {status}" ); |
1094 | /// |
1095 | /// assert!(status.success()); |
1096 | /// ``` |
1097 | #[stable (feature = "process" , since = "1.0.0" )] |
1098 | pub fn status(&mut self) -> io::Result<ExitStatus> { |
1099 | self.inner |
1100 | .spawn(imp::Stdio::Inherit, true) |
1101 | .map(Child::from_inner) |
1102 | .and_then(|mut p| p.wait()) |
1103 | } |
1104 | |
1105 | /// Returns the path to the program that was given to [`Command::new`]. |
1106 | /// |
1107 | /// # Examples |
1108 | /// |
1109 | /// ``` |
1110 | /// use std::process::Command; |
1111 | /// |
1112 | /// let cmd = Command::new("echo" ); |
1113 | /// assert_eq!(cmd.get_program(), "echo" ); |
1114 | /// ``` |
1115 | #[must_use ] |
1116 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1117 | pub fn get_program(&self) -> &OsStr { |
1118 | self.inner.get_program() |
1119 | } |
1120 | |
1121 | /// Returns an iterator of the arguments that will be passed to the program. |
1122 | /// |
1123 | /// This does not include the path to the program as the first argument; |
1124 | /// it only includes the arguments specified with [`Command::arg`] and |
1125 | /// [`Command::args`]. |
1126 | /// |
1127 | /// # Examples |
1128 | /// |
1129 | /// ``` |
1130 | /// use std::ffi::OsStr; |
1131 | /// use std::process::Command; |
1132 | /// |
1133 | /// let mut cmd = Command::new("echo" ); |
1134 | /// cmd.arg("first" ).arg("second" ); |
1135 | /// let args: Vec<&OsStr> = cmd.get_args().collect(); |
1136 | /// assert_eq!(args, &["first" , "second" ]); |
1137 | /// ``` |
1138 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1139 | pub fn get_args(&self) -> CommandArgs<'_> { |
1140 | CommandArgs { inner: self.inner.get_args() } |
1141 | } |
1142 | |
1143 | /// Returns an iterator of the environment variables explicitly set for the child process. |
1144 | /// |
1145 | /// Environment variables explicitly set using [`Command::env`], [`Command::envs`], and |
1146 | /// [`Command::env_remove`] can be retrieved with this method. |
1147 | /// |
1148 | /// Note that this output does not include environment variables inherited from the parent |
1149 | /// process. |
1150 | /// |
1151 | /// Each element is a tuple key/value pair `(&OsStr, Option<&OsStr>)`. A [`None`] value |
1152 | /// indicates its key was explicitly removed via [`Command::env_remove`]. The associated key for |
1153 | /// the [`None`] value will no longer inherit from its parent process. |
1154 | /// |
1155 | /// An empty iterator can indicate that no explicit mappings were added or that |
1156 | /// [`Command::env_clear`] was called. After calling [`Command::env_clear`], the child process |
1157 | /// will not inherit any environment variables from its parent process. |
1158 | /// |
1159 | /// # Examples |
1160 | /// |
1161 | /// ``` |
1162 | /// use std::ffi::OsStr; |
1163 | /// use std::process::Command; |
1164 | /// |
1165 | /// let mut cmd = Command::new("ls" ); |
1166 | /// cmd.env("TERM" , "dumb" ).env_remove("TZ" ); |
1167 | /// let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect(); |
1168 | /// assert_eq!(envs, &[ |
1169 | /// (OsStr::new("TERM" ), Some(OsStr::new("dumb" ))), |
1170 | /// (OsStr::new("TZ" ), None) |
1171 | /// ]); |
1172 | /// ``` |
1173 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1174 | pub fn get_envs(&self) -> CommandEnvs<'_> { |
1175 | CommandEnvs { iter: self.inner.get_envs() } |
1176 | } |
1177 | |
1178 | /// Returns the working directory for the child process. |
1179 | /// |
1180 | /// This returns [`None`] if the working directory will not be changed. |
1181 | /// |
1182 | /// # Examples |
1183 | /// |
1184 | /// ``` |
1185 | /// use std::path::Path; |
1186 | /// use std::process::Command; |
1187 | /// |
1188 | /// let mut cmd = Command::new("ls" ); |
1189 | /// assert_eq!(cmd.get_current_dir(), None); |
1190 | /// cmd.current_dir("/bin" ); |
1191 | /// assert_eq!(cmd.get_current_dir(), Some(Path::new("/bin" ))); |
1192 | /// ``` |
1193 | #[must_use ] |
1194 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1195 | pub fn get_current_dir(&self) -> Option<&Path> { |
1196 | self.inner.get_current_dir() |
1197 | } |
1198 | } |
1199 | |
1200 | #[stable (feature = "rust1" , since = "1.0.0" )] |
1201 | impl fmt::Debug for Command { |
1202 | /// Format the program and arguments of a Command for display. Any |
1203 | /// non-utf8 data is lossily converted using the utf8 replacement |
1204 | /// character. |
1205 | /// |
1206 | /// The default format approximates a shell invocation of the program along with its |
1207 | /// arguments. It does not include most of the other command properties. The output is not guaranteed to work |
1208 | /// (e.g. due to lack of shell-escaping or differences in path resolution). |
1209 | /// On some platforms you can use [the alternate syntax] to show more fields. |
1210 | /// |
1211 | /// Note that the debug implementation is platform-specific. |
1212 | /// |
1213 | /// [the alternate syntax]: fmt#sign0 |
1214 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1215 | self.inner.fmt(f) |
1216 | } |
1217 | } |
1218 | |
1219 | impl AsInner<imp::Command> for Command { |
1220 | #[inline ] |
1221 | fn as_inner(&self) -> &imp::Command { |
1222 | &self.inner |
1223 | } |
1224 | } |
1225 | |
1226 | impl AsInnerMut<imp::Command> for Command { |
1227 | #[inline ] |
1228 | fn as_inner_mut(&mut self) -> &mut imp::Command { |
1229 | &mut self.inner |
1230 | } |
1231 | } |
1232 | |
1233 | /// An iterator over the command arguments. |
1234 | /// |
1235 | /// This struct is created by [`Command::get_args`]. See its documentation for |
1236 | /// more. |
1237 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
1238 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1239 | #[derive (Debug)] |
1240 | pub struct CommandArgs<'a> { |
1241 | inner: imp::CommandArgs<'a>, |
1242 | } |
1243 | |
1244 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1245 | impl<'a> Iterator for CommandArgs<'a> { |
1246 | type Item = &'a OsStr; |
1247 | fn next(&mut self) -> Option<&'a OsStr> { |
1248 | self.inner.next() |
1249 | } |
1250 | fn size_hint(&self) -> (usize, Option<usize>) { |
1251 | self.inner.size_hint() |
1252 | } |
1253 | } |
1254 | |
1255 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1256 | impl<'a> ExactSizeIterator for CommandArgs<'a> { |
1257 | fn len(&self) -> usize { |
1258 | self.inner.len() |
1259 | } |
1260 | fn is_empty(&self) -> bool { |
1261 | self.inner.is_empty() |
1262 | } |
1263 | } |
1264 | |
1265 | /// An iterator over the command environment variables. |
1266 | /// |
1267 | /// This struct is created by |
1268 | /// [`Command::get_envs`][crate::process::Command::get_envs]. See its |
1269 | /// documentation for more. |
1270 | #[must_use = "iterators are lazy and do nothing unless consumed" ] |
1271 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1272 | pub struct CommandEnvs<'a> { |
1273 | iter: imp::CommandEnvs<'a>, |
1274 | } |
1275 | |
1276 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1277 | impl<'a> Iterator for CommandEnvs<'a> { |
1278 | type Item = (&'a OsStr, Option<&'a OsStr>); |
1279 | |
1280 | fn next(&mut self) -> Option<Self::Item> { |
1281 | self.iter.next() |
1282 | } |
1283 | |
1284 | fn size_hint(&self) -> (usize, Option<usize>) { |
1285 | self.iter.size_hint() |
1286 | } |
1287 | } |
1288 | |
1289 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1290 | impl<'a> ExactSizeIterator for CommandEnvs<'a> { |
1291 | fn len(&self) -> usize { |
1292 | self.iter.len() |
1293 | } |
1294 | |
1295 | fn is_empty(&self) -> bool { |
1296 | self.iter.is_empty() |
1297 | } |
1298 | } |
1299 | |
1300 | #[stable (feature = "command_access" , since = "1.57.0" )] |
1301 | impl<'a> fmt::Debug for CommandEnvs<'a> { |
1302 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1303 | self.iter.fmt(f) |
1304 | } |
1305 | } |
1306 | |
1307 | /// The output of a finished process. |
1308 | /// |
1309 | /// This is returned in a Result by either the [`output`] method of a |
1310 | /// [`Command`], or the [`wait_with_output`] method of a [`Child`] |
1311 | /// process. |
1312 | /// |
1313 | /// [`output`]: Command::output |
1314 | /// [`wait_with_output`]: Child::wait_with_output |
1315 | #[derive (PartialEq, Eq, Clone)] |
1316 | #[stable (feature = "process" , since = "1.0.0" )] |
1317 | pub struct Output { |
1318 | /// The status (exit code) of the process. |
1319 | #[stable (feature = "process" , since = "1.0.0" )] |
1320 | pub status: ExitStatus, |
1321 | /// The data that the process wrote to stdout. |
1322 | #[stable (feature = "process" , since = "1.0.0" )] |
1323 | pub stdout: Vec<u8>, |
1324 | /// The data that the process wrote to stderr. |
1325 | #[stable (feature = "process" , since = "1.0.0" )] |
1326 | pub stderr: Vec<u8>, |
1327 | } |
1328 | |
1329 | impl Output { |
1330 | /// Returns an error if a nonzero exit status was received. |
1331 | /// |
1332 | /// If the [`Command`] exited successfully, |
1333 | /// `self` is returned. |
1334 | /// |
1335 | /// This is equivalent to calling [`exit_ok`](ExitStatus::exit_ok) |
1336 | /// on [`Output.status`](Output::status). |
1337 | /// |
1338 | /// Note that this will throw away the [`Output::stderr`] field in the error case. |
1339 | /// If the child process outputs useful informantion to stderr, you can: |
1340 | /// * Use `cmd.stderr(Stdio::inherit())` to forward the |
1341 | /// stderr child process to the parent's stderr, |
1342 | /// usually printing it to console where the user can see it. |
1343 | /// This is usually correct for command-line applications. |
1344 | /// * Capture `stderr` using a custom error type. |
1345 | /// This is usually correct for libraries. |
1346 | /// |
1347 | /// # Examples |
1348 | /// |
1349 | /// ``` |
1350 | /// #![feature(exit_status_error)] |
1351 | /// # #[cfg (all(unix, not(target_os = "android" )))] { |
1352 | /// use std::process::Command; |
1353 | /// assert!(Command::new("false" ).output().unwrap().exit_ok().is_err()); |
1354 | /// # } |
1355 | /// ``` |
1356 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
1357 | pub fn exit_ok(self) -> Result<Self, ExitStatusError> { |
1358 | self.status.exit_ok()?; |
1359 | Ok(self) |
1360 | } |
1361 | } |
1362 | |
1363 | // If either stderr or stdout are valid utf8 strings it prints the valid |
1364 | // strings, otherwise it prints the byte sequence instead |
1365 | #[stable (feature = "process_output_debug" , since = "1.7.0" )] |
1366 | impl fmt::Debug for Output { |
1367 | fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { |
1368 | let stdout_utf8: Result<&str, Utf8Error> = str::from_utf8(&self.stdout); |
1369 | let stdout_debug: &dyn fmt::Debug = match stdout_utf8 { |
1370 | Ok(ref s: &&str) => s, |
1371 | Err(_) => &self.stdout, |
1372 | }; |
1373 | |
1374 | let stderr_utf8: Result<&str, Utf8Error> = str::from_utf8(&self.stderr); |
1375 | let stderr_debug: &dyn fmt::Debug = match stderr_utf8 { |
1376 | Ok(ref s: &&str) => s, |
1377 | Err(_) => &self.stderr, |
1378 | }; |
1379 | |
1380 | fmt&mut DebugStruct<'_, '_>.debug_struct("Output" ) |
1381 | .field("status" , &self.status) |
1382 | .field("stdout" , stdout_debug) |
1383 | .field(name:"stderr" , value:stderr_debug) |
1384 | .finish() |
1385 | } |
1386 | } |
1387 | |
1388 | /// Describes what to do with a standard I/O stream for a child process when |
1389 | /// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`]. |
1390 | /// |
1391 | /// [`stdin`]: Command::stdin |
1392 | /// [`stdout`]: Command::stdout |
1393 | /// [`stderr`]: Command::stderr |
1394 | #[stable (feature = "process" , since = "1.0.0" )] |
1395 | pub struct Stdio(imp::Stdio); |
1396 | |
1397 | impl Stdio { |
1398 | /// A new pipe should be arranged to connect the parent and child processes. |
1399 | /// |
1400 | /// # Examples |
1401 | /// |
1402 | /// With stdout: |
1403 | /// |
1404 | /// ```no_run |
1405 | /// use std::process::{Command, Stdio}; |
1406 | /// |
1407 | /// let output = Command::new("echo" ) |
1408 | /// .arg("Hello, world!" ) |
1409 | /// .stdout(Stdio::piped()) |
1410 | /// .output() |
1411 | /// .expect("Failed to execute command" ); |
1412 | /// |
1413 | /// assert_eq!(String::from_utf8_lossy(&output.stdout), "Hello, world! \n" ); |
1414 | /// // Nothing echoed to console |
1415 | /// ``` |
1416 | /// |
1417 | /// With stdin: |
1418 | /// |
1419 | /// ```no_run |
1420 | /// use std::io::Write; |
1421 | /// use std::process::{Command, Stdio}; |
1422 | /// |
1423 | /// let mut child = Command::new("rev" ) |
1424 | /// .stdin(Stdio::piped()) |
1425 | /// .stdout(Stdio::piped()) |
1426 | /// .spawn() |
1427 | /// .expect("Failed to spawn child process" ); |
1428 | /// |
1429 | /// let mut stdin = child.stdin.take().expect("Failed to open stdin" ); |
1430 | /// std::thread::spawn(move || { |
1431 | /// stdin.write_all("Hello, world!" .as_bytes()).expect("Failed to write to stdin" ); |
1432 | /// }); |
1433 | /// |
1434 | /// let output = child.wait_with_output().expect("Failed to read stdout" ); |
1435 | /// assert_eq!(String::from_utf8_lossy(&output.stdout), "!dlrow ,olleH" ); |
1436 | /// ``` |
1437 | /// |
1438 | /// Writing more than a pipe buffer's worth of input to stdin without also reading |
1439 | /// stdout and stderr at the same time may cause a deadlock. |
1440 | /// This is an issue when running any program that doesn't guarantee that it reads |
1441 | /// its entire stdin before writing more than a pipe buffer's worth of output. |
1442 | /// The size of a pipe buffer varies on different targets. |
1443 | /// |
1444 | #[must_use ] |
1445 | #[stable (feature = "process" , since = "1.0.0" )] |
1446 | pub fn piped() -> Stdio { |
1447 | Stdio(imp::Stdio::MakePipe) |
1448 | } |
1449 | |
1450 | /// The child inherits from the corresponding parent descriptor. |
1451 | /// |
1452 | /// # Examples |
1453 | /// |
1454 | /// With stdout: |
1455 | /// |
1456 | /// ```no_run |
1457 | /// use std::process::{Command, Stdio}; |
1458 | /// |
1459 | /// let output = Command::new("echo" ) |
1460 | /// .arg("Hello, world!" ) |
1461 | /// .stdout(Stdio::inherit()) |
1462 | /// .output() |
1463 | /// .expect("Failed to execute command" ); |
1464 | /// |
1465 | /// assert_eq!(String::from_utf8_lossy(&output.stdout), "" ); |
1466 | /// // "Hello, world!" echoed to console |
1467 | /// ``` |
1468 | /// |
1469 | /// With stdin: |
1470 | /// |
1471 | /// ```no_run |
1472 | /// use std::process::{Command, Stdio}; |
1473 | /// use std::io::{self, Write}; |
1474 | /// |
1475 | /// let output = Command::new("rev" ) |
1476 | /// .stdin(Stdio::inherit()) |
1477 | /// .stdout(Stdio::piped()) |
1478 | /// .output()?; |
1479 | /// |
1480 | /// print!("You piped in the reverse of: " ); |
1481 | /// io::stdout().write_all(&output.stdout)?; |
1482 | /// # io::Result::Ok(()) |
1483 | /// ``` |
1484 | #[must_use ] |
1485 | #[stable (feature = "process" , since = "1.0.0" )] |
1486 | pub fn inherit() -> Stdio { |
1487 | Stdio(imp::Stdio::Inherit) |
1488 | } |
1489 | |
1490 | /// This stream will be ignored. This is the equivalent of attaching the |
1491 | /// stream to `/dev/null`. |
1492 | /// |
1493 | /// # Examples |
1494 | /// |
1495 | /// With stdout: |
1496 | /// |
1497 | /// ```no_run |
1498 | /// use std::process::{Command, Stdio}; |
1499 | /// |
1500 | /// let output = Command::new("echo" ) |
1501 | /// .arg("Hello, world!" ) |
1502 | /// .stdout(Stdio::null()) |
1503 | /// .output() |
1504 | /// .expect("Failed to execute command" ); |
1505 | /// |
1506 | /// assert_eq!(String::from_utf8_lossy(&output.stdout), "" ); |
1507 | /// // Nothing echoed to console |
1508 | /// ``` |
1509 | /// |
1510 | /// With stdin: |
1511 | /// |
1512 | /// ```no_run |
1513 | /// use std::process::{Command, Stdio}; |
1514 | /// |
1515 | /// let output = Command::new("rev" ) |
1516 | /// .stdin(Stdio::null()) |
1517 | /// .stdout(Stdio::piped()) |
1518 | /// .output() |
1519 | /// .expect("Failed to execute command" ); |
1520 | /// |
1521 | /// assert_eq!(String::from_utf8_lossy(&output.stdout), "" ); |
1522 | /// // Ignores any piped-in input |
1523 | /// ``` |
1524 | #[must_use ] |
1525 | #[stable (feature = "process" , since = "1.0.0" )] |
1526 | pub fn null() -> Stdio { |
1527 | Stdio(imp::Stdio::Null) |
1528 | } |
1529 | |
1530 | /// Returns `true` if this requires [`Command`] to create a new pipe. |
1531 | /// |
1532 | /// # Example |
1533 | /// |
1534 | /// ``` |
1535 | /// #![feature(stdio_makes_pipe)] |
1536 | /// use std::process::Stdio; |
1537 | /// |
1538 | /// let io = Stdio::piped(); |
1539 | /// assert_eq!(io.makes_pipe(), true); |
1540 | /// ``` |
1541 | #[unstable (feature = "stdio_makes_pipe" , issue = "98288" )] |
1542 | pub fn makes_pipe(&self) -> bool { |
1543 | matches!(self.0, imp::Stdio::MakePipe) |
1544 | } |
1545 | } |
1546 | |
1547 | impl FromInner<imp::Stdio> for Stdio { |
1548 | fn from_inner(inner: imp::Stdio) -> Stdio { |
1549 | Stdio(inner) |
1550 | } |
1551 | } |
1552 | |
1553 | #[stable (feature = "std_debug" , since = "1.16.0" )] |
1554 | impl fmt::Debug for Stdio { |
1555 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1556 | f.debug_struct(name:"Stdio" ).finish_non_exhaustive() |
1557 | } |
1558 | } |
1559 | |
1560 | #[stable (feature = "stdio_from" , since = "1.20.0" )] |
1561 | impl From<ChildStdin> for Stdio { |
1562 | /// Converts a [`ChildStdin`] into a [`Stdio`]. |
1563 | /// |
1564 | /// # Examples |
1565 | /// |
1566 | /// `ChildStdin` will be converted to `Stdio` using `Stdio::from` under the hood. |
1567 | /// |
1568 | /// ```rust,no_run |
1569 | /// use std::process::{Command, Stdio}; |
1570 | /// |
1571 | /// let reverse = Command::new("rev" ) |
1572 | /// .stdin(Stdio::piped()) |
1573 | /// .spawn() |
1574 | /// .expect("failed reverse command" ); |
1575 | /// |
1576 | /// let _echo = Command::new("echo" ) |
1577 | /// .arg("Hello, world!" ) |
1578 | /// .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here |
1579 | /// .output() |
1580 | /// .expect("failed echo command" ); |
1581 | /// |
1582 | /// // "!dlrow ,olleH" echoed to console |
1583 | /// ``` |
1584 | fn from(child: ChildStdin) -> Stdio { |
1585 | Stdio::from_inner(child.into_inner().into()) |
1586 | } |
1587 | } |
1588 | |
1589 | #[stable (feature = "stdio_from" , since = "1.20.0" )] |
1590 | impl From<ChildStdout> for Stdio { |
1591 | /// Converts a [`ChildStdout`] into a [`Stdio`]. |
1592 | /// |
1593 | /// # Examples |
1594 | /// |
1595 | /// `ChildStdout` will be converted to `Stdio` using `Stdio::from` under the hood. |
1596 | /// |
1597 | /// ```rust,no_run |
1598 | /// use std::process::{Command, Stdio}; |
1599 | /// |
1600 | /// let hello = Command::new("echo" ) |
1601 | /// .arg("Hello, world!" ) |
1602 | /// .stdout(Stdio::piped()) |
1603 | /// .spawn() |
1604 | /// .expect("failed echo command" ); |
1605 | /// |
1606 | /// let reverse = Command::new("rev" ) |
1607 | /// .stdin(hello.stdout.unwrap()) // Converted into a Stdio here |
1608 | /// .output() |
1609 | /// .expect("failed reverse command" ); |
1610 | /// |
1611 | /// assert_eq!(reverse.stdout, b"!dlrow ,olleH \n" ); |
1612 | /// ``` |
1613 | fn from(child: ChildStdout) -> Stdio { |
1614 | Stdio::from_inner(child.into_inner().into()) |
1615 | } |
1616 | } |
1617 | |
1618 | #[stable (feature = "stdio_from" , since = "1.20.0" )] |
1619 | impl From<ChildStderr> for Stdio { |
1620 | /// Converts a [`ChildStderr`] into a [`Stdio`]. |
1621 | /// |
1622 | /// # Examples |
1623 | /// |
1624 | /// ```rust,no_run |
1625 | /// use std::process::{Command, Stdio}; |
1626 | /// |
1627 | /// let reverse = Command::new("rev" ) |
1628 | /// .arg("non_existing_file.txt" ) |
1629 | /// .stderr(Stdio::piped()) |
1630 | /// .spawn() |
1631 | /// .expect("failed reverse command" ); |
1632 | /// |
1633 | /// let cat = Command::new("cat" ) |
1634 | /// .arg("-" ) |
1635 | /// .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here |
1636 | /// .output() |
1637 | /// .expect("failed echo command" ); |
1638 | /// |
1639 | /// assert_eq!( |
1640 | /// String::from_utf8_lossy(&cat.stdout), |
1641 | /// "rev: cannot open non_existing_file.txt: No such file or directory \n" |
1642 | /// ); |
1643 | /// ``` |
1644 | fn from(child: ChildStderr) -> Stdio { |
1645 | Stdio::from_inner(child.into_inner().into()) |
1646 | } |
1647 | } |
1648 | |
1649 | #[stable (feature = "stdio_from" , since = "1.20.0" )] |
1650 | impl From<fs::File> for Stdio { |
1651 | /// Converts a [`File`](fs::File) into a [`Stdio`]. |
1652 | /// |
1653 | /// # Examples |
1654 | /// |
1655 | /// `File` will be converted to `Stdio` using `Stdio::from` under the hood. |
1656 | /// |
1657 | /// ```rust,no_run |
1658 | /// use std::fs::File; |
1659 | /// use std::process::Command; |
1660 | /// |
1661 | /// // With the `foo.txt` file containing "Hello, world!" |
1662 | /// let file = File::open("foo.txt" )?; |
1663 | /// |
1664 | /// let reverse = Command::new("rev" ) |
1665 | /// .stdin(file) // Implicit File conversion into a Stdio |
1666 | /// .output()?; |
1667 | /// |
1668 | /// assert_eq!(reverse.stdout, b"!dlrow ,olleH" ); |
1669 | /// # std::io::Result::Ok(()) |
1670 | /// ``` |
1671 | fn from(file: fs::File) -> Stdio { |
1672 | Stdio::from_inner(file.into_inner().into()) |
1673 | } |
1674 | } |
1675 | |
1676 | #[stable (feature = "stdio_from_stdio" , since = "1.74.0" )] |
1677 | impl From<io::Stdout> for Stdio { |
1678 | /// Redirect command stdout/stderr to our stdout |
1679 | /// |
1680 | /// # Examples |
1681 | /// |
1682 | /// ```rust |
1683 | /// #![feature(exit_status_error)] |
1684 | /// use std::io; |
1685 | /// use std::process::Command; |
1686 | /// |
1687 | /// # fn test() -> Result<(), Box<dyn std::error::Error>> { |
1688 | /// let output = Command::new("whoami" ) |
1689 | // "whoami" is a command which exists on both Unix and Windows, |
1690 | // and which succeeds, producing some stdout output but no stderr. |
1691 | /// .stdout(io::stdout()) |
1692 | /// .output()?; |
1693 | /// output.status.exit_ok()?; |
1694 | /// assert!(output.stdout.is_empty()); |
1695 | /// # Ok(()) |
1696 | /// # } |
1697 | /// # |
1698 | /// # if cfg!(all(unix, not(target_os = "android" ))) { |
1699 | /// # test().unwrap(); |
1700 | /// # } |
1701 | /// ``` |
1702 | fn from(inherit: io::Stdout) -> Stdio { |
1703 | Stdio::from_inner(inherit.into()) |
1704 | } |
1705 | } |
1706 | |
1707 | #[stable (feature = "stdio_from_stdio" , since = "1.74.0" )] |
1708 | impl From<io::Stderr> for Stdio { |
1709 | /// Redirect command stdout/stderr to our stderr |
1710 | /// |
1711 | /// # Examples |
1712 | /// |
1713 | /// ```rust |
1714 | /// #![feature(exit_status_error)] |
1715 | /// use std::io; |
1716 | /// use std::process::Command; |
1717 | /// |
1718 | /// # fn test() -> Result<(), Box<dyn std::error::Error>> { |
1719 | /// let output = Command::new("whoami" ) |
1720 | /// .stdout(io::stderr()) |
1721 | /// .output()?; |
1722 | /// output.status.exit_ok()?; |
1723 | /// assert!(output.stdout.is_empty()); |
1724 | /// # Ok(()) |
1725 | /// # } |
1726 | /// # |
1727 | /// # if cfg!(all(unix, not(target_os = "android" ))) { |
1728 | /// # test().unwrap(); |
1729 | /// # } |
1730 | /// ``` |
1731 | fn from(inherit: io::Stderr) -> Stdio { |
1732 | Stdio::from_inner(inherit.into()) |
1733 | } |
1734 | } |
1735 | |
1736 | #[stable (feature = "anonymous_pipe" , since = "1.87.0" )] |
1737 | impl From<io::PipeWriter> for Stdio { |
1738 | fn from(pipe: io::PipeWriter) -> Self { |
1739 | Stdio::from_inner(pipe.into_inner().into()) |
1740 | } |
1741 | } |
1742 | |
1743 | #[stable (feature = "anonymous_pipe" , since = "1.87.0" )] |
1744 | impl From<io::PipeReader> for Stdio { |
1745 | fn from(pipe: io::PipeReader) -> Self { |
1746 | Stdio::from_inner(pipe.into_inner().into()) |
1747 | } |
1748 | } |
1749 | |
1750 | /// Describes the result of a process after it has terminated. |
1751 | /// |
1752 | /// This `struct` is used to represent the exit status or other termination of a child process. |
1753 | /// Child processes are created via the [`Command`] struct and their exit |
1754 | /// status is exposed through the [`status`] method, or the [`wait`] method |
1755 | /// of a [`Child`] process. |
1756 | /// |
1757 | /// An `ExitStatus` represents every possible disposition of a process. On Unix this |
1758 | /// is the **wait status**. It is *not* simply an *exit status* (a value passed to `exit`). |
1759 | /// |
1760 | /// For proper error reporting of failed processes, print the value of `ExitStatus` or |
1761 | /// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display). |
1762 | /// |
1763 | /// # Differences from `ExitCode` |
1764 | /// |
1765 | /// [`ExitCode`] is intended for terminating the currently running process, via |
1766 | /// the `Termination` trait, in contrast to `ExitStatus`, which represents the |
1767 | /// termination of a child process. These APIs are separate due to platform |
1768 | /// compatibility differences and their expected usage; it is not generally |
1769 | /// possible to exactly reproduce an `ExitStatus` from a child for the current |
1770 | /// process after the fact. |
1771 | /// |
1772 | /// [`status`]: Command::status |
1773 | /// [`wait`]: Child::wait |
1774 | // |
1775 | // We speak slightly loosely (here and in various other places in the stdlib docs) about `exit` |
1776 | // vs `_exit`. Naming of Unix system calls is not standardised across Unices, so terminology is a |
1777 | // matter of convention and tradition. For clarity we usually speak of `exit`, even when we might |
1778 | // mean an underlying system call such as `_exit`. |
1779 | #[derive (PartialEq, Eq, Clone, Copy, Debug)] |
1780 | #[stable (feature = "process" , since = "1.0.0" )] |
1781 | pub struct ExitStatus(imp::ExitStatus); |
1782 | |
1783 | /// The default value is one which indicates successful completion. |
1784 | #[stable (feature = "process_exitstatus_default" , since = "1.73.0" )] |
1785 | impl Default for ExitStatus { |
1786 | fn default() -> Self { |
1787 | // Ideally this would be done by ExitCode::default().into() but that is complicated. |
1788 | ExitStatus::from_inner(imp::ExitStatus::default()) |
1789 | } |
1790 | } |
1791 | |
1792 | /// Allows extension traits within `std`. |
1793 | #[unstable (feature = "sealed" , issue = "none" )] |
1794 | impl crate::sealed::Sealed for ExitStatus {} |
1795 | |
1796 | impl ExitStatus { |
1797 | /// Was termination successful? Returns a `Result`. |
1798 | /// |
1799 | /// # Examples |
1800 | /// |
1801 | /// ``` |
1802 | /// #![feature(exit_status_error)] |
1803 | /// # if cfg!(unix) { |
1804 | /// use std::process::Command; |
1805 | /// |
1806 | /// let status = Command::new("ls" ) |
1807 | /// .arg("/dev/nonexistent" ) |
1808 | /// .status() |
1809 | /// .expect("ls could not be executed" ); |
1810 | /// |
1811 | /// println!("ls: {status}" ); |
1812 | /// status.exit_ok().expect_err("/dev/nonexistent could be listed!" ); |
1813 | /// # } // cfg!(unix) |
1814 | /// ``` |
1815 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
1816 | pub fn exit_ok(&self) -> Result<(), ExitStatusError> { |
1817 | self.0.exit_ok().map_err(ExitStatusError) |
1818 | } |
1819 | |
1820 | /// Was termination successful? Signal termination is not considered a |
1821 | /// success, and success is defined as a zero exit status. |
1822 | /// |
1823 | /// # Examples |
1824 | /// |
1825 | /// ```rust,no_run |
1826 | /// use std::process::Command; |
1827 | /// |
1828 | /// let status = Command::new("mkdir" ) |
1829 | /// .arg("projects" ) |
1830 | /// .status() |
1831 | /// .expect("failed to execute mkdir" ); |
1832 | /// |
1833 | /// if status.success() { |
1834 | /// println!("'projects/' directory created" ); |
1835 | /// } else { |
1836 | /// println!("failed to create 'projects/' directory: {status}" ); |
1837 | /// } |
1838 | /// ``` |
1839 | #[must_use ] |
1840 | #[stable (feature = "process" , since = "1.0.0" )] |
1841 | pub fn success(&self) -> bool { |
1842 | self.0.exit_ok().is_ok() |
1843 | } |
1844 | |
1845 | /// Returns the exit code of the process, if any. |
1846 | /// |
1847 | /// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the |
1848 | /// process finished by calling `exit`. Note that on Unix the exit status is truncated to 8 |
1849 | /// bits, and that values that didn't come from a program's call to `exit` may be invented by the |
1850 | /// runtime system (often, for example, 255, 254, 127 or 126). |
1851 | /// |
1852 | /// On Unix, this will return `None` if the process was terminated by a signal. |
1853 | /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) is an |
1854 | /// extension trait for extracting any such signal, and other details, from the `ExitStatus`. |
1855 | /// |
1856 | /// # Examples |
1857 | /// |
1858 | /// ```no_run |
1859 | /// use std::process::Command; |
1860 | /// |
1861 | /// let status = Command::new("mkdir" ) |
1862 | /// .arg("projects" ) |
1863 | /// .status() |
1864 | /// .expect("failed to execute mkdir" ); |
1865 | /// |
1866 | /// match status.code() { |
1867 | /// Some(code) => println!("Exited with status code: {code}" ), |
1868 | /// None => println!("Process terminated by signal" ) |
1869 | /// } |
1870 | /// ``` |
1871 | #[must_use ] |
1872 | #[stable (feature = "process" , since = "1.0.0" )] |
1873 | pub fn code(&self) -> Option<i32> { |
1874 | self.0.code() |
1875 | } |
1876 | } |
1877 | |
1878 | impl AsInner<imp::ExitStatus> for ExitStatus { |
1879 | #[inline ] |
1880 | fn as_inner(&self) -> &imp::ExitStatus { |
1881 | &self.0 |
1882 | } |
1883 | } |
1884 | |
1885 | impl FromInner<imp::ExitStatus> for ExitStatus { |
1886 | fn from_inner(s: imp::ExitStatus) -> ExitStatus { |
1887 | ExitStatus(s) |
1888 | } |
1889 | } |
1890 | |
1891 | #[stable (feature = "process" , since = "1.0.0" )] |
1892 | impl fmt::Display for ExitStatus { |
1893 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
1894 | self.0.fmt(f) |
1895 | } |
1896 | } |
1897 | |
1898 | /// Allows extension traits within `std`. |
1899 | #[unstable (feature = "sealed" , issue = "none" )] |
1900 | impl crate::sealed::Sealed for ExitStatusError {} |
1901 | |
1902 | /// Describes the result of a process after it has failed |
1903 | /// |
1904 | /// Produced by the [`.exit_ok`](ExitStatus::exit_ok) method on [`ExitStatus`]. |
1905 | /// |
1906 | /// # Examples |
1907 | /// |
1908 | /// ``` |
1909 | /// #![feature(exit_status_error)] |
1910 | /// # if cfg!(all(unix, not(target_os = "android" ))) { |
1911 | /// use std::process::{Command, ExitStatusError}; |
1912 | /// |
1913 | /// fn run(cmd: &str) -> Result<(), ExitStatusError> { |
1914 | /// Command::new(cmd).status().unwrap().exit_ok()?; |
1915 | /// Ok(()) |
1916 | /// } |
1917 | /// |
1918 | /// run("true" ).unwrap(); |
1919 | /// run("false" ).unwrap_err(); |
1920 | /// # } // cfg!(unix) |
1921 | /// ``` |
1922 | #[derive (PartialEq, Eq, Clone, Copy, Debug)] |
1923 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
1924 | // The definition of imp::ExitStatusError should ideally be such that |
1925 | // Result<(), imp::ExitStatusError> has an identical representation to imp::ExitStatus. |
1926 | pub struct ExitStatusError(imp::ExitStatusError); |
1927 | |
1928 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
1929 | impl ExitStatusError { |
1930 | /// Reports the exit code, if applicable, from an `ExitStatusError`. |
1931 | /// |
1932 | /// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the |
1933 | /// process finished by calling `exit`. Note that on Unix the exit status is truncated to 8 |
1934 | /// bits, and that values that didn't come from a program's call to `exit` may be invented by the |
1935 | /// runtime system (often, for example, 255, 254, 127 or 126). |
1936 | /// |
1937 | /// On Unix, this will return `None` if the process was terminated by a signal. If you want to |
1938 | /// handle such situations specially, consider using methods from |
1939 | /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt). |
1940 | /// |
1941 | /// If the process finished by calling `exit` with a nonzero value, this will return |
1942 | /// that exit status. |
1943 | /// |
1944 | /// If the error was something else, it will return `None`. |
1945 | /// |
1946 | /// If the process exited successfully (ie, by calling `exit(0)`), there is no |
1947 | /// `ExitStatusError`. So the return value from `ExitStatusError::code()` is always nonzero. |
1948 | /// |
1949 | /// # Examples |
1950 | /// |
1951 | /// ``` |
1952 | /// #![feature(exit_status_error)] |
1953 | /// # #[cfg (all(unix, not(target_os = "android" )))] { |
1954 | /// use std::process::Command; |
1955 | /// |
1956 | /// let bad = Command::new("false" ).status().unwrap().exit_ok().unwrap_err(); |
1957 | /// assert_eq!(bad.code(), Some(1)); |
1958 | /// # } // #[cfg(unix)] |
1959 | /// ``` |
1960 | #[must_use ] |
1961 | pub fn code(&self) -> Option<i32> { |
1962 | self.code_nonzero().map(Into::into) |
1963 | } |
1964 | |
1965 | /// Reports the exit code, if applicable, from an `ExitStatusError`, as a [`NonZero`]. |
1966 | /// |
1967 | /// This is exactly like [`code()`](Self::code), except that it returns a <code>[NonZero]<[i32]></code>. |
1968 | /// |
1969 | /// Plain `code`, returning a plain integer, is provided because it is often more convenient. |
1970 | /// The returned value from `code()` is indeed also nonzero; use `code_nonzero()` when you want |
1971 | /// a type-level guarantee of nonzeroness. |
1972 | /// |
1973 | /// # Examples |
1974 | /// |
1975 | /// ``` |
1976 | /// #![feature(exit_status_error)] |
1977 | /// |
1978 | /// # if cfg!(all(unix, not(target_os = "android" ))) { |
1979 | /// use std::num::NonZero; |
1980 | /// use std::process::Command; |
1981 | /// |
1982 | /// let bad = Command::new("false" ).status().unwrap().exit_ok().unwrap_err(); |
1983 | /// assert_eq!(bad.code_nonzero().unwrap(), NonZero::new(1).unwrap()); |
1984 | /// # } // cfg!(unix) |
1985 | /// ``` |
1986 | #[must_use ] |
1987 | pub fn code_nonzero(&self) -> Option<NonZero<i32>> { |
1988 | self.0.code() |
1989 | } |
1990 | |
1991 | /// Converts an `ExitStatusError` (back) to an `ExitStatus`. |
1992 | #[must_use ] |
1993 | pub fn into_status(&self) -> ExitStatus { |
1994 | ExitStatus(self.0.into()) |
1995 | } |
1996 | } |
1997 | |
1998 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
1999 | impl From<ExitStatusError> for ExitStatus { |
2000 | fn from(error: ExitStatusError) -> Self { |
2001 | Self(error.0.into()) |
2002 | } |
2003 | } |
2004 | |
2005 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
2006 | impl fmt::Display for ExitStatusError { |
2007 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
2008 | write!(f, "process exited unsuccessfully: {}" , self.into_status()) |
2009 | } |
2010 | } |
2011 | |
2012 | #[unstable (feature = "exit_status_error" , issue = "84908" )] |
2013 | impl crate::error::Error for ExitStatusError {} |
2014 | |
2015 | /// This type represents the status code the current process can return |
2016 | /// to its parent under normal termination. |
2017 | /// |
2018 | /// `ExitCode` is intended to be consumed only by the standard library (via |
2019 | /// [`Termination::report()`]). For forwards compatibility with potentially |
2020 | /// unusual targets, this type currently does not provide `Eq`, `Hash`, or |
2021 | /// access to the raw value. This type does provide `PartialEq` for |
2022 | /// comparison, but note that there may potentially be multiple failure |
2023 | /// codes, some of which will _not_ compare equal to `ExitCode::FAILURE`. |
2024 | /// The standard library provides the canonical `SUCCESS` and `FAILURE` |
2025 | /// exit codes as well as `From<u8> for ExitCode` for constructing other |
2026 | /// arbitrary exit codes. |
2027 | /// |
2028 | /// # Portability |
2029 | /// |
2030 | /// Numeric values used in this type don't have portable meanings, and |
2031 | /// different platforms may mask different amounts of them. |
2032 | /// |
2033 | /// For the platform's canonical successful and unsuccessful codes, see |
2034 | /// the [`SUCCESS`] and [`FAILURE`] associated items. |
2035 | /// |
2036 | /// [`SUCCESS`]: ExitCode::SUCCESS |
2037 | /// [`FAILURE`]: ExitCode::FAILURE |
2038 | /// |
2039 | /// # Differences from `ExitStatus` |
2040 | /// |
2041 | /// `ExitCode` is intended for terminating the currently running process, via |
2042 | /// the `Termination` trait, in contrast to [`ExitStatus`], which represents the |
2043 | /// termination of a child process. These APIs are separate due to platform |
2044 | /// compatibility differences and their expected usage; it is not generally |
2045 | /// possible to exactly reproduce an `ExitStatus` from a child for the current |
2046 | /// process after the fact. |
2047 | /// |
2048 | /// # Examples |
2049 | /// |
2050 | /// `ExitCode` can be returned from the `main` function of a crate, as it implements |
2051 | /// [`Termination`]: |
2052 | /// |
2053 | /// ``` |
2054 | /// use std::process::ExitCode; |
2055 | /// # fn check_foo() -> bool { true } |
2056 | /// |
2057 | /// fn main() -> ExitCode { |
2058 | /// if !check_foo() { |
2059 | /// return ExitCode::from(42); |
2060 | /// } |
2061 | /// |
2062 | /// ExitCode::SUCCESS |
2063 | /// } |
2064 | /// ``` |
2065 | #[derive (Clone, Copy, Debug, PartialEq)] |
2066 | #[stable (feature = "process_exitcode" , since = "1.61.0" )] |
2067 | pub struct ExitCode(imp::ExitCode); |
2068 | |
2069 | /// Allows extension traits within `std`. |
2070 | #[unstable (feature = "sealed" , issue = "none" )] |
2071 | impl crate::sealed::Sealed for ExitCode {} |
2072 | |
2073 | #[stable (feature = "process_exitcode" , since = "1.61.0" )] |
2074 | impl ExitCode { |
2075 | /// The canonical `ExitCode` for successful termination on this platform. |
2076 | /// |
2077 | /// Note that a `()`-returning `main` implicitly results in a successful |
2078 | /// termination, so there's no need to return this from `main` unless |
2079 | /// you're also returning other possible codes. |
2080 | #[stable (feature = "process_exitcode" , since = "1.61.0" )] |
2081 | pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS); |
2082 | |
2083 | /// The canonical `ExitCode` for unsuccessful termination on this platform. |
2084 | /// |
2085 | /// If you're only returning this and `SUCCESS` from `main`, consider |
2086 | /// instead returning `Err(_)` and `Ok(())` respectively, which will |
2087 | /// return the same codes (but will also `eprintln!` the error). |
2088 | #[stable (feature = "process_exitcode" , since = "1.61.0" )] |
2089 | pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE); |
2090 | |
2091 | /// Exit the current process with the given `ExitCode`. |
2092 | /// |
2093 | /// Note that this has the same caveats as [`process::exit()`][exit], namely that this function |
2094 | /// terminates the process immediately, so no destructors on the current stack or any other |
2095 | /// thread's stack will be run. Also see those docs for some important notes on interop with C |
2096 | /// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from |
2097 | /// the `main` function, as demonstrated in the [type documentation](#examples). |
2098 | /// |
2099 | /// # Differences from `process::exit()` |
2100 | /// |
2101 | /// `process::exit()` accepts any `i32` value as the exit code for the process; however, there |
2102 | /// are platforms that only use a subset of that value (see [`process::exit` platform-specific |
2103 | /// behavior][exit#platform-specific-behavior]). `ExitCode` exists because of this; only |
2104 | /// `ExitCode`s that are supported by a majority of our platforms can be created, so those |
2105 | /// problems don't exist (as much) with this method. |
2106 | /// |
2107 | /// # Examples |
2108 | /// |
2109 | /// ``` |
2110 | /// #![feature(exitcode_exit_method)] |
2111 | /// # use std::process::ExitCode; |
2112 | /// # use std::fmt; |
2113 | /// # enum UhOhError { GenericProblem, Specific, WithCode { exit_code: ExitCode, _x: () } } |
2114 | /// # impl fmt::Display for UhOhError { |
2115 | /// # fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { unimplemented!() } |
2116 | /// # } |
2117 | /// // there's no way to gracefully recover from an UhOhError, so we just |
2118 | /// // print a message and exit |
2119 | /// fn handle_unrecoverable_error(err: UhOhError) -> ! { |
2120 | /// eprintln!("UH OH! {err}" ); |
2121 | /// let code = match err { |
2122 | /// UhOhError::GenericProblem => ExitCode::FAILURE, |
2123 | /// UhOhError::Specific => ExitCode::from(3), |
2124 | /// UhOhError::WithCode { exit_code, .. } => exit_code, |
2125 | /// }; |
2126 | /// code.exit_process() |
2127 | /// } |
2128 | /// ``` |
2129 | #[unstable (feature = "exitcode_exit_method" , issue = "97100" )] |
2130 | pub fn exit_process(self) -> ! { |
2131 | exit(self.to_i32()) |
2132 | } |
2133 | } |
2134 | |
2135 | impl ExitCode { |
2136 | // This is private/perma-unstable because ExitCode is opaque; we don't know that i32 will serve |
2137 | // all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we |
2138 | // likely want to isolate users anything that could restrict the platform specific |
2139 | // representation of an ExitCode |
2140 | // |
2141 | // More info: https://internals.rust-lang.org/t/mini-pre-rfc-redesigning-process-exitstatus/5426 |
2142 | /// Converts an `ExitCode` into an i32 |
2143 | #[unstable ( |
2144 | feature = "process_exitcode_internals" , |
2145 | reason = "exposed only for libstd" , |
2146 | issue = "none" |
2147 | )] |
2148 | #[inline ] |
2149 | #[doc (hidden)] |
2150 | pub fn to_i32(self) -> i32 { |
2151 | self.0.as_i32() |
2152 | } |
2153 | } |
2154 | |
2155 | /// The default value is [`ExitCode::SUCCESS`] |
2156 | #[stable (feature = "process_exitcode_default" , since = "1.75.0" )] |
2157 | impl Default for ExitCode { |
2158 | fn default() -> Self { |
2159 | ExitCode::SUCCESS |
2160 | } |
2161 | } |
2162 | |
2163 | #[stable (feature = "process_exitcode" , since = "1.61.0" )] |
2164 | impl From<u8> for ExitCode { |
2165 | /// Constructs an `ExitCode` from an arbitrary u8 value. |
2166 | fn from(code: u8) -> Self { |
2167 | ExitCode(imp::ExitCode::from(code)) |
2168 | } |
2169 | } |
2170 | |
2171 | impl AsInner<imp::ExitCode> for ExitCode { |
2172 | #[inline ] |
2173 | fn as_inner(&self) -> &imp::ExitCode { |
2174 | &self.0 |
2175 | } |
2176 | } |
2177 | |
2178 | impl FromInner<imp::ExitCode> for ExitCode { |
2179 | fn from_inner(s: imp::ExitCode) -> ExitCode { |
2180 | ExitCode(s) |
2181 | } |
2182 | } |
2183 | |
2184 | impl Child { |
2185 | /// Forces the child process to exit. If the child has already exited, `Ok(())` |
2186 | /// is returned. |
2187 | /// |
2188 | /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function. |
2189 | /// |
2190 | /// This is equivalent to sending a SIGKILL on Unix platforms. |
2191 | /// |
2192 | /// # Examples |
2193 | /// |
2194 | /// ```no_run |
2195 | /// use std::process::Command; |
2196 | /// |
2197 | /// let mut command = Command::new("yes" ); |
2198 | /// if let Ok(mut child) = command.spawn() { |
2199 | /// child.kill().expect("command couldn't be killed" ); |
2200 | /// } else { |
2201 | /// println!("yes command didn't start" ); |
2202 | /// } |
2203 | /// ``` |
2204 | /// |
2205 | /// [`ErrorKind`]: io::ErrorKind |
2206 | /// [`InvalidInput`]: io::ErrorKind::InvalidInput |
2207 | #[stable (feature = "process" , since = "1.0.0" )] |
2208 | #[cfg_attr (not(test), rustc_diagnostic_item = "child_kill" )] |
2209 | pub fn kill(&mut self) -> io::Result<()> { |
2210 | self.handle.kill() |
2211 | } |
2212 | |
2213 | /// Returns the OS-assigned process identifier associated with this child. |
2214 | /// |
2215 | /// # Examples |
2216 | /// |
2217 | /// ```no_run |
2218 | /// use std::process::Command; |
2219 | /// |
2220 | /// let mut command = Command::new("ls" ); |
2221 | /// if let Ok(child) = command.spawn() { |
2222 | /// println!("Child's ID is {}" , child.id()); |
2223 | /// } else { |
2224 | /// println!("ls command didn't start" ); |
2225 | /// } |
2226 | /// ``` |
2227 | #[must_use ] |
2228 | #[stable (feature = "process_id" , since = "1.3.0" )] |
2229 | #[cfg_attr (not(test), rustc_diagnostic_item = "child_id" )] |
2230 | pub fn id(&self) -> u32 { |
2231 | self.handle.id() |
2232 | } |
2233 | |
2234 | /// Waits for the child to exit completely, returning the status that it |
2235 | /// exited with. This function will continue to have the same return value |
2236 | /// after it has been called at least once. |
2237 | /// |
2238 | /// The stdin handle to the child process, if any, will be closed |
2239 | /// before waiting. This helps avoid deadlock: it ensures that the |
2240 | /// child does not block waiting for input from the parent, while |
2241 | /// the parent waits for the child to exit. |
2242 | /// |
2243 | /// # Examples |
2244 | /// |
2245 | /// ```no_run |
2246 | /// use std::process::Command; |
2247 | /// |
2248 | /// let mut command = Command::new("ls" ); |
2249 | /// if let Ok(mut child) = command.spawn() { |
2250 | /// child.wait().expect("command wasn't running" ); |
2251 | /// println!("Child has finished its execution!" ); |
2252 | /// } else { |
2253 | /// println!("ls command didn't start" ); |
2254 | /// } |
2255 | /// ``` |
2256 | #[stable (feature = "process" , since = "1.0.0" )] |
2257 | pub fn wait(&mut self) -> io::Result<ExitStatus> { |
2258 | drop(self.stdin.take()); |
2259 | self.handle.wait().map(ExitStatus) |
2260 | } |
2261 | |
2262 | /// Attempts to collect the exit status of the child if it has already |
2263 | /// exited. |
2264 | /// |
2265 | /// This function will not block the calling thread and will only |
2266 | /// check to see if the child process has exited or not. If the child has |
2267 | /// exited then on Unix the process ID is reaped. This function is |
2268 | /// guaranteed to repeatedly return a successful exit status so long as the |
2269 | /// child has already exited. |
2270 | /// |
2271 | /// If the child has exited, then `Ok(Some(status))` is returned. If the |
2272 | /// exit status is not available at this time then `Ok(None)` is returned. |
2273 | /// If an error occurs, then that error is returned. |
2274 | /// |
2275 | /// Note that unlike `wait`, this function will not attempt to drop stdin. |
2276 | /// |
2277 | /// # Examples |
2278 | /// |
2279 | /// ```no_run |
2280 | /// use std::process::Command; |
2281 | /// |
2282 | /// let mut child = Command::new("ls" ).spawn()?; |
2283 | /// |
2284 | /// match child.try_wait() { |
2285 | /// Ok(Some(status)) => println!("exited with: {status}" ), |
2286 | /// Ok(None) => { |
2287 | /// println!("status not ready yet, let's really wait" ); |
2288 | /// let res = child.wait(); |
2289 | /// println!("result: {res:?}" ); |
2290 | /// } |
2291 | /// Err(e) => println!("error attempting to wait: {e}" ), |
2292 | /// } |
2293 | /// # std::io::Result::Ok(()) |
2294 | /// ``` |
2295 | #[stable (feature = "process_try_wait" , since = "1.18.0" )] |
2296 | pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> { |
2297 | Ok(self.handle.try_wait()?.map(ExitStatus)) |
2298 | } |
2299 | |
2300 | /// Simultaneously waits for the child to exit and collect all remaining |
2301 | /// output on the stdout/stderr handles, returning an `Output` |
2302 | /// instance. |
2303 | /// |
2304 | /// The stdin handle to the child process, if any, will be closed |
2305 | /// before waiting. This helps avoid deadlock: it ensures that the |
2306 | /// child does not block waiting for input from the parent, while |
2307 | /// the parent waits for the child to exit. |
2308 | /// |
2309 | /// By default, stdin, stdout and stderr are inherited from the parent. |
2310 | /// In order to capture the output into this `Result<Output>` it is |
2311 | /// necessary to create new pipes between parent and child. Use |
2312 | /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively. |
2313 | /// |
2314 | /// # Examples |
2315 | /// |
2316 | /// ```should_panic |
2317 | /// use std::process::{Command, Stdio}; |
2318 | /// |
2319 | /// let child = Command::new("/bin/cat" ) |
2320 | /// .arg("file.txt" ) |
2321 | /// .stdout(Stdio::piped()) |
2322 | /// .spawn() |
2323 | /// .expect("failed to execute child" ); |
2324 | /// |
2325 | /// let output = child |
2326 | /// .wait_with_output() |
2327 | /// .expect("failed to wait on child" ); |
2328 | /// |
2329 | /// assert!(output.status.success()); |
2330 | /// ``` |
2331 | /// |
2332 | #[stable (feature = "process" , since = "1.0.0" )] |
2333 | pub fn wait_with_output(mut self) -> io::Result<Output> { |
2334 | drop(self.stdin.take()); |
2335 | |
2336 | let (mut stdout, mut stderr) = (Vec::new(), Vec::new()); |
2337 | match (self.stdout.take(), self.stderr.take()) { |
2338 | (None, None) => {} |
2339 | (Some(mut out), None) => { |
2340 | let res = out.read_to_end(&mut stdout); |
2341 | res.unwrap(); |
2342 | } |
2343 | (None, Some(mut err)) => { |
2344 | let res = err.read_to_end(&mut stderr); |
2345 | res.unwrap(); |
2346 | } |
2347 | (Some(out), Some(err)) => { |
2348 | let res = read2(out.inner, &mut stdout, err.inner, &mut stderr); |
2349 | res.unwrap(); |
2350 | } |
2351 | } |
2352 | |
2353 | let status = self.wait()?; |
2354 | Ok(Output { status, stdout, stderr }) |
2355 | } |
2356 | } |
2357 | |
2358 | /// Terminates the current process with the specified exit code. |
2359 | /// |
2360 | /// This function will never return and will immediately terminate the current |
2361 | /// process. The exit code is passed through to the underlying OS and will be |
2362 | /// available for consumption by another process. |
2363 | /// |
2364 | /// Note that because this function never returns, and that it terminates the |
2365 | /// process, no destructors on the current stack or any other thread's stack |
2366 | /// will be run. If a clean shutdown is needed it is recommended to only call |
2367 | /// this function at a known point where there are no more destructors left |
2368 | /// to run; or, preferably, simply return a type implementing [`Termination`] |
2369 | /// (such as [`ExitCode`] or `Result`) from the `main` function and avoid this |
2370 | /// function altogether: |
2371 | /// |
2372 | /// ``` |
2373 | /// # use std::io::Error as MyError; |
2374 | /// fn main() -> Result<(), MyError> { |
2375 | /// // ... |
2376 | /// Ok(()) |
2377 | /// } |
2378 | /// ``` |
2379 | /// |
2380 | /// In its current implementation, this function will execute exit handlers registered with `atexit` |
2381 | /// as well as other platform-specific exit handlers (e.g. `fini` sections of ELF shared objects). |
2382 | /// This means that Rust requires that all exit handlers are safe to execute at any time. In |
2383 | /// particular, if an exit handler cleans up some state that might be concurrently accessed by other |
2384 | /// threads, it is required that the exit handler performs suitable synchronization with those |
2385 | /// threads. (The alternative to this requirement would be to not run exit handlers at all, which is |
2386 | /// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an |
2387 | /// unsafe operation is not an option.) |
2388 | /// |
2389 | /// ## Platform-specific behavior |
2390 | /// |
2391 | /// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit` |
2392 | /// will be visible to a parent process inspecting the exit code. On most |
2393 | /// Unix-like platforms, only the eight least-significant bits are considered. |
2394 | /// |
2395 | /// For example, the exit code for this example will be `0` on Linux, but `256` |
2396 | /// on Windows: |
2397 | /// |
2398 | /// ```no_run |
2399 | /// use std::process; |
2400 | /// |
2401 | /// process::exit(0x0100); |
2402 | /// ``` |
2403 | /// |
2404 | /// ### Safe interop with C code |
2405 | /// |
2406 | /// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As |
2407 | /// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust |
2408 | /// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior. |
2409 | /// Note that returning from `main` is equivalent to calling `exit`. |
2410 | /// |
2411 | /// Therefore, it is undefined behavior to have two concurrent threads perform the following |
2412 | /// without synchronization: |
2413 | /// - One thread calls Rust's `exit` function or returns from Rust's `main` function |
2414 | /// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function |
2415 | /// |
2416 | /// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining |
2417 | /// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the |
2418 | /// perspective of code running in one of the Rust runtimes, the "outside" Rust code is basically C |
2419 | /// code, and concurrent `exit` again causes undefined behavior. |
2420 | /// |
2421 | /// Individual C implementations might provide more guarantees than the standard and permit concurrent |
2422 | /// calls to `exit`; consult the documentation of your C implementation for details. |
2423 | /// |
2424 | /// For some of the on-going discussion to make `exit` thread-safe in C, see: |
2425 | /// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600) |
2426 | /// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845) |
2427 | /// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997) |
2428 | /// |
2429 | /// [C-exit]: https://en.cppreference.com/w/c/program/exit |
2430 | #[stable (feature = "rust1" , since = "1.0.0" )] |
2431 | #[cfg_attr (not(test), rustc_diagnostic_item = "process_exit" )] |
2432 | pub fn exit(code: i32) -> ! { |
2433 | crate::rt::cleanup(); |
2434 | crate::sys::os::exit(code) |
2435 | } |
2436 | |
2437 | /// Terminates the process in an abnormal fashion. |
2438 | /// |
2439 | /// The function will never return and will immediately terminate the current |
2440 | /// process in a platform specific "abnormal" manner. As a consequence, |
2441 | /// no destructors on the current stack or any other thread's stack |
2442 | /// will be run, Rust IO buffers (eg, from `BufWriter`) will not be flushed, |
2443 | /// and C stdio buffers will (on most platforms) not be flushed. |
2444 | /// |
2445 | /// This is in contrast to the default behavior of [`panic!`] which unwinds |
2446 | /// the current thread's stack and calls all destructors. |
2447 | /// When `panic="abort"` is set, either as an argument to `rustc` or in a |
2448 | /// crate's Cargo.toml, [`panic!`] and `abort` are similar. However, |
2449 | /// [`panic!`] will still call the [panic hook] while `abort` will not. |
2450 | /// |
2451 | /// If a clean shutdown is needed it is recommended to only call |
2452 | /// this function at a known point where there are no more destructors left |
2453 | /// to run. |
2454 | /// |
2455 | /// The process's termination will be similar to that from the C `abort()` |
2456 | /// function. On Unix, the process will terminate with signal `SIGABRT`, which |
2457 | /// typically means that the shell prints "Aborted". |
2458 | /// |
2459 | /// # Examples |
2460 | /// |
2461 | /// ```no_run |
2462 | /// use std::process; |
2463 | /// |
2464 | /// fn main() { |
2465 | /// println!("aborting" ); |
2466 | /// |
2467 | /// process::abort(); |
2468 | /// |
2469 | /// // execution never gets here |
2470 | /// } |
2471 | /// ``` |
2472 | /// |
2473 | /// The `abort` function terminates the process, so the destructor will not |
2474 | /// get run on the example below: |
2475 | /// |
2476 | /// ```no_run |
2477 | /// use std::process; |
2478 | /// |
2479 | /// struct HasDrop; |
2480 | /// |
2481 | /// impl Drop for HasDrop { |
2482 | /// fn drop(&mut self) { |
2483 | /// println!("This will never be printed!" ); |
2484 | /// } |
2485 | /// } |
2486 | /// |
2487 | /// fn main() { |
2488 | /// let _x = HasDrop; |
2489 | /// process::abort(); |
2490 | /// // the destructor implemented for HasDrop will never get run |
2491 | /// } |
2492 | /// ``` |
2493 | /// |
2494 | /// [panic hook]: crate::panic::set_hook |
2495 | #[stable (feature = "process_abort" , since = "1.17.0" )] |
2496 | #[cold ] |
2497 | #[cfg_attr (not(test), rustc_diagnostic_item = "process_abort" )] |
2498 | pub fn abort() -> ! { |
2499 | crate::sys::abort_internal(); |
2500 | } |
2501 | |
2502 | /// Returns the OS-assigned process identifier associated with this process. |
2503 | /// |
2504 | /// # Examples |
2505 | /// |
2506 | /// ```no_run |
2507 | /// use std::process; |
2508 | /// |
2509 | /// println!("My pid is {}" , process::id()); |
2510 | /// ``` |
2511 | #[must_use ] |
2512 | #[stable (feature = "getpid" , since = "1.26.0" )] |
2513 | pub fn id() -> u32 { |
2514 | crate::sys::os::getpid() |
2515 | } |
2516 | |
2517 | /// A trait for implementing arbitrary return types in the `main` function. |
2518 | /// |
2519 | /// The C-main function only supports returning integers. |
2520 | /// So, every type implementing the `Termination` trait has to be converted |
2521 | /// to an integer. |
2522 | /// |
2523 | /// The default implementations are returning `libc::EXIT_SUCCESS` to indicate |
2524 | /// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned. |
2525 | /// |
2526 | /// Because different runtimes have different specifications on the return value |
2527 | /// of the `main` function, this trait is likely to be available only on |
2528 | /// standard library's runtime for convenience. Other runtimes are not required |
2529 | /// to provide similar functionality. |
2530 | #[cfg_attr (not(any(test, doctest)), lang = "termination" )] |
2531 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2532 | #[rustc_on_unimplemented (on( |
2533 | cause = "MainFunctionType" , |
2534 | message = "`main` has invalid return type `{Self}`" , |
2535 | label = "`main` can only return types that implement `{This}`" |
2536 | ))] |
2537 | pub trait Termination { |
2538 | /// Is called to get the representation of the value as status code. |
2539 | /// This status code is returned to the operating system. |
2540 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2541 | fn report(self) -> ExitCode; |
2542 | } |
2543 | |
2544 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2545 | impl Termination for () { |
2546 | #[inline ] |
2547 | fn report(self) -> ExitCode { |
2548 | ExitCode::SUCCESS |
2549 | } |
2550 | } |
2551 | |
2552 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2553 | impl Termination for ! { |
2554 | fn report(self) -> ExitCode { |
2555 | self |
2556 | } |
2557 | } |
2558 | |
2559 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2560 | impl Termination for Infallible { |
2561 | fn report(self) -> ExitCode { |
2562 | match self {} |
2563 | } |
2564 | } |
2565 | |
2566 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2567 | impl Termination for ExitCode { |
2568 | #[inline ] |
2569 | fn report(self) -> ExitCode { |
2570 | self |
2571 | } |
2572 | } |
2573 | |
2574 | #[stable (feature = "termination_trait_lib" , since = "1.61.0" )] |
2575 | impl<T: Termination, E: fmt::Debug> Termination for Result<T, E> { |
2576 | fn report(self) -> ExitCode { |
2577 | match self { |
2578 | Ok(val: T) => val.report(), |
2579 | Err(err: E) => { |
2580 | io::attempt_print_to_stderr(args:format_args_nl!("Error: {err:?}" )); |
2581 | ExitCode::FAILURE |
2582 | } |
2583 | } |
2584 | } |
2585 | } |
2586 | |