diff options
author | bors <bors@rust-lang.org> | 2021-05-18 08:01:32 +0000 |
---|---|---|
committer | bors <bors@rust-lang.org> | 2021-05-18 08:01:32 +0000 |
commit | 25a277f03df7e44643ddfcc240d034409cb2f505 (patch) | |
tree | c4f00d62c473f44d09ccb147ead2775ce280628d /library/std/src/sys/unix/process/process_unix.rs | |
parent | 5f10d310f475b3ba583b9c590b8d19f6c2fde28f (diff) | |
parent | 26c782b8e7f939a00f889dfb3f1e969fc8f8c79d (diff) | |
download | rust-25a277f03df7e44643ddfcc240d034409cb2f505.tar.gz |
Auto merge of #82973 - ijackson:exitstatuserror, r=yaahc
Provide ExitStatusError
Closes #73125
In MR #81452 "Add #[must_use] to [...] process::ExitStatus" we concluded that the existing arrangements in are too awkward so adding that `#[must_use]` is blocked on improving the ergonomics.
I wrote a mini-RFC-style discusion of the approach in https://github.com/rust-lang/rust/issues/73125#issuecomment-771092741
Diffstat (limited to 'library/std/src/sys/unix/process/process_unix.rs')
-rw-r--r-- | library/std/src/sys/unix/process/process_unix.rs | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 08b500b9c82..7f8065e7500 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -1,7 +1,9 @@ -use crate::convert::TryInto; +use crate::convert::{TryFrom, TryInto}; use crate::fmt; use crate::io::{self, Error, ErrorKind}; use crate::mem; +use crate::num::NonZeroI32; +use crate::os::raw::NonZero_c_int; use crate::ptr; use crate::sys; use crate::sys::cvt; @@ -491,8 +493,16 @@ impl ExitStatus { libc::WIFEXITED(self.0) } - pub fn success(&self) -> bool { - self.code() == Some(0) + pub fn exit_ok(&self) -> Result<(), ExitStatusError> { + // This assumes that WIFEXITED(status) && WEXITSTATUS==0 corresponds to status==0. This is + // true on all actual versios of Unix, is widely assumed, and is specified in SuS + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html . If it is not + // true for a platform pretending to be Unix, the tests (our doctests, and also + // procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. + match NonZero_c_int::try_from(self.0) { + /* was nonzero */ Ok(failure) => Err(ExitStatusError(failure)), + /* was zero, couldn't convert */ Err(_) => Ok(()), + } } pub fn code(&self) -> Option<i32> { @@ -547,6 +557,21 @@ impl fmt::Display for ExitStatus { } } +#[derive(PartialEq, Eq, Clone, Copy, Debug)] +pub struct ExitStatusError(NonZero_c_int); + +impl Into<ExitStatus> for ExitStatusError { + fn into(self) -> ExitStatus { + ExitStatus(self.0.into()) + } +} + +impl ExitStatusError { + pub fn code(self) -> Option<NonZeroI32> { + ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap()) + } +} + #[cfg(test)] #[path = "process_unix/tests.rs"] mod tests; |