`ExitStatus::exit_code`
Nobody has claimed this yet.
Assessment
- Difficulty
- 5/5
- Estimated time
- Over a week
- Newbie friendliness
- 35/100
Research direction
This is an API change proposal for Rust’s standard library, with no implementation files or tests identified. Read the feature lifecycle guidance and linked Zulip discussion first; the issue says the libs-api team must review the proposal before implementation. Done would require an accepted API design, followed by implementation and tests in a later contribution.
Written by the indexing model from the issue text.
Description
Proposal
Problem statement
There's no good way to convert an ExitStatus to an ExitCode cross-platform. More generally, there's no way to pass on a c_int exit code without knowing platform details.
Motivating examples or use cases
use std::process::{Command, ExitCode};
fn main() -> ExitCode {
let status = Command::new("foo").status().expect("failed to run command");
if status.success() {
ExitCode::SUCCESS
} else {
eprintln!("running foo failed: {status:?}");
if let Some(code) = status.code() {
// I sure hope this is right for all platforms...
cfg_select! {
windows => {
use std::os::windows::process::ExitCodeExt;
ExitCode::from_raw(code)
}
_ => ExitCode::from(code as u8),
}
} else {
ExitCode::FAILURE
}
}
}
Solution sketch
Provide an alternative to ExitStatus::code that returns an ExitCode type.
impl ExitStatus {
/// The same as `ExitStatus::code` except that it returns an `ExitCode` instead of an `i32`.
pub fn exit_code(&self) -> Option<ExitCode>;
}
Rewriting the above motivating code:
use std::process::{Command, ExitCode};
fn main() -> ExitCode {
let status = Command::new("foo").status().expect("failed to run command");
if status.success() {
ExitCode::SUCCESS
} else {
eprintln!("running foo failed: {status:?}");
status.exit_code().unwrap_or(ExitCode::FAILURE)
}
I would also propose some way to construct an ExitCode from a c_int. As you may know, C's main is int main so this should make at least some sense for every std target. And even exotic targets must support at least ExitCode::SUCCESS and ExitCode::FAILURE so in the worst case we can fallback to using code != 0 to select the exit code.
impl ExitCode {
/// Create an `ExitCode` from a `c_int`. This is potentially lossy.
pub const fn new(code: core::ffi::c_int) -> Self;
}
Though maybe it should have a more evocative name because of the cross-platform compatibility hazard (e.g. from_c_int_lossy). However, status and process::exit use i32 without any fuss. Then again, maybe that was a mistake.
Alternatives
- https://github.com/rust-lang/libs-team/issues/729 which I now don't think is the best design, having played with it a bit more.
Links and related work
#t-libs > `ExitStatus::exit_code` @ 💬
What happens now?
This issue contains an API change proposal (or ACP) and is part of the libs-api team feature lifecycle. Once this issue is filed, the libs-api team will review open proposals as capability becomes available. Current response times do not have a clear estimate, but may be up to several months.
Possible responses
The libs team may respond in various different ways. First, the team will consider the problem (this doesn't require any concrete solution or alternatives to have been proposed):
- We think this problem seems worth solving, and the standard library might be the right place to solve it.
- We think that this probably doesn't belong in the standard library.
Second, if there's a concrete solution:
- We think this specific solution looks roughly right, approved, you or someone else should implement this. (Further review will still happen on the subsequent implementation PR.)
- We're not sure this is the right solution, and the alternatives or other materials don't give us enough information to be sure about that. Here are some questions we have that aren't answered, or rough ideas about alternatives we'd want to see discussed.
- Dominant language
- Rust
- Stars
- 188
- Forks
- 28
- Avg merge
- 23h 50m
- Merged PRs (30d)
- 7
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rust-lang/libs-team
-
api-change-proposal T-libs
Difficulty 5/5 Over a week Newbie friendliness 30/100
-
api-change-proposal T-libs
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
ACP: `Path::len`Openapi-change-proposal T-libs
Difficulty 5/5 Over a week Newbie friendliness 30/100
-
api-change-proposal T-libs
Difficulty 5/5 Over a week Newbie friendliness 30/100
-
api-change-proposal T-libs
Difficulty 5/5 Over a week Newbie friendliness 30/100
All issues in rust-lang/libs-team
Similar issues
-
good first issue help wanted program
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
hffgzktbcc-blip/ounce-core#297 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
nautechsystems/nautilus_trader#5631 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 69/100
bytecodealliance/rustix#1736 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
longbridge/gpui-kit#3871 ·
Maintainers usually reply within 1 day
-
area:models enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day