|
| 1 | +use crate::convert::{TryFrom, TryInto}; |
1 | 2 | use crate::fmt;
|
2 | 3 | use crate::io::{self, Error, ErrorKind};
|
| 4 | +use crate::num::NonZeroI32; |
| 5 | +use crate::os::raw::NonZero_c_int; |
3 | 6 | use crate::sys;
|
4 | 7 | use crate::sys::cvt;
|
5 | 8 | use crate::sys::process::process_common::*;
|
@@ -187,8 +190,16 @@ impl ExitStatus {
|
187 | 190 | libc::WIFEXITED(self.0)
|
188 | 191 | }
|
189 | 192 |
|
190 |
| - pub fn success(&self) -> bool { |
191 |
| - self.code() == Some(0) |
| 193 | + pub fn exit_ok(&self) -> Result<(), ExitStatusError> { |
| 194 | + // This assumes that WIFEXITED(status) && WEXITSTATUS==0 corresponds to status==0. This is |
| 195 | + // true on all actual versions of Unix, is widely assumed, and is specified in SuS |
| 196 | + // https://pubs.opengroup.org/onlinepubs/9699919799/functions/wait.html . If it is not |
| 197 | + // true for a platform pretending to be Unix, the tests (our doctests, and also |
| 198 | + // procsss_unix/tests.rs) will spot it. `ExitStatusError::code` assumes this too. |
| 199 | + match NonZero_c_int::try_from(self.0) { |
| 200 | + Ok(failure) => Err(ExitStatusError(failure)), |
| 201 | + Err(_) => Ok(()), |
| 202 | + } |
192 | 203 | }
|
193 | 204 |
|
194 | 205 | pub fn code(&self) -> Option<i32> {
|
@@ -235,3 +246,18 @@ impl fmt::Display for ExitStatus {
|
235 | 246 | }
|
236 | 247 | }
|
237 | 248 | }
|
| 249 | + |
| 250 | +#[derive(PartialEq, Eq, Clone, Copy, Debug)] |
| 251 | +pub struct ExitStatusError(NonZero_c_int); |
| 252 | + |
| 253 | +impl Into<ExitStatus> for ExitStatusError { |
| 254 | + fn into(self) -> ExitStatus { |
| 255 | + ExitStatus(self.0.into()) |
| 256 | + } |
| 257 | +} |
| 258 | + |
| 259 | +impl ExitStatusError { |
| 260 | + pub fn code(self) -> Option<NonZeroI32> { |
| 261 | + ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap()) |
| 262 | + } |
| 263 | +} |
0 commit comments