diff --git a/library/std/src/sys/yggdrasil/mod.rs b/library/std/src/sys/yggdrasil/mod.rs index bc13579c34d..d6ef497fedc 100644 --- a/library/std/src/sys/yggdrasil/mod.rs +++ b/library/std/src/sys/yggdrasil/mod.rs @@ -1,3 +1,4 @@ +#![allow(unused)] #![allow(nonstandard_style)] use crate::io::ErrorKind; @@ -28,6 +29,7 @@ pub mod time; pub(self) use yggdrasil_rt; +use yggdrasil_rt::process::{ExitCode as OsExitCode, Signal as OsSignal, SignalEntryData}; use yggdrasil_rt::Error as OsError; use crate::path::Path; @@ -156,6 +158,34 @@ pub fn decode_error_kind(_errno: i32) -> ErrorKind { loop {} } +const SIGNAL_STACK_SIZE: usize = 16384; + +#[repr(C, align(0x10))] +struct SignalStack { + data: [u8; SIGNAL_STACK_SIZE], +} +static mut SIGNAL_STACK: SignalStack = SignalStack { data: [0; SIGNAL_STACK_SIZE] }; + +unsafe extern "C" fn signal_entry(data: &SignalEntryData) -> ! { + let pid = crate::process::id(); + + if data.signal == OsSignal::MemoryAccessViolation { + eprintln!("{:?} in #{}, exiting", data.signal, pid); + eprintln!(" Occured at {:#x}", data.data.unwrap()); + } else { + eprintln!("#{}: {:?}", pid, data.signal); + } + + yggdrasil_rt::sys::exit(OsExitCode::BySignal(data.signal)); +} + +unsafe fn signal_init() { + let signal_sp = SIGNAL_STACK.data.as_mut_ptr() as usize + SIGNAL_STACK_SIZE; + let signal_entry = signal_entry as usize; + + yggdrasil_rt::sys::set_signal_entry(signal_entry, signal_sp); +} + #[cfg(not(test))] #[no_mangle] pub unsafe extern "C" fn runtime_entry(program_arg: usize) -> ! { @@ -167,7 +197,11 @@ pub unsafe extern "C" fn runtime_entry(program_arg: usize) -> ! { } args::init(program_arg); + + // Initialize signals + signal_init(); + let result = main(0, null()); - yggdrasil_rt::sys::exit(result); + yggdrasil_rt::sys::exit(OsExitCode::Exited(result)); } diff --git a/library/std/src/sys/yggdrasil/os.rs b/library/std/src/sys/yggdrasil/os.rs index 3b031ba4e49..a70fda571b7 100644 --- a/library/std/src/sys/yggdrasil/os.rs +++ b/library/std/src/sys/yggdrasil/os.rs @@ -56,7 +56,7 @@ pub fn exit(_code: i32) -> ! { } pub fn getpid() -> u32 { - todo!() + unsafe { yggdrasil_rt::sys::get_pid() } } pub fn home_dir() -> Option { diff --git a/library/std/src/sys/yggdrasil/process.rs b/library/std/src/sys/yggdrasil/process.rs index a3f50449f71..8f6444fce07 100644 --- a/library/std/src/sys/yggdrasil/process.rs +++ b/library/std/src/sys/yggdrasil/process.rs @@ -11,7 +11,9 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs}; pub use crate::ffi::OsString as EnvKey; use yggdrasil_rt::io::RawFd; -use yggdrasil_rt::process::{SpawnOption, SpawnOptions}; +use yggdrasil_rt::process::{ + ExitCode as OsExitCode, Signal as OsSignal, SpawnOption, SpawnOptions, +}; // Process @@ -51,11 +53,11 @@ impl Process { } pub fn kill(&mut self) -> io::Result<()> { - todo!() + cvt_io(unsafe { yggdrasil_rt::sys::send_signal(self.pid, OsSignal::Killed) }) } pub fn wait(&mut self) -> io::Result { - let mut status = 0; + let mut status = OsExitCode::Exited(0); cvt_io(unsafe { yggdrasil_rt::sys::wait_process(self.pid, &mut status) })?; Ok(ExitStatus(status)) } @@ -90,7 +92,7 @@ impl From for Stdio { // Status #[derive(Clone, Copy, PartialEq, Eq)] -pub struct ExitStatus(i32); +pub struct ExitStatus(OsExitCode); #[derive(Clone, Copy, PartialEq, Eq, Debug)] pub struct ExitStatusError(NonZeroI32); @@ -100,15 +102,11 @@ pub struct ExitCode(bool); impl ExitStatus { pub fn exit_ok(&self) -> Result<(), ExitStatusError> { - if self.0 == 0 { - Ok(()) - } else { - Err(ExitStatusError(unsafe { NonZeroI32::new_unchecked(self.0) })) - } + if let Some(error) = self.0.as_failure() { Err(ExitStatusError(error)) } else { Ok(()) } } pub fn code(&self) -> Option { - Some(self.0) + Some(i32::from(self.0)) } } @@ -121,7 +119,7 @@ impl ExitStatusError { impl From for ExitStatus { fn from(value: ExitStatusError) -> Self { - Self(value.0.into()) + Self(OsExitCode::from(i32::from(value.0))) } } @@ -148,7 +146,7 @@ impl fmt::Debug for ExitStatus { impl fmt::Display for ExitStatus { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt(&self.0, f) + fmt::Debug::fmt(&self.0, f) } }