alnyan/yggdrasil: Process::kill + basic signal handling
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
#![allow(unused)]
|
||||||
#![allow(nonstandard_style)]
|
#![allow(nonstandard_style)]
|
||||||
|
|
||||||
use crate::io::ErrorKind;
|
use crate::io::ErrorKind;
|
||||||
@@ -28,6 +29,7 @@ pub mod time;
|
|||||||
|
|
||||||
pub(self) use yggdrasil_rt;
|
pub(self) use yggdrasil_rt;
|
||||||
|
|
||||||
|
use yggdrasil_rt::process::{ExitCode as OsExitCode, Signal as OsSignal, SignalEntryData};
|
||||||
use yggdrasil_rt::Error as OsError;
|
use yggdrasil_rt::Error as OsError;
|
||||||
|
|
||||||
use crate::path::Path;
|
use crate::path::Path;
|
||||||
@@ -156,6 +158,34 @@ pub fn decode_error_kind(_errno: i32) -> ErrorKind {
|
|||||||
loop {}
|
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))]
|
#[cfg(not(test))]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn runtime_entry(program_arg: usize) -> ! {
|
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);
|
args::init(program_arg);
|
||||||
|
|
||||||
|
// Initialize signals
|
||||||
|
signal_init();
|
||||||
|
|
||||||
let result = main(0, null());
|
let result = main(0, null());
|
||||||
|
|
||||||
yggdrasil_rt::sys::exit(result);
|
yggdrasil_rt::sys::exit(OsExitCode::Exited(result));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ pub fn exit(_code: i32) -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getpid() -> u32 {
|
pub fn getpid() -> u32 {
|
||||||
todo!()
|
unsafe { yggdrasil_rt::sys::get_pid() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn home_dir() -> Option<PathBuf> {
|
pub fn home_dir() -> Option<PathBuf> {
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ use crate::sys_common::process::{CommandEnv, CommandEnvs};
|
|||||||
pub use crate::ffi::OsString as EnvKey;
|
pub use crate::ffi::OsString as EnvKey;
|
||||||
|
|
||||||
use yggdrasil_rt::io::RawFd;
|
use yggdrasil_rt::io::RawFd;
|
||||||
use yggdrasil_rt::process::{SpawnOption, SpawnOptions};
|
use yggdrasil_rt::process::{
|
||||||
|
ExitCode as OsExitCode, Signal as OsSignal, SpawnOption, SpawnOptions,
|
||||||
|
};
|
||||||
|
|
||||||
// Process
|
// Process
|
||||||
|
|
||||||
@@ -51,11 +53,11 @@ impl Process {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn kill(&mut self) -> io::Result<()> {
|
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<ExitStatus> {
|
pub fn wait(&mut self) -> io::Result<ExitStatus> {
|
||||||
let mut status = 0;
|
let mut status = OsExitCode::Exited(0);
|
||||||
cvt_io(unsafe { yggdrasil_rt::sys::wait_process(self.pid, &mut status) })?;
|
cvt_io(unsafe { yggdrasil_rt::sys::wait_process(self.pid, &mut status) })?;
|
||||||
Ok(ExitStatus(status))
|
Ok(ExitStatus(status))
|
||||||
}
|
}
|
||||||
@@ -90,7 +92,7 @@ impl From<File> for Stdio {
|
|||||||
// Status
|
// Status
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq)]
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct ExitStatus(i32);
|
pub struct ExitStatus(OsExitCode);
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
pub struct ExitStatusError(NonZeroI32);
|
pub struct ExitStatusError(NonZeroI32);
|
||||||
@@ -100,15 +102,11 @@ pub struct ExitCode(bool);
|
|||||||
|
|
||||||
impl ExitStatus {
|
impl ExitStatus {
|
||||||
pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
|
pub fn exit_ok(&self) -> Result<(), ExitStatusError> {
|
||||||
if self.0 == 0 {
|
if let Some(error) = self.0.as_failure() { Err(ExitStatusError(error)) } else { Ok(()) }
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(ExitStatusError(unsafe { NonZeroI32::new_unchecked(self.0) }))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn code(&self) -> Option<i32> {
|
pub fn code(&self) -> Option<i32> {
|
||||||
Some(self.0)
|
Some(i32::from(self.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +119,7 @@ impl ExitStatusError {
|
|||||||
|
|
||||||
impl From<ExitStatusError> for ExitStatus {
|
impl From<ExitStatusError> for ExitStatus {
|
||||||
fn from(value: ExitStatusError) -> Self {
|
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 {
|
impl fmt::Display for ExitStatus {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Display::fmt(&self.0, f)
|
fmt::Debug::fmt(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user