Implement psignal and psiginfo.

This commit is contained in:
4lDO2
2024-08-04 23:25:29 +02:00
parent 2b7a1ea94b
commit af6435e12d
4 changed files with 82 additions and 5 deletions
+57 -3
View File
@@ -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(),
);
}
+2 -2
View File
@@ -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
}
+1
View File
@@ -25,6 +25,7 @@ EXPECT_NAMES=\
locale \
math \
netdb/getaddrinfo \
psignal \
ptrace \
regex \
select \
+22
View File
@@ -0,0 +1,22 @@
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#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("------ -----");
}