}
}
-/// Unix-specific extensions to [`process::ExitStatus`].
+/// Unix-specific extensions to [`process::ExitStatus`] and
+/// [`ExitStatusError`](process::ExitStatusError).
///
-/// On Unix, `ExitStatus` **does not necessarily represent an exit status**, as passed to the
-/// `exit` system call or returned by [`ExitStatus::code()`](crate::process::ExitStatus::code).
-/// It represents **any wait status**, as returned by one of the `wait` family of system calls.
+/// On Unix, `ExitStatus` and `ExitStatusError` **do not necessarily represent an exit status**, as
+/// passed to the `exit` system call or returned by
+/// [`ExitStatus::code()`](crate::process::ExitStatus::code). They represents **any wait status**
+/// (or any nonzero wait status, respectively), as returned by one of the `wait` family of system
+/// calls.
///
-/// This is because a Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but
-/// can also represent other kinds of process event.
+/// A Unix wait status (a Rust `ExitStatus`) can represent a Unix exit status, but can also
+/// represent other kinds of process event.
///
/// This trait is sealed: it cannot be implemented outside the standard library.
/// This is so that future additional methods are not breaking changes.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait ExitStatusExt: Sealed {
- /// Creates a new `ExitStatus` from the raw underlying integer status value from `wait`
+ /// Creates a new `ExitStatus` or `ExitStatusError` from the raw underlying integer status
+ /// value from `wait`
///
/// The value should be a **wait status, not an exit status**.
+ ///
+ /// # Panics
+ ///
+ /// Panics on an attempt to make an `ExitStatusError` from a wait status of `0`.
+ ///
+ /// Making an `ExitStatus` always succeds and never panics.
#[stable(feature = "exit_status_from", since = "1.12.0")]
fn from_raw(raw: i32) -> Self;
/// If the process was terminated by a signal, returns that signal.
///
/// In other words, if `WIFSIGNALED`, this returns `WTERMSIG`.
+ ///
+ /// # Examples
+ /// ```
+ /// #![feature(exit_status_error)]
+ /// use std::process::{Command, ExitStatusError};
+ /// use std::os::unix::process::ExitStatusExt;
+ ///
+ /// fn run(script: &str) -> Result<(), ExitStatusError> {
+ /// Command::new("sh").args(&["-ec",script])
+ /// .status().expect("failed to fork/exec sh")
+ /// .exit_ok()
+ /// .or_else(|bad| {
+ /// if bad.signal() == Some(13) /*PIPE*/ {
+ /// Ok(())
+ /// } else {
+ /// Err(bad)
+ /// }
+ /// })
+ /// }
+ ///
+ /// run("exit").unwrap();
+ /// run("kill -PIPE $$").unwrap();
+ /// run("exit 42").unwrap_err();
+ /// ```
#[stable(feature = "rust1", since = "1.0.0")]
fn signal(&self) -> Option<i32>;
}
}
+#[unstable(feature = "exit_status_error", issue = "84908")]
+impl ExitStatusExt for process::ExitStatusError {
+ fn from_raw(raw: i32) -> Self {
+ process::ExitStatus::from_raw(raw)
+ .exit_ok()
+ .expect_err("<ExitStatusError as ExitStatusExt>::from_raw(0) but zero is not an error")
+ }
+
+ fn signal(&self) -> Option<i32> {
+ self.into_status().signal()
+ }
+
+ fn core_dumped(&self) -> bool {
+ self.into_status().core_dumped()
+ }
+
+ fn stopped_signal(&self) -> Option<i32> {
+ self.into_status().stopped_signal()
+ }
+
+ fn continued(&self) -> bool {
+ self.into_status().continued()
+ }
+
+ fn into_raw(self) -> i32 {
+ self.into_status().into_raw()
+ }
+}
+
#[stable(feature = "process_extensions", since = "1.2.0")]
impl FromRawFd for process::Stdio {
#[inline]
}
}
+/// Allows extension traits within `std`.
+#[unstable(feature = "sealed", issue = "none")]
+impl crate::sealed::Sealed for ExitStatusError {}
+
/// Describes the result of a process after it has failed
///
/// Produced by the [`.exit_ok`](ExitStatus::exit_ok) method on [`ExitStatus`].
/// runtime system (often, for example, 255, 254, 127 or 126).
///
/// On Unix, this will return `None` if the process was terminated by a signal. If you want to
- /// handle such situations specially, consider using
- /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) (possibly after getting the
- /// general `ExitStatus` by using [`status()`](ExitStatusError::status).
+ /// handle such situations specially, consider using methods from
+ /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt).
///
/// If the process finished by calling `exit` with a nonzero value, this will return
/// that exit status.