diff --git a/litebox_common_linux/src/lib.rs b/litebox_common_linux/src/lib.rs index 67c904275..ab245d390 100644 --- a/litebox_common_linux/src/lib.rs +++ b/litebox_common_linux/src/lib.rs @@ -1851,11 +1851,11 @@ bitflags::bitflags! { } } -/// Packaged sigset with its size, used by `pselect` syscall -#[derive(Clone, Copy, FromBytes, IntoBytes)] +/// Packaged sigset pointer with its size, used by `pselect6` syscall. +#[derive(Clone, Copy, FromBytes)] #[repr(C)] -pub struct SigSetPack { - pub sigset: SigSet, +pub struct SigSetPack { + pub sigset: Platform::RawConstPointer, pub size: usize, } @@ -2272,7 +2272,7 @@ pub enum SyscallRequest { writefds: Option>, exceptfds: Option>, timeout: TimeParam, - sigsetpack: Option>, + sigsetpack: Option>>, }, ArchPrctl { arg: ArchPrctlArg, diff --git a/litebox_shim_linux/src/syscalls/file.rs b/litebox_shim_linux/src/syscalls/file.rs index 06020e270..d5d087e9e 100644 --- a/litebox_shim_linux/src/syscalls/file.rs +++ b/litebox_shim_linux/src/syscalls/file.rs @@ -2248,11 +2248,17 @@ impl Task { writefds: Option>, exceptfds: Option>, timeout: TimeParam, - sigsetpack: Option>, + sigsetpack: Option>>, ) -> Result { - if sigsetpack.is_some() { - unimplemented!("no sigsetpack support yet"); - } + let sigmask = if let Some(sigsetpack) = sigsetpack { + let sigsetpack = sigsetpack.read_at_offset(0).ok_or(Errno::EFAULT)?; + if sigsetpack.size != core::mem::size_of::() { + return Err(Errno::EINVAL); + } + Some(sigsetpack.sigset.read_at_offset(0).ok_or(Errno::EFAULT)?) + } else { + None + }; let timeout = timeout.read()?; if nfds >= i32::MAX as u32 || nfds as usize @@ -2277,13 +2283,20 @@ impl Task { .transpose()? .map(|fds| bitvec::vec::BitVec::from_vec(fds.into_vec())); - let count = self.do_pselect( - nfds, - kreadfds.as_mut(), - kwritefds.as_mut(), - kexceptfds.as_mut(), - timeout, - )?; + let mut do_pselect = || { + self.do_pselect( + nfds, + kreadfds.as_mut(), + kwritefds.as_mut(), + kexceptfds.as_mut(), + timeout, + ) + }; + let count = if let Some(sigmask) = sigmask { + self.with_temporary_signal_mask(sigmask, do_pselect) + } else { + do_pselect() + }?; if let Some(fds) = kreadfds { readfds diff --git a/litebox_shim_linux/src/syscalls/signal/mod.rs b/litebox_shim_linux/src/syscalls/signal/mod.rs index e61e74d6d..86e6436ac 100644 --- a/litebox_shim_linux/src/syscalls/signal/mod.rs +++ b/litebox_shim_linux/src/syscalls/signal/mod.rs @@ -381,6 +381,14 @@ impl SignalState { struct DeliverFault; impl Task { + pub(crate) fn with_temporary_signal_mask(&self, mask: SigSet, f: impl FnOnce() -> R) -> R { + let old = self.signals.blocked.get(); + self.signals.set_signal_mask(mask); + let result = f(); + self.signals.set_signal_mask(old); + result + } + pub(crate) fn sys_rt_sigprocmask( &self, how: SigmaskHow,