refactor: better Pid type

This commit is contained in:
2021-11-30 18:07:39 +02:00
parent 4ffbb8c115
commit e965c25181
8 changed files with 67 additions and 40 deletions
+12 -12
View File
@@ -196,11 +196,11 @@ pub fn sys_fstatat(
/// System call
#[inline(always)]
pub unsafe fn sys_fork() -> Result<Option<Pid>, Errno> {
Errno::from_syscall(syscall!(SystemCall::Fork)).map(|res| {
Errno::from_syscall(syscall!(SystemCall::Fork)).and_then(|res| {
if res != 0 {
Some(unsafe { Pid::from_raw(res as u32) })
Pid::try_from(res as u32).map(Some)
} else {
None
Ok(None)
}
})
}
@@ -229,7 +229,7 @@ pub fn sys_waitpid(pid: Pid, status: &mut i32) -> Result<(), Errno> {
Errno::from_syscall_unit(unsafe {
syscall!(
SystemCall::WaitPid,
argn!(pid.value()),
argn!(u32::from(pid)),
argp!(status as *mut i32)
)
})
@@ -362,21 +362,21 @@ pub fn sys_ex_gettid() -> u32 {
#[inline(always)]
pub fn sys_getpid() -> Pid {
unsafe { Pid::from_raw(syscall!(SystemCall::GetPid) as u32) }
Pid::try_from(unsafe { syscall!(SystemCall::GetPid) as u32 }).unwrap()
}
#[inline(always)]
pub fn sys_getpgid(pid: Pid) -> Result<Pid, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::GetPgid, argn!(pid.value())) })
.map(|e| unsafe { Pid::from_raw(e as u32) })
pub fn sys_getpgid(pid: Option<Pid>) -> Result<Pid, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::GetPgid, argn!(Pid::from_option(pid))) })
.and_then(|e| Pid::try_from(e as u32))
}
#[inline(always)]
pub fn sys_setpgid(pid: Pid, pgid: Pid) -> Result<Pid, Errno> {
pub fn sys_setpgid(pid: Option<Pid>, pgid: Option<Pid>) -> Result<Pid, Errno> {
Errno::from_syscall(unsafe {
syscall!(SystemCall::SetPgid, argn!(pid.value()), argn!(pgid.value()))
syscall!(SystemCall::SetPgid, argn!(Pid::from_option(pid)), argn!(Pid::from_option(pgid)))
})
.map(|e| unsafe { Pid::from_raw(e as u32) })
.and_then(|e| Pid::try_from(e as u32))
}
#[inline(always)]
@@ -404,7 +404,7 @@ pub fn sys_getgid() -> GroupId {
#[inline(always)]
pub fn sys_setsid() -> Result<Pid, Errno> {
Errno::from_syscall(unsafe { syscall!(SystemCall::SetSid) })
.map(|e| unsafe { Pid::from_raw(e as u32) })
.and_then(|e| Pid::try_from(e as u32) )
}
#[inline(always)]
+38 -11
View File
@@ -12,6 +12,11 @@ pub struct ExitCode(i32);
#[repr(transparent)]
pub struct Pid(u32);
/// Wrapper type for thread ID
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
#[repr(transparent)]
pub struct Tid(u32);
#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Debug)]
#[repr(transparent)]
pub struct Pgid(u32);
@@ -57,10 +62,14 @@ impl Pid {
pub const IDLE: Self = Self(Self::KERNEL_BIT);
const KERNEL_BIT: u32 = 1 << 31;
const USER_MAX: u32 = 256;
/// Constructs an instance of user-space PID
pub const fn user(id: u32) -> Self {
assert!(id < 256, "PID is too high");
assert!(id < Self::USER_MAX, "PID is too high");
if id == 0 {
panic!("User PID cannot be zero");
}
Self(id)
}
@@ -83,18 +92,16 @@ impl Pid {
self.0 as u8
}
/// Returns bit value of this pid
pub const fn value(self) -> u32 {
self.0
pub fn from_option(m: Option<Self>) -> u32 {
if let Some(pid) = m {
u32::from(pid)
} else {
0
}
}
/// Constructs [Pid] from raw [u32] value
///
/// # Safety
///
/// Unsafe: does not check `num`
pub const unsafe fn from_raw(num: u32) -> Self {
Self(num)
pub fn to_option(m: u32) -> Option<Self> {
todo!()
}
}
@@ -109,6 +116,26 @@ impl fmt::Debug for Pid {
}
}
impl TryFrom<u32> for Pid {
type Error = Errno;
fn try_from(raw: u32) -> Result<Pid, Errno> {
if raw & Self::KERNEL_BIT != 0 {
Ok(Pid::kernel(raw & !Self::KERNEL_BIT))
} else if raw != 0 && raw < Self::USER_MAX {
Ok(Pid::user(raw))
} else {
Err(Errno::InvalidArgument)
}
}
}
impl From<Pid> for u32 {
fn from(pid: Pid) -> u32 {
pid.0
}
}
impl TryFrom<Pid> for Pgid {
type Error = Errno;
+1 -1
View File
@@ -37,7 +37,7 @@ impl From<isize> for SignalDestination {
impl From<SignalDestination> for isize {
fn from(p: SignalDestination) -> isize {
match p {
SignalDestination::Process(pid) => pid.value() as isize,
SignalDestination::Process(pid) => u32::from(pid) as isize,
SignalDestination::Group(pgid) => -(u32::from(pgid) as isize),
SignalDestination::This => 0,
SignalDestination::All => -1