diff --git a/src/data.rs b/src/data.rs index 0b3845e..6ad8d8b 100644 --- a/src/data.rs +++ b/src/data.rs @@ -1,5 +1,5 @@ use core::ops::{Deref, DerefMut}; -use core::{mem, slice}; +use core::{fmt, mem, slice}; #[derive(Copy, Clone, Debug, Default)] #[repr(C)] @@ -13,7 +13,7 @@ impl Deref for Event { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::()) } } } @@ -21,7 +21,7 @@ impl Deref for Event { impl DerefMut for Event { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::()) } } } @@ -38,7 +38,7 @@ impl Deref for ITimerSpec { fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const ITimerSpec as *const u8, - mem::size_of::()) as &[u8] + mem::size_of::()) } } } @@ -47,7 +47,7 @@ impl DerefMut for ITimerSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut ITimerSpec as *mut u8, - mem::size_of::()) as &mut [u8] + mem::size_of::()) } } } @@ -64,7 +64,7 @@ impl Deref for Map { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::()) } } } @@ -72,7 +72,7 @@ impl Deref for Map { impl DerefMut for Map { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::()) } } } @@ -94,7 +94,7 @@ impl Deref for Packet { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts(self as *const Packet as *const u8, mem::size_of::()) } } } @@ -102,27 +102,26 @@ impl Deref for Packet { impl DerefMut for Packet { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut(self as *mut Packet as *mut u8, mem::size_of::()) } } } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Default, PartialEq)] #[repr(C)] pub struct SigAction { - pub sa_handler: extern "C" fn(usize), + pub sa_handler: Option, pub sa_mask: [u64; 2], pub sa_flags: usize, } -impl Default for SigAction { - fn default() -> Self { - Self { - sa_handler: unsafe { mem::transmute(0usize) }, - sa_mask: [0; 2], - sa_flags: 0, - } - } +#[allow(dead_code)] +unsafe fn _assert_size_of_function_is_sane() { + // Transmuting will complain *at compile time* if sizes differ. + // Rust forbids a fn-pointer from being 0 so to allow SIG_DFL to + // exist, we use Option which will mean 0 + // becomes None + let _ = mem::transmute::, usize>(None); } #[derive(Copy, Clone, Debug, Default, PartialEq)] @@ -150,7 +149,7 @@ impl Deref for Stat { fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const Stat as *const u8, - mem::size_of::()) as &[u8] + mem::size_of::()) } } } @@ -159,7 +158,7 @@ impl DerefMut for Stat { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut Stat as *mut u8, - mem::size_of::()) as &mut [u8] + mem::size_of::()) } } } @@ -178,7 +177,7 @@ impl Deref for StatVfs { fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const StatVfs as *const u8, - mem::size_of::()) as &[u8] + mem::size_of::()) } } } @@ -187,7 +186,7 @@ impl DerefMut for StatVfs { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, - mem::size_of::()) as &mut [u8] + mem::size_of::()) } } } @@ -204,7 +203,7 @@ impl Deref for TimeSpec { fn deref(&self) -> &[u8] { unsafe { slice::from_raw_parts(self as *const TimeSpec as *const u8, - mem::size_of::()) as &[u8] + mem::size_of::()) } } } @@ -213,7 +212,7 @@ impl DerefMut for TimeSpec { fn deref_mut(&mut self) -> &mut [u8] { unsafe { slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, - mem::size_of::()) as &mut [u8] + mem::size_of::()) } } } @@ -257,7 +256,7 @@ impl Deref for IntRegisters { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const IntRegisters as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts(self as *const IntRegisters as *const u8, mem::size_of::()) } } } @@ -265,7 +264,7 @@ impl Deref for IntRegisters { impl DerefMut for IntRegisters { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut IntRegisters as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut(self as *mut IntRegisters as *mut u8, mem::size_of::()) } } } @@ -291,7 +290,7 @@ impl Deref for FloatRegisters { type Target = [u8]; fn deref(&self) -> &[u8] { unsafe { - slice::from_raw_parts(self as *const FloatRegisters as *const u8, mem::size_of::()) as &[u8] + slice::from_raw_parts(self as *const FloatRegisters as *const u8, mem::size_of::()) } } } @@ -299,7 +298,52 @@ impl Deref for FloatRegisters { impl DerefMut for FloatRegisters { fn deref_mut(&mut self) -> &mut [u8] { unsafe { - slice::from_raw_parts_mut(self as *mut FloatRegisters as *mut u8, mem::size_of::()) as &mut [u8] + slice::from_raw_parts_mut(self as *mut FloatRegisters as *mut u8, mem::size_of::()) + } + } +} + +#[derive(Clone, Copy)] +#[repr(C)] +pub union PtraceEventData { + pub clone: usize, + pub signal: usize +} + +impl Default for PtraceEventData { + fn default() -> Self { + Self { + clone: 0, + } + } +} + +impl fmt::Debug for PtraceEventData { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "PtraceEventData(...)") + } +} + +#[derive(Clone, Copy, Debug, Default)] +#[repr(C)] +pub struct PtraceEvent { + pub tag: u16, + pub data: PtraceEventData, +} + +impl Deref for PtraceEvent { + type Target = [u8]; + fn deref(&self) -> &[u8] { + unsafe { + slice::from_raw_parts(self as *const PtraceEvent as *const u8, mem::size_of::()) + } + } +} + +impl DerefMut for PtraceEvent { + fn deref_mut(&mut self) -> &mut [u8] { + unsafe { + slice::from_raw_parts_mut(self as *mut PtraceEvent as *mut u8, mem::size_of::()) } } } diff --git a/src/flag.rs b/src/flag.rs index e6c4cbf..9c928b4 100644 --- a/src/flag.rs +++ b/src/flag.rs @@ -69,9 +69,14 @@ pub const PTRACE_CONT: u8 = 0b0000_0001; pub const PTRACE_SINGLESTEP: u8 = 0b0000_0010; pub const PTRACE_SYSCALL: u8 = 0b0000_0011; pub const PTRACE_WAIT: u8 = 0b0000_0100; +pub const PTRACE_SIGNAL: u8 = 0b0000_0101; + pub const PTRACE_OPERATIONMASK: u8 = 0b0000_1111; pub const PTRACE_SYSEMU: u8 = 0b0001_0000; +pub const PTRACE_EVENT_CLONE: u16 = 0; +pub const PTRACE_EVENT_SIGNAL: u16 = 1; + pub const SEEK_SET: usize = 0; pub const SEEK_CUR: usize = 1; pub const SEEK_END: usize = 2; diff --git a/src/tests.rs b/src/tests.rs index 03273d4..7dd2bad 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -409,3 +409,68 @@ fn unlink() { fn sched_yield() { assert_eq!(dbg!(crate::sched_yield()), Ok(0)); } + +#[test] +fn sigaction() { + use std::{ + mem, + sync::atomic::{AtomicBool, Ordering} + }; + + static SA_HANDLER_WAS_RAN: AtomicBool = AtomicBool::new(false); + static SA_HANDLER_2_WAS_IGNORED: AtomicBool = AtomicBool::new(false); + + let child = unsafe { crate::clone(crate::CLONE_VM).unwrap() }; + + if child == 0 { + let pid = crate::getpid().unwrap(); + + extern "C" fn hello_im_a_signal_handler(signal: usize) { + assert_eq!(signal, crate::SIGUSR1); + SA_HANDLER_WAS_RAN.store(true, Ordering::SeqCst); + } + + let my_signal_handler = crate::SigAction { + sa_handler: Some(hello_im_a_signal_handler), + ..Default::default() + }; + crate::sigaction(crate::SIGUSR1, Some(&my_signal_handler), None).unwrap(); + + crate::kill(pid, crate::SIGUSR1).unwrap(); // calls handler + + let mut old_signal_handler = crate::SigAction::default(); + crate::sigaction( + crate::SIGUSR1, + Some(&crate::SigAction { + sa_handler: unsafe { mem::transmute::>(crate::SIG_IGN) }, + ..Default::default() + }), + Some(&mut old_signal_handler) + ).unwrap(); + assert_eq!(my_signal_handler, old_signal_handler); + + crate::kill(pid, crate::SIGUSR1).unwrap(); // does nothing + + SA_HANDLER_2_WAS_IGNORED.store(true, Ordering::SeqCst); + + crate::sigaction( + crate::SIGUSR1, + Some(&crate::SigAction { + sa_handler: unsafe { mem::transmute::>(crate::SIG_DFL) }, + ..Default::default() + }), + Some(&mut old_signal_handler) + ).unwrap(); + + crate::kill(pid, crate::SIGUSR1).unwrap(); // actually exits + } else { + let mut status = 0; + dbg!(crate::waitpid(child, &mut status, 0)).unwrap(); + + assert!(crate::wifsignaled(status)); + assert_eq!(crate::wtermsig(status), crate::SIGUSR1); + + assert!(SA_HANDLER_WAS_RAN.load(Ordering::SeqCst)); + assert!(SA_HANDLER_2_WAS_IGNORED.load(Ordering::SeqCst)); + } +}