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