psignal/psiginfo: complete TODOs and remove allocations

These implementations already passed the os-test test suite (and still
do after these changes), but I saw that they had some TODOs and some
overcomplicated code. If we want to be a fast libc, removing use of
`format!` where we can is likely a good first step because it
allocates memory.
This commit is contained in:
Connor-GH
2026-01-21 17:41:33 -06:00
parent 8548517784
commit 89c0ff6570
+24 -49
View File
@@ -11,7 +11,7 @@ use crate::{
error::{Errno, ResultExt},
header::{errno, setjmp, time::timespec},
platform::{
self, Pal, PalSignal, Sys,
self, ERRNO, Pal, PalSignal, Sys,
types::{
c_char, c_int, c_ulong, c_ulonglong, c_void, pid_t, pthread_attr_t, pthread_t, size_t,
uid_t,
@@ -21,7 +21,10 @@ use crate::{
pub use self::sys::*;
use super::{errno::EFAULT, unistd};
use super::{
errno::EFAULT,
stdio::{fprintf, stderr},
};
#[cfg(target_os = "linux")]
#[path = "linux.rs"]
@@ -561,58 +564,30 @@ 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 = unsafe { 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 _ = unsafe {
unistd::write(
unistd::STDERR_FILENO,
string.as_bytes().as_ptr().cast(),
string.as_bytes().len(),
)
};
.unwrap_or(&SIGNAL_STRINGS[0])
.as_ptr();
// fprintf can affect errno, so we save errno and restore it
let old_errno = ERRNO.get();
// POSIX says that "prefix" shall be written if it isn't null or an empty string.
// Otherwise, only the signal description should be written
if prefix.is_null() {
unsafe {
fprintf(stderr, c"%s\n".as_ptr(), c_description);
}
} else {
unsafe {
fprintf(stderr, c"%s: %s\n".as_ptr(), prefix, c_description);
}
}
ERRNO.set(old_errno);
}
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/psiginfo.html>.
#[unsafe(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,
} = unsafe { &*info };
let sival_ptr = unsafe { si_value.sival_ptr };
let prefix = unsafe { 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 _ = unsafe {
unistd::write(
unistd::STDERR_FILENO,
string.as_bytes().as_ptr().cast(),
string.as_bytes().len(),
)
};
unsafe {
psignal(unsafe { &*info }.si_signo, prefix);
}
}
#[unsafe(no_mangle)]