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