Skip to content

Commit

Permalink
Auto merge of #95356 - coolreader18:exitstatus-exit-method, r=<try>
Browse files Browse the repository at this point in the history
ExitCode::exit_process() method

cc `@yaahc` / #93840

(eeek, hit ctrl-enter before I meant to and right after realizing the branch name was wrong. oh, well)

I feel like it makes sense to have the `exit(ExitCode)` function as a method or at least associated function on ExitCode, but maybe that would hurt discoverability? Probably not as much if it's at the top of the `process::exit()` documentation or something, but idk. Also very unsure about the name, I'd like something that communicates that you are exiting with *this* ExitCode, but with a method name being postfix it doesn't seem to flow. `code.exit_process_with()` ? `.exit_process_with_self()` ? Blech. Maybe it doesn't matter, since ideally just `code.exit()` or something would be clear simply by the name and single parameter but 🤷

Also I'd like to touch up the `ExitCode` docs (which I did a bit here), but that would probably be good in a separate PR, right? Since I think the beta deadline is coming up.
  • Loading branch information
bors committed May 13, 2022
2 parents a7d6408 + a9e29d2 commit 9ad4bde
Showing 1 changed file with 56 additions and 28 deletions.
84 changes: 56 additions & 28 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,49 @@ impl ExitCode {
/// return the same codes (but will also `eprintln!` the error).
#[stable(feature = "process_exitcode", since = "1.61.0")]
pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);

/// Exit the current process with the given `ExitCode`.
///
/// Note that this has the same caveats as [`process::exit()`][exit], namely that this function
/// terminates the process immediately, so no destructors on the current stack or any other
/// thread's stack will be run. If a clean shutdown is needed, it is recommended to simply
/// return this ExitCode from the `main` function, as demonstrated in the [type
/// documentation](#examples).
///
/// # Differences from `process::exit()`
///
/// `process::exit()` accepts any `i32` value as the exit code for the process; however, there
/// are platforms that only use a subset of that value (see [`process::exit` platform-specific
/// behavior][exit#platform-specific-behavior]). `ExitCode` exists because of this; only
/// `ExitCode`s that are supported by a majority of our platforms can be created, so those
/// problems don't exist (as much) with this method.
///
/// # Examples
///
/// ```
/// #![feature(exitcode_exit_method)]
/// # use std::process::ExitCode;
/// # use std::fmt;
/// # enum UhOhError { GenericProblem, Specific, WithCode { exit_code: ExitCode, _x: () } }
/// # impl fmt::Display for UhOhError {
/// # fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result { unimplemented!() }
/// # }
/// // there's no way to gracefully recover from an UhOhError, so we just
/// // print a message and exit
/// fn handle_unrecoverable_error(err: UhOhError) -> ! {
/// eprintln!("UH OH! {err}");
/// let code = match err {
/// UhOhError::GenericProblem => ExitCode::FAILURE,
/// UhOhError::Specific => ExitCode::from(3),
/// UhOhError::WithCode { exit_code, .. } => exit_code,
/// };
/// code.exit_process()
/// }
/// ```
#[unstable(feature = "exitcode_exit_method", issue = "none")]
pub fn exit_process(self) -> ! {
exit(self.to_i32())
}
}

impl ExitCode {
Expand Down Expand Up @@ -1944,47 +1987,32 @@ impl Child {
/// process, no destructors on the current stack or any other thread's stack
/// will be run. If a clean shutdown is needed it is recommended to only call
/// this function at a known point where there are no more destructors left
/// to run.
/// to run; or, preferably, simply return a type implementing [`Termination`]
/// (such as [`ExitCode`] or `Result`) from the `main` function and avoid this
/// function altogether:
///
/// ```
/// # use std::io::Error as MyError;
/// fn main() -> Result<(), MyError> {
/// // ...
/// Ok(())
/// }
/// ```
///
/// ## Platform-specific behavior
///
/// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`
/// will be visible to a parent process inspecting the exit code. On most
/// Unix-like platforms, only the eight least-significant bits are considered.
///
/// # Examples
///
/// Due to this function’s behavior regarding destructors, a conventional way
/// to use the function is to extract the actual computation to another
/// function and compute the exit code from its return value:
///
/// ```
/// fn run_app() -> Result<(), ()> {
/// // Application logic here
/// Ok(())
/// }
///
/// fn main() {
/// std::process::exit(match run_app() {
/// Ok(_) => 0,
/// Err(err) => {
/// eprintln!("error: {err:?}");
/// 1
/// }
/// });
/// }
/// ```
///
/// Due to [platform-specific behavior], the exit code for this example will be
/// `0` on Linux, but `256` on Windows:
/// For example, the exit code for this example will be `0` on Linux, but `256`
/// on Windows:
///
/// ```no_run
/// use std::process;
///
/// process::exit(0x0100);
/// ```
///
/// [platform-specific behavior]: #platform-specific-behavior
#[stable(feature = "rust1", since = "1.0.0")]
pub fn exit(code: i32) -> ! {
crate::rt::cleanup();
Expand Down

0 comments on commit 9ad4bde

Please sign in to comment.