From af6435e12d96c6757719bf194810dcf2e92c0a2e Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Sun, 4 Aug 2024 23:25:29 +0200 Subject: [PATCH] Implement psignal and psiginfo. --- src/header/signal/mod.rs | 60 ++++++++++++++++++++++++++++++++++++++-- src/header/string/mod.rs | 4 +-- tests/Makefile | 1 + tests/psignal.c | 22 +++++++++++++++ 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 tests/psignal.c diff --git a/src/header/signal/mod.rs b/src/header/signal/mod.rs index dbd6d69ced..a8785a8807 100644 --- a/src/header/signal/mod.rs +++ b/src/header/signal/mod.rs @@ -5,14 +5,15 @@ use core::{mem, ptr}; use cbitset::BitSet; use crate::{ - error::{self, Errno, ResultExt}, + error::{Errno, ResultExt}, + c_str::CStr, header::{errno, time::timespec}, platform::{self, types::*, Pal, PalSignal, Sys}, }; pub use self::sys::*; -use super::errno::EFAULT; +use super::{errno::EFAULT, unistd}; #[cfg(target_os = "linux")] #[path = "linux.rs"] @@ -54,6 +55,7 @@ pub struct sigaltstack { pub ss_size: size_t, } +// FIXME: This struct is wrong on Linux #[repr(C)] #[derive(Clone, Copy)] pub struct siginfo { @@ -395,7 +397,7 @@ pub unsafe extern "C" fn sigwaitinfo(set: *const sigset_t, sig: *mut siginfo_t) sigtimedwait(set, sig, core::ptr::null()) } -pub const _signal_strings: [&str; 32] = [ +pub(crate) const SIGNAL_STRINGS: [&str; 32] = [ "Unknown signal\0", "Hangup\0", "Interrupt\0", @@ -429,3 +431,55 @@ pub const _signal_strings: [&str; 32] = [ "Power failure\0", "Bad system call\0", ]; +#[no_mangle] +pub unsafe extern "C" fn psignal(sig: c_int, prefix: *const c_char) { + let c_description = usize::try_from(sig) + .ok() + .and_then(|idx| SIGNAL_STRINGS.get(idx)) + .unwrap_or(&SIGNAL_STRINGS[0]); + let description = &c_description[..c_description.len() - 1]; + let prefix = CStr::from_ptr(prefix).to_string_lossy(); + // TODO: stack vec or print directly? + let string = alloc::format!("{prefix}:{description}\n"); + // TODO: better internal libc API? + let _ = unistd::write( + unistd::STDERR_FILENO, + string.as_bytes().as_ptr().cast(), + string.as_bytes().len(), + ); +} +#[no_mangle] +pub unsafe extern "C" fn psiginfo(info: *const siginfo_t, prefix: *const c_char) { + let siginfo_t { + si_code, + si_signo, + si_pid, + si_uid, + si_errno, + si_addr, + si_status, + si_value, + } = &*info; + let sival_ptr = si_value.sival_ptr; + let prefix = CStr::from_ptr(prefix).to_string_lossy(); + // TODO: stack vec or print directly? + let string = alloc::format!( + "{prefix}:siginfo_t {{ + si_code: {si_code} + si_signo: {si_signo} + si_pid: {si_pid} + si_uid: {si_uid} + si_errno: {si_errno} + si_addr: {si_addr:p} + si_status: {si_status} + si_value: {sival_ptr:p} +}} +" + ); + // TODO: better internal libc API? + let _ = unistd::write( + unistd::STDERR_FILENO, + string.as_bytes().as_ptr().cast(), + string.as_bytes().len(), + ); +} diff --git a/src/header/string/mod.rs b/src/header/string/mod.rs index 0d16d6d2d1..9ddc6cb37a 100644 --- a/src/header/string/mod.rs +++ b/src/header/string/mod.rs @@ -353,9 +353,9 @@ pub unsafe extern "C" fn strrchr(s: *const c_char, c: c_int) -> *mut c_char { #[no_mangle] pub unsafe extern "C" fn strsignal(sig: c_int) -> *mut c_char { - signal::_signal_strings + signal::SIGNAL_STRINGS .get(sig as usize) - .unwrap_or(&signal::_signal_strings[0]) // Unknown signal message + .unwrap_or(&signal::SIGNAL_STRINGS[0]) // Unknown signal message .as_ptr() as *mut c_char } diff --git a/tests/Makefile b/tests/Makefile index b2ce84cbf7..0865ff9928 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -25,6 +25,7 @@ EXPECT_NAMES=\ locale \ math \ netdb/getaddrinfo \ + psignal \ ptrace \ regex \ select \ diff --git a/tests/psignal.c b/tests/psignal.c new file mode 100644 index 0000000000..375d1b0552 --- /dev/null +++ b/tests/psignal.c @@ -0,0 +1,22 @@ +#include +#include +#include +#include +#include + +#include "test_helpers.h" + +int main(void) { + puts("------psignal------"); + psignal(SIGUSR1, "a prefix"); + puts("------ end ------"); + puts("------psiginfo-----"); + siginfo_t info = { 0 }; + info.si_code = SI_USER; + info.si_pid = 42; + info.si_uid = 1337; + info.si_addr = (void *)0xdeadbeef; + info.si_value.sival_ptr = (void *)0xfedface; + psiginfo(&info, "another prefix"); + puts("------ -----"); +}