From b08adc81e32b2e161df69e4c1fe004361fb6431d Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 11:37:48 +0100 Subject: [PATCH 01/17] refactors signals --- src/kernel/src/process/mod.rs | 10 +- src/kernel/src/process/signal.rs | 24 ++-- src/kernel/src/signal/mod.rs | 183 +++++++++++++++++++------------ src/kernel/src/signal/set.rs | 23 ++-- 4 files changed, 138 insertions(+), 102 deletions(-) diff --git a/src/kernel/src/process/mod.rs b/src/kernel/src/process/mod.rs index 0b7a532c3..2f90187a3 100644 --- a/src/kernel/src/process/mod.rs +++ b/src/kernel/src/process/mod.rs @@ -11,9 +11,10 @@ use crate::errno::{EINVAL, ENAMETOOLONG, EPERM, ERANGE, ESRCH}; use crate::fs::Vnode; use crate::idt::Idt; use crate::info; +use crate::signal::Signal; use crate::signal::{ strsignal, SignalAct, SignalFlags, SignalSet, SIGCHLD, SIGKILL, SIGSTOP, SIG_BLOCK, SIG_DFL, - SIG_IGN, SIG_MAXSIG, SIG_SETMASK, SIG_UNBLOCK, + SIG_IGN, SIG_SETMASK, SIG_UNBLOCK, }; use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls}; use crate::ucred::{AuthInfo, Gid, Privilege, Ucred, Uid}; @@ -284,14 +285,10 @@ impl VProc { fn sys_sigaction(self: &Arc, i: &SysIn) -> Result { // Get arguments. - let sig: i32 = i.args[0].try_into().unwrap(); + let sig: Signal = i.args[0].try_into()?; let act: *const SignalAct = i.args[1].into(); let oact: *mut SignalAct = i.args[2].into(); - if sig == 0 || sig > SIG_MAXSIG { - return Err(SysErr::Raw(EINVAL)); - } - // Save the old actions. let mut acts = self.sigacts.write(); @@ -304,7 +301,6 @@ impl VProc { } // Set new actions. - let sig = NonZeroI32::new(sig).unwrap(); let handler = unsafe { (*act).handler }; let flags = unsafe { (*act).flags }; let mut mask = unsafe { (*act).mask }; diff --git a/src/kernel/src/process/signal.rs b/src/kernel/src/process/signal.rs index f151c8800..196d4e36e 100644 --- a/src/kernel/src/process/signal.rs +++ b/src/kernel/src/process/signal.rs @@ -1,4 +1,4 @@ -use crate::signal::{SignalSet, SIG_MAXSIG}; +use crate::signal::{Signal, SignalSet, SIG_MAXSIG}; use std::num::NonZeroI32; /// An implementation of `sigacts` structure. @@ -30,47 +30,47 @@ impl SignalActs { } } - pub fn handler(&self, sig: NonZeroI32) -> usize { + pub fn handler(&self, sig: Signal) -> usize { self.handler[(sig.get() - 1) as usize] } - pub fn set_handler(&mut self, sig: NonZeroI32, h: usize) { + pub fn set_handler(&mut self, sig: Signal, h: usize) { self.handler[(sig.get() - 1) as usize] = h; } - pub fn set_catchmask(&mut self, sig: NonZeroI32, mask: SignalSet) { + pub fn set_catchmask(&mut self, sig: Signal, mask: SignalSet) { self.catchmask[(sig.get() - 1) as usize] = mask; } - pub fn remove_stack(&mut self, sig: NonZeroI32) { + pub fn remove_stack(&mut self, sig: Signal) { self.stack.remove(sig); } - pub fn set_interupt(&mut self, sig: NonZeroI32) { + pub fn set_interupt(&mut self, sig: Signal) { self.interupt.add(sig); } - pub fn remove_reset(&mut self, sig: NonZeroI32) { + pub fn remove_reset(&mut self, sig: Signal) { self.reset.remove(sig); } - pub fn remove_nodefer(&mut self, sig: NonZeroI32) { + pub fn remove_nodefer(&mut self, sig: Signal) { self.nodefer.remove(sig); } - pub fn set_modern(&mut self, sig: NonZeroI32) { + pub fn set_modern(&mut self, sig: Signal) { self.modern.add(sig); } - pub fn remove_ignore(&mut self, sig: NonZeroI32) { + pub fn remove_ignore(&mut self, sig: Signal) { self.ignore.remove(sig); } - pub fn set_catch(&mut self, sig: NonZeroI32) { + pub fn set_catch(&mut self, sig: Signal) { self.catch.add(sig); } - pub fn remove_catch(&mut self, sig: NonZeroI32) { + pub fn remove_catch(&mut self, sig: Signal) { self.catch.remove(sig); } } diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index faa8824a5..44d69dac2 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -1,5 +1,7 @@ pub use self::set::*; +use crate::errno::EINVAL; +use crate::syscalls::{SysArg, SysErr}; use bitflags::bitflags; use std::borrow::Cow; use std::fmt::{Display, Formatter}; @@ -7,42 +9,86 @@ use std::num::NonZeroI32; mod set; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct Signal(NonZeroI32); + +impl Signal { + pub fn get(&self) -> i32 { + self.0.get() + } +} + +impl TryFrom for Signal { + type Error = SysErr; + + fn try_from(value: SysArg) -> Result { + let value: i32 = value.try_into().map_err(|_| SysErr::Raw(EINVAL))?; + + match value { + 1..=SIG_MAXSIG => Ok(Signal(unsafe { NonZeroI32::new_unchecked(value) })), + _ => Err(SysErr::Raw(EINVAL)), + } + } +} + +macro_rules! signals { + ($($name:ident => $num:expr,)*) => { + $( + #[allow(dead_code)] + pub const $name: Signal = Signal(unsafe { + assert!($num > 0 && $num <= SIG_MAXSIG); + NonZeroI32::new_unchecked($num) + }); + )* + + pub fn strsignal(sig: Signal) -> Cow<'static, str> { + match sig.0.get() { + $( $num => Cow::Borrowed(stringify!($name)), )* + _ => format!("{sig}", sig = sig.get()).into(), + } + } + }; +} + // List of PS4 signals. The value must be the same as PS4 kernel. -pub const SIGHUP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(1) }; -pub const SIGINT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(2) }; -pub const SIGQUIT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(3) }; -pub const SIGILL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(4) }; -pub const SIGTRAP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(5) }; -pub const SIGABRT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(6) }; -pub const SIGEMT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(7) }; -pub const SIGFPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(8) }; -pub const SIGKILL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(9) }; -pub const SIGBUS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(10) }; -pub const SIGSEGV: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(11) }; -pub const SIGSYS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(12) }; -pub const SIGPIPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(13) }; -pub const SIGALRM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(14) }; -pub const SIGTERM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(15) }; -pub const SIGURG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(16) }; -pub const SIGSTOP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(17) }; -pub const SIGTSTP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(18) }; -pub const SIGCONT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(19) }; -pub const SIGCHLD: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(20) }; -pub const SIGTTIN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(21) }; -pub const SIGTTOU: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(22) }; -pub const SIGIO: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(23) }; -pub const SIGXCPU: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(24) }; -pub const SIGXFSZ: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(25) }; -pub const SIGVTALRM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(26) }; -pub const SIGPROF: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(27) }; -pub const SIGWINCH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(28) }; -pub const SIGINFO: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(29) }; -pub const SIGUSR1: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(30) }; -pub const SIGUSR2: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(31) }; -pub const SIGTHR: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(32) }; -pub const SIGNONE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(128) }; -pub const SIG_MAXSIG: i32 = 128; +// Not that this macro call also generates the strsignal function. +signals!( + SIGHUP => 1, + SIGINT => 2, + SIGQUIT => 3, + SIGILL => 4, + SIGTRAP => 5, + SIGABRT => 6, + SIGEMT => 7, + SIGFPE => 8, + SIGKILL => 9, + SIGBUS => 10, + SIGSEGV => 11, + SIGSYS => 12, + SIGPIPE => 13, + SIGALRM => 14, + SIGTERM => 15, + SIGURG => 16, + SIGSTOP => 17, + SIGTSTP => 18, + SIGCONT => 19, + SIGCHLD => 20, + SIGTTIN => 21, + SIGTTOU => 22, + SIGIO => 23, + SIGXCPU => 24, + SIGXFSZ => 25, + SIGVTALRM => 26, + SIGPROF => 27, + SIGWINCH => 28, + SIGINFO => 29, + SIGUSR1 => 30, + SIGUSR2 => 31, + SIGTHR => 32, + SIGNONE => 128, +); +pub const SIG_MAXSIG: i32 = 128; // List of sigprocmask operations. The value must be the same as PS4 kernel. pub const SIG_BLOCK: i32 = 1; pub const SIG_UNBLOCK: i32 = 2; @@ -51,42 +97,39 @@ pub const SIG_SETMASK: i32 = 3; pub const SIG_IGN: usize = 1; pub const SIG_DFL: usize = 0; -pub fn strsignal(num: NonZeroI32) -> Cow<'static, str> { - match num { - SIGHUP => "SIGHUP".into(), - SIGINT => "SIGINT".into(), - SIGQUIT => "SIGQUIT".into(), - SIGILL => "SIGILL".into(), - SIGTRAP => "SIGTRAP".into(), - SIGABRT => "SIGABRT".into(), - SIGEMT => "SIGEMT".into(), - SIGFPE => "SIGFPE".into(), - SIGKILL => "SIGKILL".into(), - SIGBUS => "SIGBUS".into(), - SIGSEGV => "SIGSEGV".into(), - SIGSYS => "SIGSYS".into(), - SIGPIPE => "SIGPIPE".into(), - SIGALRM => "SIGALRM".into(), - SIGTERM => "SIGTERM".into(), - SIGURG => "SIGURG".into(), - SIGSTOP => "SIGSTOP".into(), - SIGTSTP => "SIGTSTP".into(), - SIGCONT => "SIGCONT".into(), - SIGCHLD => "SIGCHLD".into(), - SIGTTIN => "SIGTTIN".into(), - SIGTTOU => "SIGTTOU".into(), - SIGIO => "SIGIO".into(), - SIGXCPU => "SIGXCPU".into(), - SIGXFSZ => "SIGXFSZ".into(), - SIGVTALRM => "SIGVTALRM".into(), - SIGPROF => "SIGPROF".into(), - SIGWINCH => "SIGWINCH".into(), - SIGINFO => "SIGINFO".into(), - SIGUSR1 => "SIGUSR1".into(), - SIGUSR2 => "SIGUSR2".into(), - SIGTHR => "SIGTHR".into(), - SIGNONE => "SIGNONE".into(), - v => format!("{v}").into(), +/// An iterator over all possible signals +pub struct SignalIter { + current: i32, +} + +impl SignalIter { + pub fn new() -> Self { + Self { current: 1 } + } +} + +impl Iterator for SignalIter { + type Item = Signal; + + fn next(&mut self) -> Option { + if self.current <= SIG_MAXSIG { + let signal = Signal(unsafe { NonZeroI32::new_unchecked(self.current) }); + self.current += 1; + Some(signal) + } else { + None + } + } + + fn size_hint(&self) -> (usize, Option) { + let len = (SIG_MAXSIG - self.current + 1) as usize; + (len, Some(len)) + } +} + +impl ExactSizeIterator for SignalIter { + fn len(&self) -> usize { + (SIG_MAXSIG - self.current + 1) as usize } } diff --git a/src/kernel/src/signal/set.rs b/src/kernel/src/signal/set.rs index 66e2be04d..dd91b5045 100644 --- a/src/kernel/src/signal/set.rs +++ b/src/kernel/src/signal/set.rs @@ -1,6 +1,5 @@ -use super::strsignal; +use super::{strsignal, Signal, SignalIter}; use std::fmt::{Display, Formatter}; -use std::num::NonZeroI32; use std::ops::{BitAndAssign, BitOrAssign, Not}; /// An implementation of `sigset_t`. @@ -12,32 +11,32 @@ pub struct SignalSet { impl SignalSet { /// An implementation of `SIGISMEMBER`. - pub fn contains(&self, sig: NonZeroI32) -> bool { + pub fn contains(&self, sig: Signal) -> bool { (self.bits[Self::word(sig)] & Self::bit(sig)) != 0 } /// An implementation of `SIGADDSET`. - pub fn add(&mut self, sig: NonZeroI32) { + pub fn add(&mut self, sig: Signal) { self.bits[Self::word(sig)] |= Self::bit(sig); } /// An implementation of `SIGDELSET`. - pub fn remove(&mut self, sig: NonZeroI32) { + pub fn remove(&mut self, sig: Signal) { self.bits[Self::word(sig)] &= !Self::bit(sig); } // An implementation of `_SIG_IDX`. - fn idx(s: NonZeroI32) -> i32 { + fn idx(s: Signal) -> i32 { s.get() - 1 } /// An implementation of `_SIG_WORD`. - fn word(s: NonZeroI32) -> usize { + fn word(s: Signal) -> usize { (Self::idx(s) >> 5).try_into().unwrap() } /// An implementation of `_SIG_BIT`. - fn bit(s: NonZeroI32) -> u32 { + fn bit(s: Signal) -> u32 { 1 << (Self::idx(s) & 31) } } @@ -73,15 +72,13 @@ impl Display for SignalSet { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let mut first = true; - for i in 1..=128 { - let num = unsafe { NonZeroI32::new_unchecked(i) }; - - if self.contains(num) { + for sig in SignalIter::new() { + if self.contains(sig) { if !first { f.write_str(" | ")?; } - f.write_str(strsignal(num).as_ref())?; + f.write_str(strsignal(sig).as_ref())?; first = false; } } From 4c000a0b376961ed25aa460d691571add0afe4cd Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 11:45:45 +0100 Subject: [PATCH 02/17] ref strsignal --- src/kernel/src/signal/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 44d69dac2..9ec08a792 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -41,7 +41,8 @@ macro_rules! signals { }); )* - pub fn strsignal(sig: Signal) -> Cow<'static, str> { + #[inline(always)] + pub fn strsignal_impl(sig: Signal) -> Cow<'static, str> { match sig.0.get() { $( $num => Cow::Borrowed(stringify!($name)), )* _ => format!("{sig}", sig = sig.get()).into(), @@ -51,7 +52,6 @@ macro_rules! signals { } // List of PS4 signals. The value must be the same as PS4 kernel. -// Not that this macro call also generates the strsignal function. signals!( SIGHUP => 1, SIGINT => 2, @@ -88,6 +88,11 @@ signals!( SIGNONE => 128, ); +pub fn strsignal(sig: Signal) -> Cow<'static, str> { + // This function is generated inside the macro `signals!`. + strsignal_impl(sig) +} + pub const SIG_MAXSIG: i32 = 128; // List of sigprocmask operations. The value must be the same as PS4 kernel. pub const SIG_BLOCK: i32 = 1; From 744f376462ca24fc78210947e7205d4519e2018b Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 11:54:38 +0100 Subject: [PATCH 03/17] ref errors --- src/kernel/src/errno.rs | 324 +++++++++++++++------------------------- 1 file changed, 123 insertions(+), 201 deletions(-) diff --git a/src/kernel/src/errno.rs b/src/kernel/src/errno.rs index b3b326e84..71f0853f3 100644 --- a/src/kernel/src/errno.rs +++ b/src/kernel/src/errno.rs @@ -3,105 +3,127 @@ use std::error::Error; use std::num::NonZeroI32; -pub const EPERM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(1) }; -pub const ENOENT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(2) }; -pub const ESRCH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(3) }; -pub const EINTR: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(4) }; -pub const EIO: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(5) }; -pub const ENXIO: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(6) }; -pub const E2BIG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(7) }; -pub const ENOEXEC: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(8) }; -pub const EBADF: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(9) }; -pub const ECHILD: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(10) }; -pub const EDEADLK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(11) }; -pub const ENOMEM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(12) }; -pub const EACCES: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(13) }; -pub const EFAULT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(14) }; -pub const ENOTBLK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(15) }; -pub const EBUSY: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(16) }; -pub const EEXIST: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(17) }; -pub const EXDEV: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(18) }; -pub const ENODEV: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(19) }; -pub const ENOTDIR: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(20) }; -pub const EISDIR: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(21) }; -pub const EINVAL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(22) }; -pub const ENFILE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(23) }; -pub const EMFILE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(24) }; -pub const ENOTTY: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(25) }; -pub const ETXTBSY: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(26) }; -pub const EFBIG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(27) }; -pub const ENOSPC: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(28) }; -pub const ESPIPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(29) }; -pub const EROFS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(30) }; -pub const EMLINK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(31) }; -pub const EPIPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(32) }; -pub const EDOM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(33) }; -pub const ERANGE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(34) }; -pub const EAGAIN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(35) }; -pub const EINPROGRESS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(36) }; -pub const EALREADY: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(37) }; -pub const ENOTSOCK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(38) }; -pub const EDESTADDRREQ: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(39) }; -pub const EMSGSIZE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(40) }; -pub const EPROTOTYPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(41) }; -pub const ENOPROTOOPT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(42) }; -pub const EPROTONOSUPPORT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(43) }; -pub const ESOCKTNOSUPPORT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(44) }; -pub const EOPNOTSUPP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(45) }; -pub const EPFNOSUPPORT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(46) }; -pub const EAFNOSUPPORT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(47) }; -pub const EADDRINUSE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(48) }; -pub const EADDRNOTAVAIL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(49) }; -pub const ENETDOWN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(50) }; -pub const ENETUNREACH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(51) }; -pub const ENETRESET: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(52) }; -pub const ECONNABORTED: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(53) }; -pub const ECONNRESET: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(54) }; -pub const ENOBUFS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(55) }; -pub const EISCONN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(56) }; -pub const ENOTCONN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(57) }; -pub const ESHUTDOWN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(58) }; -pub const ETOOMANYREFS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(59) }; -pub const ETIMEDOUT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(60) }; -pub const ECONNREFUSED: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(61) }; -pub const ELOOP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(62) }; -pub const ENAMETOOLONG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(63) }; -pub const EHOSTDOWN: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(64) }; -pub const EHOSTUNREACH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(65) }; -pub const ENOTEMPTY: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(66) }; -pub const EPROCLIM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(67) }; -pub const EUSERS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(68) }; -pub const EDQUOT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(69) }; -pub const ESTALE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(70) }; -pub const EREMOTE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(71) }; -pub const EBADRPC: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(72) }; -pub const ERPCMISMATCH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(73) }; -pub const EPROGUNAVAIL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(74) }; -pub const EPROGMISMATCH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(75) }; -pub const EPROCUNAVAIL: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(76) }; -pub const ENOLCK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(77) }; -pub const ENOSYS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(78) }; -pub const EFTYPE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(79) }; -pub const EAUTH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(80) }; -pub const ENEEDAUTH: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(81) }; -pub const EIDRM: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(82) }; -pub const ENOMSG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(83) }; -pub const EOVERFLOW: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(84) }; -pub const ECANCELED: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(85) }; -pub const EILSEQ: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(86) }; -pub const ENOATTR: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(87) }; -pub const EDOOFUS: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(88) }; -pub const EBADMSG: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(89) }; -pub const EMULTIHOP: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(90) }; -pub const ENOLINK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(91) }; -pub const EPROTO: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(92) }; -pub const ENOTCAPABLE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(93) }; -pub const ECAPMODE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(94) }; -pub const ENOBLK: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(95) }; -pub const EICV: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(96) }; -pub const ENOPLAYGOENT: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(97) }; -pub const EREVOKE: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(98) }; -pub const ESDKVERSION: NonZeroI32 = unsafe { NonZeroI32::new_unchecked(99) }; +macro_rules! error_numbers { + ($($name:ident => $num:expr,)*) => { + $( + #[allow(dead_code)] + pub const $name: NonZeroI32 = unsafe { + assert!($num > 0); + NonZeroI32::new_unchecked($num) + }; + )* + + #[inline(always)] + pub fn strerror_impl(num: NonZeroI32) -> &'static str { + match num { + $( $name => stringify!($name), )* + _ => todo!("strerror {num}", num = num.get()), + } + } + }; +} + +error_numbers! { + EPERM => 1, + ENOENT => 2, + ESRCH => 3, + EINTR => 4, + EIO => 5, + ENXIO => 6, + E2BIG => 7, + ENOEXEC => 8, + EBADF => 9, + ECHILD => 10, + EDEADLK => 11, + ENOMEM => 12, + EACCES => 13, + EFAULT => 14, + ENOTBLK => 15, + EBUSY => 16, + EEXIST => 17, + EXDEV => 18, + ENODEV => 19, + ENOTDIR => 20, + EISDIR => 21, + EINVAL => 22, + ENFILE => 23, + EMFILE => 24, + ENOTTY => 25, + ETXTBSY => 26, + EFBIG => 27, + ENOSPC => 28, + ESPIPE => 29, + EROFS => 30, + EMLINK => 31, + EPIPE => 32, + EDOM => 33, + ERANGE => 34, + EAGAIN => 35, + EINPROGRESS => 36, + EALREADY => 37, + ENOTSOCK => 38, + EDESTADDRREQ => 39, + EMSGSIZE => 40, + EPROTOTYPE => 41, + ENOPROTOOPT => 42, + EPROTONOSUPPORT => 43, + ESOCKTNOSUPPORT => 44, + EOPNOTSUPP => 45, + EPFNOSUPPORT => 46, + EAFNOSUPPORT => 47, + EADDRINUSE => 48, + EADDRNOTAVAIL => 49, + ENETDOWN => 50, + ENETUNREACH => 51, + ENETRESET => 52, + ECONNABORTED => 53, + ECONNRESET => 54, + ENOBUFS => 55, + EISCONN => 56, + ENOTCONN => 57, + ESHUTDOWN => 58, + ETOOMANYREFS => 59, + ETIMEDOUT => 60, + ECONNREFUSED => 61, + ELOOP => 62, + ENAMETOOLONG => 63, + EHOSTDOWN => 64, + EHOSTUNREACH => 65, + ENOTEMPTY => 66, + EPROCLIM => 67, + EUSERS => 68, + EDQUOT => 69, + ESTALE => 70, + EREMOTE => 71, + EBADRPC => 72, + ERPCMISMATCH => 73, + EPROGUNAVAIL => 74, + EPROGMISMATCH => 75, + EPROCUNAVAIL => 76, + ENOLCK => 77, + ENOSYS => 78, + EFTYPE => 79, + EAUTH => 80, + ENEEDAUTH => 81, + EIDRM => 82, + ENOMSG => 83, + EOVERFLOW => 84, + ECANCELED => 85, + EILSEQ => 86, + ENOATTR => 87, + EDOOFUS => 88, + EBADMSG => 89, + EMULTIHOP => 90, + ENOLINK => 91, + EPROTO => 92, + ENOTCAPABLE => 93, + ECAPMODE => 94, + ENOBLK => 95, + EICV => 96, + ENOPLAYGOENT => 97, + EREVOKE => 98, + ESDKVERSION => 99, +} /// An object that is mappable to PS4 errno. pub trait Errno: Error { @@ -122,106 +144,6 @@ impl From for Box { /// Get human readable text. pub fn strerror(num: NonZeroI32) -> &'static str { - match num { - EPERM => "operation not permitted", - ENOENT => "no such file or directory", - ESRCH => "no such process", - EINTR => "interrupted system call", - EIO => "input/output error", - ENXIO => "device not configured", - E2BIG => "argument list too long", - ENOEXEC => "exec format error", - EBADF => "bad file descriptor", - ECHILD => "no child processes", - EDEADLK => "resource deadlock avoided", - ENOMEM => "cannot allocate memory", - EACCES => "permission denied", - EFAULT => "bad address", - ENOTBLK => "block device required", - EBUSY => "device busy", - EEXIST => "file exists", - EXDEV => "cross-device link", - ENODEV => "operation not supported by device", - ENOTDIR => "not a directory", - EISDIR => "is a directory", - EINVAL => "invalid argument", - ENFILE => "too many open files in system", - EMFILE => "too many open files", - ENOTTY => "inappropriate ioctl for device", - ETXTBSY => "text file busy", - EFBIG => "file too large", - ENOSPC => "no space left on device", - ESPIPE => "illegal seek", - EROFS => "read-only filesystem", - EMLINK => "too many links", - EPIPE => "broken pipe", - EDOM => "numerical argument out of domain", - ERANGE => "result too large", - EAGAIN => "resource temporarily unavailable", - EINPROGRESS => "operation now in progress", - EALREADY => "operation already in progress", - ENOTSOCK => "socket operation on non-socket", - EDESTADDRREQ => "destination address required", - EMSGSIZE => "message too long", - EPROTOTYPE => "protocol wrong type for socket", - ENOPROTOOPT => "protocol not available", - EPROTONOSUPPORT => "protocol not supported", - ESOCKTNOSUPPORT => "socket type not supported", - EOPNOTSUPP => "operation not supported", - EPFNOSUPPORT => "protocol family not supported", - EAFNOSUPPORT => "address family not supported by protocol family", - EADDRINUSE => "address already in use", - EADDRNOTAVAIL => "can't assign requested address", - ENETDOWN => "network is down", - ENETUNREACH => "network is unreachable", - ENETRESET => "network dropped connection on reset", - ECONNABORTED => "software caused connection abort", - ECONNRESET => "connection reset by peer", - ENOBUFS => "no buffer space available", - EISCONN => "socket is already connected", - ENOTCONN => "socket is not connected", - ESHUTDOWN => "can't send after socket shutdown", - ETOOMANYREFS => "too many references: can't splice", - ETIMEDOUT => "operation timed out", - ECONNREFUSED => "connection refused", - ELOOP => "too many levels of symbolic links", - ENAMETOOLONG => "file name too long", - EHOSTDOWN => "host is down", - EHOSTUNREACH => "no route to host", - ENOTEMPTY => "directory not empty", - EPROCLIM => "too many processes", - EUSERS => "too many users", - EDQUOT => "disc quota exceeded", - ESTALE => "stale NFS file handle", - EREMOTE => "too many levels of remote in path", - EBADRPC => "RPC struct is bad", - ERPCMISMATCH => "RPC version wrong", - EPROGUNAVAIL => "RPC prog. not avail", - EPROGMISMATCH => "program version wrong", - EPROCUNAVAIL => "bad procedure for program", - ENOLCK => "no locks available", - ENOSYS => "function not implemented", - EFTYPE => "inappropriate file type or format", - EAUTH => "authentication error", - ENEEDAUTH => "need authenticator", - EIDRM => "identifier removed", - ENOMSG => "no message of desired type", - EOVERFLOW => "value too large to be stored in data type", - ECANCELED => "operation canceled", - EILSEQ => "illegal byte sequence", - ENOATTR => "attribute not found", - EDOOFUS => "function or API is being abused at run-time", - EBADMSG => "bad message", - EMULTIHOP => "multi-hop attempted", - ENOLINK => "link has been severed", - EPROTO => "protocol error", - ENOTCAPABLE => "capabilities insufficient", - ECAPMODE => "not permitted in capability mode", - ENOBLK => "block not ready", - EICV => "integrity check error", - ENOPLAYGOENT => "file not found in PlayGo chunk definition file", - EREVOKE => "file is revoked", - ESDKVERSION => "SDK version of a binary file is invalid", - v => todo!("strerror {v}"), - } + // This function is generated inside the macro `error_numbers!`. + strerror_impl(num) } From 2e06858998c28d5918e39e772f12f3ce9cb7721f Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 12:18:38 +0100 Subject: [PATCH 04/17] repair strerror --- src/kernel/src/errno.rs | 202 ++++++++++++++++++++-------------------- 1 file changed, 101 insertions(+), 101 deletions(-) diff --git a/src/kernel/src/errno.rs b/src/kernel/src/errno.rs index 71f0853f3..7db492831 100644 --- a/src/kernel/src/errno.rs +++ b/src/kernel/src/errno.rs @@ -4,7 +4,7 @@ use std::error::Error; use std::num::NonZeroI32; macro_rules! error_numbers { - ($($name:ident => $num:expr,)*) => { + ($($name:ident($num:expr) => $desc:literal,)*) => { $( #[allow(dead_code)] pub const $name: NonZeroI32 = unsafe { @@ -16,7 +16,7 @@ macro_rules! error_numbers { #[inline(always)] pub fn strerror_impl(num: NonZeroI32) -> &'static str { match num { - $( $name => stringify!($name), )* + $( $name => $desc, )* _ => todo!("strerror {num}", num = num.get()), } } @@ -24,105 +24,105 @@ macro_rules! error_numbers { } error_numbers! { - EPERM => 1, - ENOENT => 2, - ESRCH => 3, - EINTR => 4, - EIO => 5, - ENXIO => 6, - E2BIG => 7, - ENOEXEC => 8, - EBADF => 9, - ECHILD => 10, - EDEADLK => 11, - ENOMEM => 12, - EACCES => 13, - EFAULT => 14, - ENOTBLK => 15, - EBUSY => 16, - EEXIST => 17, - EXDEV => 18, - ENODEV => 19, - ENOTDIR => 20, - EISDIR => 21, - EINVAL => 22, - ENFILE => 23, - EMFILE => 24, - ENOTTY => 25, - ETXTBSY => 26, - EFBIG => 27, - ENOSPC => 28, - ESPIPE => 29, - EROFS => 30, - EMLINK => 31, - EPIPE => 32, - EDOM => 33, - ERANGE => 34, - EAGAIN => 35, - EINPROGRESS => 36, - EALREADY => 37, - ENOTSOCK => 38, - EDESTADDRREQ => 39, - EMSGSIZE => 40, - EPROTOTYPE => 41, - ENOPROTOOPT => 42, - EPROTONOSUPPORT => 43, - ESOCKTNOSUPPORT => 44, - EOPNOTSUPP => 45, - EPFNOSUPPORT => 46, - EAFNOSUPPORT => 47, - EADDRINUSE => 48, - EADDRNOTAVAIL => 49, - ENETDOWN => 50, - ENETUNREACH => 51, - ENETRESET => 52, - ECONNABORTED => 53, - ECONNRESET => 54, - ENOBUFS => 55, - EISCONN => 56, - ENOTCONN => 57, - ESHUTDOWN => 58, - ETOOMANYREFS => 59, - ETIMEDOUT => 60, - ECONNREFUSED => 61, - ELOOP => 62, - ENAMETOOLONG => 63, - EHOSTDOWN => 64, - EHOSTUNREACH => 65, - ENOTEMPTY => 66, - EPROCLIM => 67, - EUSERS => 68, - EDQUOT => 69, - ESTALE => 70, - EREMOTE => 71, - EBADRPC => 72, - ERPCMISMATCH => 73, - EPROGUNAVAIL => 74, - EPROGMISMATCH => 75, - EPROCUNAVAIL => 76, - ENOLCK => 77, - ENOSYS => 78, - EFTYPE => 79, - EAUTH => 80, - ENEEDAUTH => 81, - EIDRM => 82, - ENOMSG => 83, - EOVERFLOW => 84, - ECANCELED => 85, - EILSEQ => 86, - ENOATTR => 87, - EDOOFUS => 88, - EBADMSG => 89, - EMULTIHOP => 90, - ENOLINK => 91, - EPROTO => 92, - ENOTCAPABLE => 93, - ECAPMODE => 94, - ENOBLK => 95, - EICV => 96, - ENOPLAYGOENT => 97, - EREVOKE => 98, - ESDKVERSION => 99, + EPERM(1) => "operation not permitted", + ENOENT(2) => "no such file or directory", + ESRCH(3) => "no such process", + EINTR(4) => "interrupted system call", + EIO(5) => "input/output error", + ENXIO(6) => "no such device or address", + E2BIG(7) => "argument list too long", + ENOEXEC(8) => "exec format error", + EBADF(9) => "bad file descriptor", + ECHILD(10) => "no child processes", + EDEADLK(11) => "resource temporarily unavailable", + ENOMEM(12) => "cannot allocate memory", + EACCES(13) => "permission denied", + EFAULT(14) => "bad address", + ENOTBLK(15) => "block device required", + EBUSY(16) => "device or resource busy", + EEXIST(17) => "file exists", + EXDEV(18) => "cross-device link", + ENODEV(19) => "no such device", + ENOTDIR(20) => "not a directory", + EISDIR(21) => "is a directory", + EINVAL(22) => "invalid argument", + ENFILE(23) => "too many open files in system", + EMFILE(24) => "too many open files", + ENOTTY(25) => "inappropriate ioctl for device", + ETXTBSY(26) => "text file busy", + EFBIG(27) => "file too large", + ENOSPC(28) => "no space left on device", + ESPIPE(29) => "illegal seek", + EROFS(30) => "read-only file system", + EMLINK(31) => "too many links", + EPIPE(32) => "broken pipe", + EDOM(33) => "numerical argument out of domain", + ERANGE(34) => "result too large", + EAGAIN(35) => "resource temporarily unavailable", + EINPROGRESS(36) => "operation now in progress", + EALREADY(37) => "operation already in progress", + ENOTSOCK(38) => "socket operation on non-socket", + EDESTADDRREQ(39) => "destination address required", + EMSGSIZE(40) => "message too long", + EPROTOTYPE(41) => "protocol wrong type for socket", + ENOPROTOOPT(42) => "protocol not available", + EPROTONOSUPPORT(43) => "protocol not supported", + ESOCKTNOSUPPORT(44) => "socket type not supported", + EOPNOTSUPP(45) => "operation not supported", + EPFNOSUPPORT(46) => "protocol family not supported", + EAFNOSUPPORT(47) => "address family not supported by protocol", + EADDRINUSE(48) => "address already in use", + EADDRNOTAVAIL(49) => "can't assign requested address", + ENETDOWN(50) => "network is down", + ENETUNREACH(51) => "network is unreachable", + ENETRESET(52) => "network dropped connection on reset", + ECONNABORTED(53) => "software caused connection abort", + ECONNRESET(54) => "connection reset by peer", + ENOBUFS(55) => "no buffer space available", + EISCONN(56) => "socket is already connected", + ENOTCONN(57) => "socket is not connected", + ESHUTDOWN(58) => "can't send after socket shutdown", + ETOOMANYREFS(59) => "too many references: can't splice", + ETIMEDOUT(60) => "operation timed out", + ECONNREFUSED(61) => "connection refused", + ELOOP(62) => "too many levels of symbolic links", + ENAMETOOLONG(63) => "file name too long", + EHOSTDOWN(64) => "host is down", + EHOSTUNREACH(65) => "no route to host", + ENOTEMPTY(66) => "directory not empty", + EPROCLIM(67) => "too many processes", + EUSERS(68) => "too many users", + EDQUOT(69) => "disc quota exceeded", + ESTALE(70) => "stale NFS file handle", + EREMOTE(71) => "too many levels of remote in path", + EBADRPC(72) => "RPC struct is bad", + ERPCMISMATCH(73) => "RPC version wrong", + EPROGUNAVAIL(74) => "RPC prog. not avail.", + EPROGMISMATCH(75) => "program version wrong", + EPROCUNAVAIL(76) => "bad procedure for program", + ENOLCK(77) => "no locks available", + ENOSYS(78) => "function not implemented", + EFTYPE(79) => "inappropriate file type or format", + EAUTH(80) => "authentication error", + ENEEDAUTH(81) => "need authenticator", + EIDRM(82) => "identifier removed", + ENOMSG(83) => "no message of desired type", + EOVERFLOW(84) => "value too large to be stored in data type", + ECANCELED(85) => "operation canceled", + EILSEQ(86) => "illegal byte sequence", + ENOATTR(87) => "attribute not found", + EDOOFUS(88) => "function or API is being abused at run-time", + EBADMSG(89) => "bad message", + EMULTIHOP(90) => "multihop attempted", + ENOLINK(91) => "link has been severed", + EPROTO(92) => "protocol error", + ENOTCAPABLE(93) => "capabilities insufficient", + ECAPMODE(94) => "not permitted in capability mode", + ENOBLK(95) => "block not ready", + EICV(96) => "integrity check error", + ENOPLAYGOENT (97) => "file not found in PlayGo chunk definition file", + EREVOKE(98) => "file is revoked", + ESDKVERSION(99) => "SDK version of a binary file is invalid", } /// An object that is mappable to PS4 errno. From fed0138633902d2daffcb32182b502c54d3e46d3 Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 12:28:34 +0100 Subject: [PATCH 05/17] refactor --- src/kernel/src/signal/mod.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 9ec08a792..48e262f73 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -13,6 +13,13 @@ mod set; pub struct Signal(NonZeroI32); impl Signal { + pub fn new(raw: i32) -> Option { + match raw { + 1..=SIG_MAXSIG => Some(Signal(unsafe { NonZeroI32::new_unchecked(raw) })), + _ => None, + } + } + pub fn get(&self) -> i32 { self.0.get() } @@ -24,10 +31,7 @@ impl TryFrom for Signal { fn try_from(value: SysArg) -> Result { let value: i32 = value.try_into().map_err(|_| SysErr::Raw(EINVAL))?; - match value { - 1..=SIG_MAXSIG => Ok(Signal(unsafe { NonZeroI32::new_unchecked(value) })), - _ => Err(SysErr::Raw(EINVAL)), - } + Signal::new(value).ok_or(SysErr::Raw(EINVAL)) } } From 942689b2fc498d5b4611044cdc78b494b9a61d6a Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 12:32:24 +0100 Subject: [PATCH 06/17] ref signal macro --- src/kernel/src/signal/mod.rs | 69 ++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 48e262f73..638d1198a 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -36,7 +36,7 @@ impl TryFrom for Signal { } macro_rules! signals { - ($($name:ident => $num:expr,)*) => { + ($($name:ident($num:expr),)*) => { $( #[allow(dead_code)] pub const $name: Signal = Signal(unsafe { @@ -56,40 +56,41 @@ macro_rules! signals { } // List of PS4 signals. The value must be the same as PS4 kernel. +#[rustfmt::skip] signals!( - SIGHUP => 1, - SIGINT => 2, - SIGQUIT => 3, - SIGILL => 4, - SIGTRAP => 5, - SIGABRT => 6, - SIGEMT => 7, - SIGFPE => 8, - SIGKILL => 9, - SIGBUS => 10, - SIGSEGV => 11, - SIGSYS => 12, - SIGPIPE => 13, - SIGALRM => 14, - SIGTERM => 15, - SIGURG => 16, - SIGSTOP => 17, - SIGTSTP => 18, - SIGCONT => 19, - SIGCHLD => 20, - SIGTTIN => 21, - SIGTTOU => 22, - SIGIO => 23, - SIGXCPU => 24, - SIGXFSZ => 25, - SIGVTALRM => 26, - SIGPROF => 27, - SIGWINCH => 28, - SIGINFO => 29, - SIGUSR1 => 30, - SIGUSR2 => 31, - SIGTHR => 32, - SIGNONE => 128, + SIGHUP(1), + SIGINT(2), + SIGQUIT(3), + SIGILL(4), + SIGTRAP(5), + SIGABRT(6), + SIGEMT(7), + SIGFPE(8), + SIGKILL(9), + SIGBUS(10), + SIGSEGV(11), + SIGSYS(12), + SIGPIPE(13), + SIGALRM(14), + SIGTERM(15), + SIGURG(16), + SIGSTOP(17), + SIGTSTP(18), + SIGCONT(19), + SIGCHLD(20), + SIGTTIN(21), + SIGTTOU(22), + SIGIO(23), + SIGXCPU(24), + SIGXFSZ(25), + SIGVTALRM(26), + SIGPROF(27), + SIGWINCH(28), + SIGINFO(29), + SIGUSR1(30), + SIGUSR2(31), + SIGTHR(32), + SIGNONE(128), ); pub fn strsignal(sig: Signal) -> Cow<'static, str> { From ff705da606d27bbf139f4b63253a62306649d23c Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 3 Feb 2024 13:08:19 +0100 Subject: [PATCH 07/17] correction --- src/kernel/src/process/mod.rs | 5 ++++- src/kernel/src/process/signal.rs | 1 - src/kernel/src/signal/mod.rs | 12 ------------ 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/kernel/src/process/mod.rs b/src/kernel/src/process/mod.rs index 2f90187a3..40721798e 100644 --- a/src/kernel/src/process/mod.rs +++ b/src/kernel/src/process/mod.rs @@ -285,7 +285,10 @@ impl VProc { fn sys_sigaction(self: &Arc, i: &SysIn) -> Result { // Get arguments. - let sig: Signal = i.args[0].try_into()?; + let sig = { + let sig: i32 = i.args[0].try_into().unwrap(); + Signal::new(sig).ok_or(SysErr::Raw(EINVAL))? + }; let act: *const SignalAct = i.args[1].into(); let oact: *mut SignalAct = i.args[2].into(); diff --git a/src/kernel/src/process/signal.rs b/src/kernel/src/process/signal.rs index 196d4e36e..2b8be9cbf 100644 --- a/src/kernel/src/process/signal.rs +++ b/src/kernel/src/process/signal.rs @@ -1,5 +1,4 @@ use crate::signal::{Signal, SignalSet, SIG_MAXSIG}; -use std::num::NonZeroI32; /// An implementation of `sigacts` structure. #[derive(Debug)] diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 638d1198a..9622c09f4 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -1,7 +1,5 @@ pub use self::set::*; -use crate::errno::EINVAL; -use crate::syscalls::{SysArg, SysErr}; use bitflags::bitflags; use std::borrow::Cow; use std::fmt::{Display, Formatter}; @@ -25,16 +23,6 @@ impl Signal { } } -impl TryFrom for Signal { - type Error = SysErr; - - fn try_from(value: SysArg) -> Result { - let value: i32 = value.try_into().map_err(|_| SysErr::Raw(EINVAL))?; - - Signal::new(value).ok_or(SysErr::Raw(EINVAL)) - } -} - macro_rules! signals { ($($name:ident($num:expr),)*) => { $( From c2469ffdb5dedd879fb0c191db57443f55c98da2 Mon Sep 17 00:00:00 2001 From: tompro Date: Mon, 5 Feb 2024 15:43:26 +0100 Subject: [PATCH 08/17] remove inline --- src/kernel/src/errno.rs | 1 - src/kernel/src/signal/mod.rs | 1 - 2 files changed, 2 deletions(-) diff --git a/src/kernel/src/errno.rs b/src/kernel/src/errno.rs index 7db492831..3b134f60b 100644 --- a/src/kernel/src/errno.rs +++ b/src/kernel/src/errno.rs @@ -13,7 +13,6 @@ macro_rules! error_numbers { }; )* - #[inline(always)] pub fn strerror_impl(num: NonZeroI32) -> &'static str { match num { $( $name => $desc, )* diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 9622c09f4..e8406c7c4 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -33,7 +33,6 @@ macro_rules! signals { }); )* - #[inline(always)] pub fn strsignal_impl(sig: Signal) -> Cow<'static, str> { match sig.0.get() { $( $num => Cow::Borrowed(stringify!($name)), )* From b75e449bf2404c50af7ea5e61f244b0bec38fd86 Mon Sep 17 00:00:00 2001 From: tompro Date: Fri, 9 Feb 2024 23:23:20 +0100 Subject: [PATCH 09/17] minor refactor --- src/kernel/src/signal/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index e8406c7c4..395a43dbc 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -119,7 +119,7 @@ impl Iterator for SignalIter { } fn size_hint(&self) -> (usize, Option) { - let len = (SIG_MAXSIG - self.current + 1) as usize; + let len = self.len(); (len, Some(len)) } } From ccca3e7084687011e75c6f5d3ef221611b7996d6 Mon Sep 17 00:00:00 2001 From: tompro Date: Fri, 9 Feb 2024 23:29:58 +0100 Subject: [PATCH 10/17] use filter --- src/kernel/src/signal/set.rs | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/kernel/src/signal/set.rs b/src/kernel/src/signal/set.rs index dd91b5045..7a7cbaf1f 100644 --- a/src/kernel/src/signal/set.rs +++ b/src/kernel/src/signal/set.rs @@ -72,15 +72,13 @@ impl Display for SignalSet { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let mut first = true; - for sig in SignalIter::new() { - if self.contains(sig) { - if !first { - f.write_str(" | ")?; - } - - f.write_str(strsignal(sig).as_ref())?; - first = false; + for sig in SignalIter::new().filter(|sig| self.contains(*sig)) { + if !first { + f.write_str(" | ")?; } + + f.write_str(strsignal(sig).as_ref())?; + first = false; } if first { From d2e011d87fa1fa0df51253c75740a92df6ebb678 Mon Sep 17 00:00:00 2001 From: tompro Date: Sun, 11 Feb 2024 16:14:46 +0100 Subject: [PATCH 11/17] fix desc --- src/kernel/src/errno.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/kernel/src/errno.rs b/src/kernel/src/errno.rs index 3b134f60b..d2a8c942f 100644 --- a/src/kernel/src/errno.rs +++ b/src/kernel/src/errno.rs @@ -28,20 +28,20 @@ error_numbers! { ESRCH(3) => "no such process", EINTR(4) => "interrupted system call", EIO(5) => "input/output error", - ENXIO(6) => "no such device or address", + ENXIO(6) => "device not configured", E2BIG(7) => "argument list too long", ENOEXEC(8) => "exec format error", EBADF(9) => "bad file descriptor", ECHILD(10) => "no child processes", - EDEADLK(11) => "resource temporarily unavailable", + EDEADLK(11) => "resource deadlock avoided", ENOMEM(12) => "cannot allocate memory", EACCES(13) => "permission denied", EFAULT(14) => "bad address", ENOTBLK(15) => "block device required", - EBUSY(16) => "device or resource busy", + EBUSY(16) => "device busy", EEXIST(17) => "file exists", EXDEV(18) => "cross-device link", - ENODEV(19) => "no such device", + ENODEV(19) => "operation not supported by device", ENOTDIR(20) => "not a directory", EISDIR(21) => "is a directory", EINVAL(22) => "invalid argument", @@ -52,7 +52,7 @@ error_numbers! { EFBIG(27) => "file too large", ENOSPC(28) => "no space left on device", ESPIPE(29) => "illegal seek", - EROFS(30) => "read-only file system", + EROFS(30) => "read-only filesystem", EMLINK(31) => "too many links", EPIPE(32) => "broken pipe", EDOM(33) => "numerical argument out of domain", From 16cd26f7ea03f0b40c77e1b2aab4ff4852a6ed6d Mon Sep 17 00:00:00 2001 From: tompro Date: Tue, 13 Feb 2024 22:32:52 +0100 Subject: [PATCH 12/17] improve --- src/kernel/src/signal/set.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/kernel/src/signal/set.rs b/src/kernel/src/signal/set.rs index 7a7cbaf1f..e9bef9cb8 100644 --- a/src/kernel/src/signal/set.rs +++ b/src/kernel/src/signal/set.rs @@ -32,7 +32,8 @@ impl SignalSet { /// An implementation of `_SIG_WORD`. fn word(s: Signal) -> usize { - (Self::idx(s) >> 5).try_into().unwrap() + // This is safe because `Signal` is guaranteed to be non-negative. + unsafe { (Self::idx(s) >> 5).try_into().unwrap_unchecked() } } /// An implementation of `_SIG_BIT`. From 3190d1f7333868388f66fc188d1ce0984826ec72 Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 17 Feb 2024 20:31:02 +0100 Subject: [PATCH 13/17] fmt --- src/kernel/src/process/mod.rs | 2 +- src/kernel/src/process/signal.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/kernel/src/process/mod.rs b/src/kernel/src/process/mod.rs index f5ce87523..c9de2f401 100644 --- a/src/kernel/src/process/mod.rs +++ b/src/kernel/src/process/mod.rs @@ -12,11 +12,11 @@ use crate::errno::{EINVAL, ENAMETOOLONG, EPERM, ERANGE, ESRCH}; use crate::fs::Vnode; use crate::idt::Idt; use crate::info; -use crate::signal::{Signal, SigChldFlags}; use crate::signal::{ strsignal, SignalAct, SignalFlags, SignalSet, SIGCHLD, SIGKILL, SIGSTOP, SIG_BLOCK, SIG_DFL, SIG_IGN, SIG_SETMASK, SIG_UNBLOCK, }; +use crate::signal::{SigChldFlags, Signal}; use crate::syscalls::{SysErr, SysIn, SysOut, Syscalls}; use crate::ucred::{AuthInfo, Gid, Privilege, Ucred, Uid}; use gmtx::{Gutex, GutexGroup, GutexWriteGuard}; diff --git a/src/kernel/src/process/signal.rs b/src/kernel/src/process/signal.rs index 6721bde29..483158b68 100644 --- a/src/kernel/src/process/signal.rs +++ b/src/kernel/src/process/signal.rs @@ -1,4 +1,4 @@ -use crate::signal::{Signal, SigChldFlags, SignalFlags, SignalSet, SIGCHLD, SIG_MAXSIG}; +use crate::signal::{SigChldFlags, Signal, SignalFlags, SignalSet, SIGCHLD, SIG_MAXSIG}; /// An implementation of `sigacts` structure. #[derive(Debug)] From bb3cb132fad2c180dfd672b6a808068bb6318cf1 Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 11:38:29 +0100 Subject: [PATCH 14/17] change braces --- src/kernel/src/signal/mod.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 5fc06c878..302743fde 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -43,8 +43,7 @@ macro_rules! signals { } // List of PS4 signals. The value must be the same as PS4 kernel. -#[rustfmt::skip] -signals!( +signals! { SIGHUP(1), SIGINT(2), SIGQUIT(3), @@ -78,7 +77,7 @@ signals!( SIGUSR2(31), SIGTHR(32), SIGNONE(128), -); +} pub fn strsignal(sig: Signal) -> Cow<'static, str> { // This function is generated inside the macro `signals!`. From b0e45d3e92cc59f6d436642e7488a1ec3972b1f0 Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 12:23:49 +0100 Subject: [PATCH 15/17] ref --- src/kernel/src/errno.rs | 2 +- src/kernel/src/signal/mod.rs | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/kernel/src/errno.rs b/src/kernel/src/errno.rs index c569feb12..87d404f65 100644 --- a/src/kernel/src/errno.rs +++ b/src/kernel/src/errno.rs @@ -14,7 +14,7 @@ macro_rules! error_numbers { }; )* - pub fn strerror_impl(num: NonZeroI32) -> &'static str { + fn strerror_impl(num: NonZeroI32) -> &'static str { match num { $( $name => $desc, )* _ => todo!("strerror {num}", num = num.get()), diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 302743fde..2d5e03248 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -11,7 +11,7 @@ mod set; pub struct Signal(NonZeroI32); impl Signal { - pub fn new(raw: i32) -> Option { + pub const fn new(raw: i32) -> Option { match raw { 1..=SIG_MAXSIG => Some(Signal(unsafe { NonZeroI32::new_unchecked(raw) })), _ => None, @@ -27,13 +27,13 @@ macro_rules! signals { ($($name:ident($num:expr),)*) => { $( #[allow(dead_code)] - pub const $name: Signal = Signal(unsafe { - assert!($num > 0 && $num <= SIG_MAXSIG); - NonZeroI32::new_unchecked($num) - }); + pub const $name: Signal = match Signal::new($num) { + Some(sig) => sig, + None => panic!(), + }; )* - pub fn strsignal_impl(sig: Signal) -> Cow<'static, str> { + fn strsignal_impl(sig: Signal) -> Cow<'static, str> { match sig.0.get() { $( $num => Cow::Borrowed(stringify!($name)), )* _ => format!("{sig}", sig = sig.get()).into(), From 31009e54a25386c740782191559b98a0193718dc Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 13:16:57 +0100 Subject: [PATCH 16/17] ref --- src/kernel/src/signal/mod.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 2d5e03248..25a455576 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -108,13 +108,14 @@ impl Iterator for SignalIter { type Item = Signal; fn next(&mut self) -> Option { - if self.current <= SIG_MAXSIG { - let signal = Signal(unsafe { NonZeroI32::new_unchecked(self.current) }); - self.current += 1; - Some(signal) - } else { - None + if self.current > SIG_MAXSIG { + return None; } + + let sig = Signal::new(self.current); + self.current += 1; + + sig } fn size_hint(&self) -> (usize, Option) { From d45167608a1fc58bf5690c45019a7d95a449642a Mon Sep 17 00:00:00 2001 From: tompro Date: Sat, 24 Feb 2024 14:10:49 +0100 Subject: [PATCH 17/17] ref --- src/kernel/src/signal/mod.rs | 12 +++++------- src/kernel/src/signal/set.rs | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/kernel/src/signal/mod.rs b/src/kernel/src/signal/mod.rs index 25a455576..805962e66 100644 --- a/src/kernel/src/signal/mod.rs +++ b/src/kernel/src/signal/mod.rs @@ -108,14 +108,12 @@ impl Iterator for SignalIter { type Item = Signal; fn next(&mut self) -> Option { - if self.current > SIG_MAXSIG { - return None; + if let Some(sig) = Signal::new(self.current) { + self.current += 1; + Some(sig) + } else { + None } - - let sig = Signal::new(self.current); - self.current += 1; - - sig } fn size_hint(&self) -> (usize, Option) { diff --git a/src/kernel/src/signal/set.rs b/src/kernel/src/signal/set.rs index e9bef9cb8..0d52a2266 100644 --- a/src/kernel/src/signal/set.rs +++ b/src/kernel/src/signal/set.rs @@ -33,7 +33,7 @@ impl SignalSet { /// An implementation of `_SIG_WORD`. fn word(s: Signal) -> usize { // This is safe because `Signal` is guaranteed to be non-negative. - unsafe { (Self::idx(s) >> 5).try_into().unwrap_unchecked() } + unsafe { (Self::idx(s) >> 5).try_into().unwrap() } } /// An implementation of `_SIG_BIT`.