Implement ExitCodeExt for Windows · Issue #48 · rust-lang/libs-team (original) (raw)
Proposal
Problem statement
On Windows it is common for applications to return HRESULT
(i32
) or DWORD
(u32
) values. The newly stabilized ExitCode
provides an excellent fit for propagating these values, because std::process::exit
exits immediately and 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 proposal 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.
Motivation, use-cases
- COM based components as well as newer Win32 based-functions make extensive use of HRESULT (
i32
) values, which is a universal success and error code on Windows designed to represent every error code from multiple facilities. - GUI applications use a message loop to process their events. On windows, once the WM_QUIT message has been received, the application is requested to return the exit code in
wParam
, which was originally sent using the PostQuitMessage function. It takes ani32
, which is to be returned from main. Usingstd::process::exit
can result in error conditions such as an unhandled exception 0x80000003 inside the ExitProcess function. In contrast, usingExitCode
allows running all destructors and unregistering window classes which prevent the exception. - Win32 errors (system error codes) received by GetLastError are also popular to return as an exit code, which do not fit inside an
u8
.
Solution sketches
/// 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.
///
/// 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.
#[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)) } }