Rollup merge of #97917 - AronParker:master, r=ChrisDenton
Implement ExitCodeExt for Windows Fixes #97914 ### Motivation: On Windows it is common for applications to return `HRESULT` (`i32`) or `DWORD` (`u32`) values. These stem from COM based components ([HRESULTS](https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize)), Win32 errors ([GetLastError](https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-getlasterror)), GUI applications ([WM_QUIT](https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-quit)) and more. The newly stabilized `ExitCode` provides an excellent fit for propagating these values, because `std::process::exit` does not run deconstructors which can result in errors. However, `ExitCode` currently only implements `From<u8> for ExitCode`, which disallows the full range of `i32`/`u32` values. This pull requests attempts to address that shortcoming by providing windows specific extensions that accept a `u32` value (which covers all possible `HRESULTS` and Win32 errors) analog to [ExitStatusExt::from_raw](https://doc.rust-lang.org/std/os/windows/process/trait.ExitStatusExt.html#tymethod.from_raw). This was also intended by the original Stabilization https://github.com/rust-lang/rust/pull/93840#issue-1129209143= as pointed out by ``@eggyal`` in https://github.com/rust-lang/rust/issues/97914#issuecomment-1151076755: > Issues around platform specific representations: We resolved this issue by changing the return type of report from i32 to the opaque type ExitCode. __That way we can change the underlying representation without affecting the API, letting us offer full support for platform specific exit code APIs in the future.__ [Emphasis added] ### API ```rust /// Windows-specific extensions to [`process::ExitCode`]. /// /// 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 = "windows_process_exit_code_from", since = "1.63.0")] pub trait ExitCodeExt: Sealed { /// Creates a new `ExitCode` from the raw underlying `u32` return value of /// a process. #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] fn from_raw(raw: u32) -> Self; } #[stable(feature = "windows_process_exit_code_from", since = "1.63.0")] impl ExitCodeExt for process::ExitCode { fn from_raw(raw: u32) -> Self { process::ExitCode::from_inner(From::from(raw)) } } ``` ### Misc I apologize in advance if I misplaced any attributes regarding stabilzation, as far as I learned traits are insta-stable so I chose to make them stable. If this is an error, please let me know and I'll correct it. I also added some additional machinery to make it work, analog to [ExitStatus](https://doc.rust-lang.org/std/process/struct.ExitStatus.html#). EDIT: Proposal: https://github.com/rust-lang/libs-team/issues/48
This commit is contained in:
commit
6826f33168
3 changed files with 45 additions and 0 deletions
|
@ -234,3 +234,26 @@ impl ChildExt for process::Child {
|
|||
self.handle.main_thread_handle()
|
||||
}
|
||||
}
|
||||
|
||||
/// Windows-specific extensions to [`process::ExitCode`].
|
||||
///
|
||||
/// This trait is sealed: it cannot be implemented outside the standard library.
|
||||
/// This is so that future additional methods are not breaking changes.
|
||||
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
|
||||
pub trait ExitCodeExt: Sealed {
|
||||
/// Creates a new `ExitCode` from the raw underlying `u32` return value of
|
||||
/// a process.
|
||||
///
|
||||
/// The exit code should not be 259, as this conflicts with the `STILL_ACTIVE`
|
||||
/// macro returned from the `GetExitCodeProcess` function to signal that the
|
||||
/// process has yet to run to completion.
|
||||
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
|
||||
fn from_raw(raw: u32) -> Self;
|
||||
}
|
||||
|
||||
#[unstable(feature = "windows_process_exit_code_from", issue = "none")]
|
||||
impl ExitCodeExt for process::ExitCode {
|
||||
fn from_raw(raw: u32) -> Self {
|
||||
process::ExitCode::from_inner(From::from(raw))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1724,6 +1724,10 @@ impl crate::error::Error for ExitStatusError {}
|
|||
#[stable(feature = "process_exitcode", since = "1.61.0")]
|
||||
pub struct ExitCode(imp::ExitCode);
|
||||
|
||||
/// Allows extension traits within `std`.
|
||||
#[unstable(feature = "sealed", issue = "none")]
|
||||
impl crate::sealed::Sealed for ExitCode {}
|
||||
|
||||
#[stable(feature = "process_exitcode", since = "1.61.0")]
|
||||
impl ExitCode {
|
||||
/// The canonical `ExitCode` for successful termination on this platform.
|
||||
|
@ -1814,6 +1818,18 @@ impl From<u8> for ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
impl AsInner<imp::ExitCode> for ExitCode {
|
||||
fn as_inner(&self) -> &imp::ExitCode {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl FromInner<imp::ExitCode> for ExitCode {
|
||||
fn from_inner(s: imp::ExitCode) -> ExitCode {
|
||||
ExitCode(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl Child {
|
||||
/// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
|
||||
/// error is returned.
|
||||
|
|
|
@ -707,6 +707,12 @@ impl From<u8> for ExitCode {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<u32> for ExitCode {
|
||||
fn from(code: u32) -> Self {
|
||||
ExitCode(c::DWORD::from(code))
|
||||
}
|
||||
}
|
||||
|
||||
fn zeroed_startupinfo() -> c::STARTUPINFO {
|
||||
c::STARTUPINFO {
|
||||
cb: 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue