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