Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 11f6c04

Browse files
committed
Add ExitStatusExt::aborted_code for Fuchsia platform
1 parent 7e763af commit 11f6c04

File tree

5 files changed

+57
-19
lines changed

5 files changed

+57
-19
lines changed

‎library/std/src/os/fuchsia/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,6 @@
33
#![stable(feature = "raw_ext", since = "1.1.0")]
44

55
pub mod fs;
6+
#[unstable(feature = "fuchsia_exit_status_aborted", issue = "none")]
7+
pub mod process;
68
pub mod raw;

‎library/std/src/os/fuchsia/process.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//! Fuchsia-specific extensions to primitives in the [`std::process`] module.
2+
//!
3+
//! [`std::process`]: crate::process
4+
5+
use crate::process;
6+
use crate::sealed::Sealed;
7+
8+
// On Zircon (the Fuchsia kernel), an abort from userspace calls the
9+
// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
10+
// raises a kernel exception. If a userspace process does not
11+
// otherwise arrange exception handling, the kernel kills the process
12+
// with this return code.
13+
const ZX_TASK_RETCODE_EXCEPTION_KILL: i32 = -1028;
14+
15+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
16+
pub trait ExitStatusExt: Sealed {
17+
/// If the process was aborted, returns the status code.
18+
#[must_use]
19+
fn aborted_code(&self) -> Option<i32>;
20+
}
21+
22+
#[unstable(feature = "fuchsia_exit_status", issue = "none")]
23+
impl ExitStatusExt for process::ExitStatus {
24+
/// If the process was aborted, returns the status code.
25+
fn aborted_code(&self) -> Option<i32> {
26+
match self.code() {
27+
code @ Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => code,
28+
Some(_) | None => None,
29+
}
30+
}
31+
}

‎library/test/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#![feature(process_exitcode_internals)]
2424
#![feature(panic_can_unwind)]
2525
#![feature(test)]
26+
#![cfg_attr(target_os = "fuchsia", feature(fuchsia_exit_status))]
2627
#![allow(internal_features)]
2728

2829
// Public reexports

‎library/test/src/test_result.rs

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
use std::any::Any;
22
use std::process::ExitStatus;
33

4+
#[cfg(target_os = "fuchsia")]
5+
use std::os::fuchsia::process::ExitStatusExt as _;
46
#[cfg(unix)]
5-
use std::os::unix::process::ExitStatusExt;
7+
use std::os::unix::process::ExitStatusExtas _;
68

79
use super::bench::BenchSamples;
810
use super::options::ShouldPanic;
@@ -21,14 +23,6 @@ pub const TR_OK: i32 = 50;
2123
#[cfg(windows)]
2224
const STATUS_FAIL_FAST_EXCEPTION: i32 = 0xC0000409u32 as i32;
2325

24-
// On Zircon (the Fuchsia kernel), an abort from userspace calls the
25-
// LLVM implementation of __builtin_trap(), e.g., ud2 on x86, which
26-
// raises a kernel exception. If a userspace process does not
27-
// otherwise arrange exception handling, the kernel kills the process
28-
// with this return code.
29-
#[cfg(target_os = "fuchsia")]
30-
const ZX_TASK_RETCODE_EXCEPTION_KILL: i32 = -1028;
31-
3226
#[derive(Debug, Clone, PartialEq)]
3327
pub enum TestResult {
3428
TrOk,
@@ -101,10 +95,19 @@ pub fn get_result_from_exit_code(
10195
time_opts: &Option<time::TestTimeOptions>,
10296
exec_time: &Option<time::TestExecTime>,
10397
) -> TestResult {
104-
let result = match status.code() {
98+
#[cfg(target_os = "fuchsia")]
99+
let result = status.aborted_code().map(|_| TestResult::TrFailed);
100+
#[cfg(not(target_os = "fuchsia"))]
101+
let result: Option<TestResult> = None;
102+
103+
let result = result.unwrap_or_else(|| match status.code() {
105104
Some(TR_OK) => TestResult::TrOk,
106105
#[cfg(windows)]
107106
Some(STATUS_FAIL_FAST_EXCEPTION) => TestResult::TrFailed,
107+
#[cfg(any(windows, unix))]
108+
Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")),
109+
#[cfg(not(any(windows, unix)))]
110+
Some(_) => TestResult::TrFailed,
108111
#[cfg(unix)]
109112
None => match status.signal() {
110113
Some(libc::SIGABRT) => TestResult::TrFailed,
@@ -113,16 +116,9 @@ pub fn get_result_from_exit_code(
113116
}
114117
None => unreachable!("status.code() returned None but status.signal() was None"),
115118
},
116-
// Upon an abort, Fuchsia returns the status code ZX_TASK_RETCODE_EXCEPTION_KILL.
117-
#[cfg(target_os = "fuchsia")]
118-
Some(ZX_TASK_RETCODE_EXCEPTION_KILL) => TestResult::TrFailed,
119119
#[cfg(not(unix))]
120120
None => TestResult::TrFailedMsg(format!("unknown return code")),
121-
#[cfg(any(windows, unix))]
122-
Some(code) => TestResult::TrFailedMsg(format!("got unexpected return code {code}")),
123-
#[cfg(not(any(windows, unix)))]
124-
Some(_) => TestResult::TrFailed,
125-
};
121+
});
126122

127123
// If test is already failed (or allowed to fail), do not change the result.
128124
if result != TestResult::TrOk {

‎tests/ui/process/signal-exit-status.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,28 @@
22
//@ ignore-wasm32 no processes
33
//@ ignore-sgx no processes
44
//@ ignore-windows
5-
//@ ignore-fuchsia code returned as ZX_TASK_RETCODE_EXCEPTION_KILL, FIXME (#58590)
65

76
#![feature(core_intrinsics)]
7+
#![cfg_attr(target_os = "fuchsia", feature(fuchsia_exit_status_aborted))]
88

99
use std::env;
1010
use std::process::Command;
1111

12+
#[cfg(target_os = "fuchsia")]
13+
use std::os::fuchsia::process::ExitStatusExt;
14+
1215
pub fn main() {
1316
let args: Vec<String> = env::args().collect();
1417
if args.len() >= 2 && args[1] == "signal" {
1518
// Raise an aborting signal without UB
1619
core::intrinsics::abort();
1720
} else {
21+
// Spawn a child process that will raise an aborting signal
1822
let status = Command::new(&args[0]).arg("signal").status().unwrap();
23+
24+
#[cfg(not(target_os = "fuchsia"))]
1925
assert!(status.code().is_none());
26+
#[cfg(target_os = "fuchsia")]
27+
assert!(status.aborted_code().is_some());
2028
}
2129
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /