Implement psignal and psiginfo.
This commit is contained in:
@@ -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(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ EXPECT_NAMES=\
|
||||
locale \
|
||||
math \
|
||||
netdb/getaddrinfo \
|
||||
psignal \
|
||||
ptrace \
|
||||
regex \
|
||||
select \
|
||||
|
||||
@@ -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("------ -----");
|
||||
}
|
||||
Reference in New Issue
Block a user