Remove round-7 stubs: todo!(), unimplemented!(), silent no-ops
Six items fixed from the round-7 relibc stub scan: 1. set_scheduler todo!() (mod.rs:1487) — replaced panic with proper policy validation: SCHED_OTHER is a no-op (kernel default), RT policies (FIFO/RR) return ENOSYS (need kernel support Redox lacks), invalid policies return EINVAL. Made posix_spawnattr_t.policy pub(crate) so the platform layer can read it. 2. F_SETLKW silent no-op (mod.rs:474) — merged into the F_SETLK | F_OFD_SETLK match arm. Redox's StdFsCallKind::Lock blocks at the kernel level, so F_SETLKW uses the same code path as F_SETLK. The is_ofd flag correctly evaluates to false for F_SETLKW. 3. relative_to_absolute_foffset silent (0,0) (mod.rs:1989) — implemented SEEK_CUR via lseek(fd, 0, SEEK_CUR) and SEEK_END via fstat(fd). Both apply the same negative-len normalization as SEEK_SET. Invalid whence values now return EINVAL instead of corrupting offsets. 4. setitimer ENOSYS (signal.rs:96) — replaced todo_skip! stub with a real implementation using a process-global POSIX timer (timer_create with CLOCK_REALTIME + SIGEV_SIGNAL/SIGALRM). Supports intervals (periodic timers), disarm (value=0), and old-value retrieval. getitimer also updated to read from the real timer instead of returning defaults. 5. ptrace unimplemented!() (ptrace.rs:127,138,279) — replaced three panics on aarch64/x86/riscv64 with Err(io::Error::from_raw_os_error( ENOSYS)). The caller maps this to Errno(ENOSYS), the proper POSIX response for architecture-specific ptrace on unsupported arches. 6. todo_skip! macro verified (macros.rs:47) — confirmed it is non-panicking (logs via log::info! and evaluates to ()). The setitimer stub was safe in that it returned ENOSYS after the log, but the real implementation is strictly better.
This commit is contained in:
@@ -41,7 +41,7 @@ pub struct posix_spawnattr_t {
|
|||||||
pub param: sched_param,
|
pub param: sched_param,
|
||||||
pub flags: c_short,
|
pub flags: c_short,
|
||||||
pub pgroup: c_int,
|
pub pgroup: c_int,
|
||||||
policy: c_int,
|
pub(crate) policy: c_int,
|
||||||
pub sigdefault: sigset_t,
|
pub sigdefault: sigset_t,
|
||||||
pub sigmask: sigset_t,
|
pub sigmask: sigset_t,
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-10
@@ -38,6 +38,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
limits::{self},
|
limits::{self},
|
||||||
pthread::{pthread_cancel, pthread_create},
|
pthread::{pthread_cancel, pthread_create},
|
||||||
|
sched::{SCHED_FIFO, SCHED_OTHER, SCHED_RR},
|
||||||
signal::{NSIG, SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD, SIGRTMIN, sigevent},
|
signal::{NSIG, SIGEV_NONE, SIGEV_SIGNAL, SIGEV_THREAD, SIGRTMIN, sigevent},
|
||||||
stdio::RENAME_NOREPLACE,
|
stdio::RENAME_NOREPLACE,
|
||||||
stdlib::posix_memalign,
|
stdlib::posix_memalign,
|
||||||
@@ -56,7 +57,7 @@ use crate::{
|
|||||||
time::{
|
time::{
|
||||||
CLOCK_MONOTONIC, CLOCK_REALTIME, TIMER_ABSTIME, itimerspec, timer_internal_t, timespec,
|
CLOCK_MONOTONIC, CLOCK_REALTIME, TIMER_ABSTIME, itimerspec, timer_internal_t, timespec,
|
||||||
},
|
},
|
||||||
unistd::{F_OK, R_OK, SEEK_CUR, SEEK_SET, W_OK, X_OK},
|
unistd::{F_OK, R_OK, SEEK_CUR, SEEK_END, SEEK_SET, W_OK, X_OK},
|
||||||
},
|
},
|
||||||
io::{self, BufReader, prelude::*},
|
io::{self, BufReader, prelude::*},
|
||||||
iter::NulTerminated,
|
iter::NulTerminated,
|
||||||
@@ -367,7 +368,7 @@ impl Pal for Sys {
|
|||||||
|
|
||||||
fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> Result<c_int> {
|
fn fcntl(fd: c_int, cmd: c_int, args: c_ulonglong) -> Result<c_int> {
|
||||||
match cmd {
|
match cmd {
|
||||||
F_SETLK | F_OFD_SETLK => {
|
F_SETLK | F_OFD_SETLK | F_SETLKW => {
|
||||||
let is_ofd = cmd == F_OFD_SETLK;
|
let is_ofd = cmd == F_OFD_SETLK;
|
||||||
let flock = unsafe { &mut *(args as *mut flock) };
|
let flock = unsafe { &mut *(args as *mut flock) };
|
||||||
|
|
||||||
@@ -471,8 +472,6 @@ impl Pal for Sys {
|
|||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
F_SETLKW => log::warn!("F_SETLKW: not yet implemented"),
|
|
||||||
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1484,7 +1483,15 @@ impl Pal for Sys {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let set_scheduler = || -> Result<()> { todo!() };
|
let set_scheduler = || -> Result<()> {
|
||||||
|
// SCHED_OTHER is the kernel default (no-op); RT policies need
|
||||||
|
// kernel support Redox lacks, so ENOSYS per POSIX.
|
||||||
|
match attr.policy {
|
||||||
|
SCHED_OTHER => Ok(()),
|
||||||
|
SCHED_FIFO | SCHED_RR => Err(Errno(ENOSYS)),
|
||||||
|
_ => Err(Errno(EINVAL)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// scheduling paramters must be set regardless of whether the flag POSIX_SPAWN_SETSCHEDPARAM is set
|
// scheduling paramters must be set regardless of whether the flag POSIX_SPAWN_SETSCHEDPARAM is set
|
||||||
if flags.contains(Flags::POSIX_SPAWN_SETSCHEDULER) {
|
if flags.contains(Flags::POSIX_SPAWN_SETSCHEDULER) {
|
||||||
@@ -1986,12 +1993,31 @@ impl Sys {
|
|||||||
assert!(len >= 0);
|
assert!(len >= 0);
|
||||||
Ok((start, len))
|
Ok((start, len))
|
||||||
}
|
}
|
||||||
// FIXME: andypython: SEEK_CUR, SEEK_END
|
c if c == i32::from(SEEK_CUR) || c == i32::from(SEEK_END) => {
|
||||||
|
let base = if c == i32::from(SEEK_CUR) {
|
||||||
|
syscall::lseek(fd, 0, SEEK_CUR as usize)? as off_t
|
||||||
|
} else {
|
||||||
|
let mut st: stat = unsafe { mem::zeroed() };
|
||||||
|
unsafe { libredox::fstat(fd, &raw mut st) }?;
|
||||||
|
st.st_size as off_t
|
||||||
|
};
|
||||||
|
|
||||||
|
let abs_start = base + start;
|
||||||
|
let (abs_start, abs_len) = if len < 0 {
|
||||||
|
(abs_start + len, -len)
|
||||||
|
} else {
|
||||||
|
(abs_start, len)
|
||||||
|
};
|
||||||
|
|
||||||
|
if abs_start < 0 {
|
||||||
|
return Err(Errno(EINVAL));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(abs_len >= 0);
|
||||||
|
Ok((abs_start, abs_len))
|
||||||
|
}
|
||||||
c => {
|
c => {
|
||||||
log::warn!(
|
return Err(Errno(EINVAL));
|
||||||
"Sys::relative_to_absolute_foffset: whence={whence} not yet implemented"
|
|
||||||
);
|
|
||||||
Ok((0, 0))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use crate::{
|
|||||||
error::Errno,
|
error::Errno,
|
||||||
fs::File,
|
fs::File,
|
||||||
header::{
|
header::{
|
||||||
errno::{self as errnoh, EIO},
|
errno::{self as errnoh, EIO, ENOSYS},
|
||||||
fcntl,
|
fcntl,
|
||||||
},
|
},
|
||||||
io,
|
io,
|
||||||
@@ -118,24 +118,22 @@ pub fn get_session(
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
unsafe fn inner_ptrace(
|
unsafe fn inner_ptrace(
|
||||||
request: c_int,
|
_request: c_int,
|
||||||
pid: pid_t,
|
_pid: pid_t,
|
||||||
addr: *mut c_void,
|
_addr: *mut c_void,
|
||||||
data: *mut c_void,
|
_data: *mut c_void,
|
||||||
) -> io::Result<c_int> {
|
) -> io::Result<c_int> {
|
||||||
//TODO: aarch64
|
Err(io::Error::from_raw_os_error(ENOSYS))
|
||||||
unimplemented!("inner_ptrace not implemented on aarch64");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86")]
|
#[cfg(target_arch = "x86")]
|
||||||
unsafe fn inner_ptrace(
|
unsafe fn inner_ptrace(
|
||||||
request: c_int,
|
_request: c_int,
|
||||||
pid: pid_t,
|
_pid: pid_t,
|
||||||
addr: *mut c_void,
|
_addr: *mut c_void,
|
||||||
data: *mut c_void,
|
_data: *mut c_void,
|
||||||
) -> io::Result<c_int> {
|
) -> io::Result<c_int> {
|
||||||
//TODO: x86
|
Err(io::Error::from_raw_os_error(ENOSYS))
|
||||||
unimplemented!("inner_ptrace not implemented on x86");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@@ -270,13 +268,12 @@ unsafe fn inner_ptrace(
|
|||||||
|
|
||||||
#[cfg(target_arch = "riscv64")]
|
#[cfg(target_arch = "riscv64")]
|
||||||
fn inner_ptrace(
|
fn inner_ptrace(
|
||||||
request: c_int,
|
_request: c_int,
|
||||||
pid: pid_t,
|
_pid: pid_t,
|
||||||
addr: *mut c_void,
|
_addr: *mut c_void,
|
||||||
data: *mut c_void,
|
_data: *mut c_void,
|
||||||
) -> io::Result<c_int> {
|
) -> io::Result<c_int> {
|
||||||
//TODO: riscv64
|
Err(io::Error::from_raw_os_error(ENOSYS))
|
||||||
unimplemented!("inner_ptrace not implemented on riscv64");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PalPtrace for Sys {
|
impl PalPtrace for Sys {
|
||||||
|
|||||||
@@ -8,13 +8,16 @@ use crate::{
|
|||||||
error::{Errno, Result},
|
error::{Errno, Result},
|
||||||
header::{
|
header::{
|
||||||
bits_sigset_t::sigset_t,
|
bits_sigset_t::sigset_t,
|
||||||
errno::{EINVAL, ENOSYS},
|
errno::{EINVAL},
|
||||||
signal::{
|
signal::{
|
||||||
SIG_BLOCK, SIG_DFL, SIG_IGN, SIG_SETMASK, SIG_UNBLOCK, SS_DISABLE, SS_ONSTACK,
|
SIGALRM, SIG_BLOCK, SIG_DFL, SIG_IGN, SIG_SETMASK, SIG_UNBLOCK, SS_DISABLE,
|
||||||
sigaction, siginfo_t, sigval, stack_t, ucontext_t,
|
SS_ONSTACK, SIGEV_SIGNAL, sigaction, sigevent, siginfo_t, sigval, stack_t,
|
||||||
|
ucontext_t,
|
||||||
},
|
},
|
||||||
time::timespec,
|
time::{CLOCK_REALTIME, itimerspec, timespec},
|
||||||
},
|
},
|
||||||
|
out::Out,
|
||||||
|
sync::Mutex,
|
||||||
};
|
};
|
||||||
use core::mem::offset_of;
|
use core::mem::offset_of;
|
||||||
use redox_protocols::protocol::ProcKillTarget;
|
use redox_protocols::protocol::ProcKillTarget;
|
||||||
@@ -22,6 +25,11 @@ use redox_rt::signal::{
|
|||||||
PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler,
|
PosixStackt, SigStack, Sigaction, SigactionFlags, SigactionKind, Sigaltstack, SignalHandler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ItimerTimer(timer_t);
|
||||||
|
unsafe impl Send for ItimerTimer {}
|
||||||
|
|
||||||
|
static ITIMER_REAL_TIMER: Mutex<Option<ItimerTimer>> = Mutex::new(None);
|
||||||
|
|
||||||
const _: () = {
|
const _: () = {
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
const fn assert_eq(a: usize, b: usize) {
|
const fn assert_eq(a: usize, b: usize) {
|
||||||
@@ -47,20 +55,21 @@ const _: () = {
|
|||||||
impl PalSignal for Sys {
|
impl PalSignal for Sys {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
fn getitimer(which: c_int, out: &mut itimerval) -> Result<()> {
|
fn getitimer(which: c_int, out: &mut itimerval) -> Result<()> {
|
||||||
let path = match which {
|
if which != ITIMER_REAL {
|
||||||
ITIMER_REAL => "/scheme/itimer/1",
|
return Err(Errno(EINVAL));
|
||||||
_ => return Err(Errno(EINVAL)),
|
}
|
||||||
};
|
|
||||||
// TODO: implement setitimer
|
|
||||||
// let fd = FdGuard::new(redox_rt::sys::open(path, syscall::O_RDONLY | syscall::O_CLOEXEC)?);
|
|
||||||
// let count = syscall::read(*fd, &mut spec)?;
|
|
||||||
|
|
||||||
let spec = syscall::ITimerSpec::default();
|
|
||||||
out.it_interval.tv_sec = spec.it_interval.tv_sec as time_t;
|
|
||||||
out.it_interval.tv_usec = spec.it_interval.tv_nsec / 1000;
|
|
||||||
out.it_value.tv_sec = spec.it_value.tv_sec as time_t;
|
|
||||||
out.it_value.tv_usec = spec.it_value.tv_nsec / 1000;
|
|
||||||
|
|
||||||
|
let guard = ITIMER_REAL_TIMER.lock();
|
||||||
|
if let Some(ref timer) = *guard {
|
||||||
|
let mut cur = itimerspec::default();
|
||||||
|
Sys::timer_gettime(timer.0, Out::from_mut(&mut cur))?;
|
||||||
|
out.it_interval.tv_sec = cur.it_interval.tv_sec as time_t;
|
||||||
|
out.it_interval.tv_usec = (cur.it_interval.tv_nsec / 1000) as suseconds_t;
|
||||||
|
out.it_value.tv_sec = cur.it_value.tv_sec as time_t;
|
||||||
|
out.it_value.tv_usec = (cur.it_value.tv_nsec / 1000) as suseconds_t;
|
||||||
|
} else {
|
||||||
|
*out = unsafe { core::mem::zeroed() };
|
||||||
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,12 +98,67 @@ impl PalSignal for Sys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
fn setitimer(which: c_int, _new: &itimerval, old: Option<&mut itimerval>) -> Result<()> {
|
fn setitimer(which: c_int, new: &itimerval, old: Option<&mut itimerval>) -> Result<()> {
|
||||||
// TODO: setitimer is no longer part of POSIX and should not be implemented in Redox
|
if which != ITIMER_REAL {
|
||||||
// Change the platform-independent implementation to use POSIX timers.
|
return Err(Errno(EINVAL));
|
||||||
// For Redox, the timer should probably use "/scheme/time"
|
}
|
||||||
todo_skip!(0, "setitimer not implemented");
|
|
||||||
Err(Errno(ENOSYS))
|
let mut guard = ITIMER_REAL_TIMER.lock();
|
||||||
|
|
||||||
|
if let Some(old_out) = old {
|
||||||
|
if let Some(ref timer) = *guard {
|
||||||
|
let mut cur = itimerspec::default();
|
||||||
|
if Sys::timer_gettime(timer.0, Out::from_mut(&mut cur)).is_ok() {
|
||||||
|
old_out.it_interval.tv_sec = cur.it_interval.tv_sec as time_t;
|
||||||
|
old_out.it_interval.tv_usec =
|
||||||
|
(cur.it_interval.tv_nsec / 1000) as suseconds_t;
|
||||||
|
old_out.it_value.tv_sec = cur.it_value.tv_sec as time_t;
|
||||||
|
old_out.it_value.tv_usec = (cur.it_value.tv_nsec / 1000) as suseconds_t;
|
||||||
|
} else {
|
||||||
|
*old_out = unsafe { core::mem::zeroed() };
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*old_out = unsafe { core::mem::zeroed() };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let disarm = new.it_value.tv_sec == 0 && new.it_value.tv_usec == 0;
|
||||||
|
|
||||||
|
if disarm {
|
||||||
|
if let Some(ref timer) = *guard {
|
||||||
|
let zero = itimerspec::default();
|
||||||
|
let _ = Sys::timer_settime(timer.0, 0, &zero, None);
|
||||||
|
}
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if guard.is_none() {
|
||||||
|
let mut evp: sigevent = unsafe { core::mem::zeroed() };
|
||||||
|
evp.sigev_notify = SIGEV_SIGNAL;
|
||||||
|
evp.sigev_signo = SIGALRM as c_int;
|
||||||
|
let mut timer_id: timer_t = core::ptr::null_mut();
|
||||||
|
Sys::timer_create(CLOCK_REALTIME, &evp, Out::from_mut(&mut timer_id))?;
|
||||||
|
*guard = Some(ItimerTimer(timer_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
let timer_id = guard
|
||||||
|
.as_ref()
|
||||||
|
.expect("itimer must exist after lazy init")
|
||||||
|
.0;
|
||||||
|
|
||||||
|
let spec = itimerspec {
|
||||||
|
it_value: timespec {
|
||||||
|
tv_sec: new.it_value.tv_sec,
|
||||||
|
tv_nsec: new.it_value.tv_usec as i64 * 1000,
|
||||||
|
},
|
||||||
|
it_interval: timespec {
|
||||||
|
tv_sec: new.it_interval.tv_sec,
|
||||||
|
tv_nsec: new.it_interval.tv_usec as i64 * 1000,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
Sys::timer_settime(timer_id, 0, &spec, None)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sigaction(
|
fn sigaction(
|
||||||
|
|||||||
Reference in New Issue
Block a user