The sys_timerfd module (timerfd_create/settime/gettime) existed on disk but was
never declared in header/mod.rs, so its code was NOT compiled and the symbols
were absent from libc — timerfd was entirely non-functional. The generated
header still declared the functions, so C programs compiled but failed to LINK
with 'undefined reference to timerfd_create/timerfd_settime' (e.g. libwayland's
event-loop.c, blocking the whole Wayland stack). Declare the module so the
implementation is built and the symbols exported.
cbindgen auto-generated the timerfd_* prototypes from the Rust signatures,
emitting a bare 'itimerspec' (not 'struct itimerspec') and a 'clockid_t'
parameter with no <time.h> in scope, so any C program that #includes
<sys/timerfd.h> failed to compile. That made meson's TFD_CLOEXEC feature probe
report NO and aborted the whole Wayland stack (libwayland) and glib. Exclude the
auto-generated prototypes (the hand-written, correct ones are emitted from the
trailer) and add <time.h> to the sys_includes.
fcntl(F_DUPFD_CLOEXEC) reached redox_rt/kernel with the POSIX/C value 1030
instead of the Redox syscall value (syscall::F_DUPFD_CLOEXEC=5). redox_rt did
not recognize it as a dup, forwarded the raw command to the kernel, and the
kernel's fcntl fell through to its EINVAL catch-all. That made
OwnedFd::try_clone() return EINVAL, which broke tokio Runtime::build() (its I/O
reactor try_clones the epoll fd) for every tokio user on Redox: all the zbus
system daemons (sessiond/polkit/udisks/upower) and the login shell. F_DUPFD and
plain dup worked because they share the same value in both namespaces;
F_DUPFD_CLOEXEC was the sole untranslated command.
Also drop the ineffective epoll_ctl EINVAL/EBADF retry loop: it was based on a
disproven 'transient scheme churn' theory; epoll registrations always succeed
immediately. The real dup failure is fixed above.
Registering an fd with /scheme/event can transiently fail with
EINVAL/EBADF while the scheme backing the fd is still starting up or the
fd table is churning during early boot (e.g. a tokio/mio reactor built by
a daemon that races ahead of ipcd's uds_stream scheme). Without recovery,
tokio's Runtime::build aborts the whole runtime with "Invalid argument
(os error 22)", killing every zbus daemon (sessiond, polkit, udisks,
upower) and any tokio program including the login shell.
Retry the /scheme/event registration write with a 5ms backoff, up to ~2s,
on EINVAL/EBADF; a genuinely permanent failure still surfaces after the
bounded window. Redox-only. This is the registration-site counterpart to
the existing park-path recovery in the P0-epoll-redox-recovery tokio patch.
Adapted from the archived local P3-waitid.patch. Fills a POSIX gap needed by
job-control-capable shells (brush/nix). waitid() maps (idtype,id)->waitpid pid,
translates WEXITED/WSTOPPED/WCONTINUED/WNOWAIT options, and populates siginfo_t
(si_pid/si_signo/si_code/si_status) from the wait status.
The copied child table did not reliably retain the thread and process descriptors at the numbers exported through auxv. Explicitly clone both descriptors into the selected child table before loading the image, and remove the ineffective parent-handle leak.
posix_spawn creates a new context and returns its thread fd to the
parent. The kernel currently does not keep a self-reference to the child
context's thread fd, so when the parent closes its handle, the child's
thread object may be destroyed before the dynamic linker reads
AT_REDOX_THR_FD from auxv and opens regs/env. Leak the parent handle
until the kernel is fixed to retain a reference per context.
The kernel proc scheme returns EBADF for writes to Filetable/NewFiletable
handles, so the bulk FileTableVerb::Close call was silently failing. Close
each O_CLOEXEC fd with SYS_CLOSE instead, which updates both the kernel file
table and the userspace FILETABLE. This unblocks Command::spawn() parents
waiting on the CLOEXEC sync pipe.
The two-step pattern (open full path as scheme root, then open reference
relative to root_fd) failed for namespace-internal paths like
/scheme/namespace/scheme-creation-cap. The namespace scheme resolves the
full path and returns OtherScheme pointing to SchemeList (a kernel scheme
that does not implement kopenat). The second call then hits
SchemeList.kopenat() → EOPNOTSUPP.
The namespace scheme already handles reference resolution internally via
open_scheme_resource(), so a single SYS_OPENAT call with the full path
resolves everything. This also bypasses FILETABLE.insert_upper (which
previously collided with the untracked ns_fd at UPPER index 0).
The open() function used openat_into_upper which calls
FILETABLE.insert_upper() to allocate UPPER fd slots. This can collide
with the namespace fd (ns_fd) that is stored in DYNAMIC_PROC_INFO,
causing the kernel to overwrite the namespace fd entry. All subsequent
open() calls then resolve to the wrong scheme.
Fix: use raw SYS_OPENAT syscalls (which auto-assign POSIX fds) and
register them with register_external_fd, bypassing insert_upper entirely.
The previous pipe2 implementation used redox_rt::sys::open() which goes
through the FILETABLE's insert_upper mechanism. This can collide with
the untracked namespace fd (ns_fd) stored in DYNAMIC_PROC_INFO, causing
the kernel to overwrite the namespace fd entry with a pipe scheme root
entry. Subsequent open() calls then resolve to the wrong scheme, and
kdup fails with EBADF because it receives a write-end (odd) ID instead
of a read-end (even) ID.
Fix: bypass the open() function entirely and use raw syscall::openat +
syscall::dup, then register both fds with register_external_fd so the
FILETABLE tracks them correctly.
bits/eventfd.h defines the eventfd_t 64-bit counter type used by
sys/eventfd.h. Without this config, cbindgen skipped the directory
and the type wasn't generated.
sys_timerfd was fully implemented in Rust (timerfd_create,
timerfd_settime, timerfd_gettime, itimerspec support) but lacked
the cbindgen.toml needed to generate the <sys/timerfd.h> C header.
Qt6's QSocketNotifier and many other C programs depend on this header.
Without it, cbindgen skips the directory entirely.
This adds the cbindgen config + trailer with all function prototypes,
matching the pattern used by sys_signalfd.
validate_kfmap_flags in kernel proc scheme requires exactly one of
MAP_SHARED or MAP_PRIVATE. Without it, shared == private == false,
and the check fails with EINVAL. This was the root cause of the
fexec_impl crash at step 62 (first PT_LOAD segment mapping).
redox-scheme Socket and RawEventQueue create fds via libredox raw
syscalls (SYS_DUP, openat) that bypass the redox-rt userspace
FILETABLE. When FdGuard::dup later reserves a POSIX fd slot via
FILETABLE.add_posix, it can reserve a position occupied by the
untracked socket fd. SYS_DUP_INTO then closes the socket and
replaces it, corrupting the procmgr's fd table.
Add register_external_fd() to redox-rt::sys that marks an
existing kernel fd as occupied in the userspace FILETABLE.
Call it from procmgr::run() for the socket fd and event queue
fd.
Removes all syscall::write(1, b'FK:...') debug trace lines from
fork_impl/fork_inner in redox-rt/src/proc.rs that were polluting
serial output during every fork() call.
Generated signal.h uses uint32_t, int32_t, uint64_t, uintptr_t etc.
without including stdint.h, causing compilation failures in C packages
that include signal.h (diffutils, etc).
Creates sys_eventfd header module providing eventfd(), eventfd_read(),
and eventfd_write(). Uses the kernel event scheme (/scheme/event) on
Redox, returning ENOSYS on Linux. Required for packages like Python
that link against eventfd.
Upstream precedence: upstream provides eventfd, signalfd, timerfd, POSIX
stubs, cbindgen fixes, Rust 2024 edition, fenv, scheduler, and many more
that RB had previously patched. All RB patches for already-upstreamed
functionality have been dropped per the golden rule.
RB additions on top of upstream:
- Version suffix +rb0.3.1
- Path deps for redox_syscall and libredox (local fork policy)
- [patch.crates-io] for local fork resolution
- Author attribution