Sync the relibc fork with 50 upstream commits (socket layer rework,
exec/signal/ptrace/path/timer updates, pthread cleanup, ld_so lifecycle
work bringing mark_ready/run_fini into the tree, dynamically-linked
init support, start.rs allocator-model rewrite, test harness updates).
Satisfies the verify-fork-functions gate (2 previously-missing ld_so
functions now present).
Conflicts resolved (4 files; 46 auto-merged):
- src/start.rs: took upstream's version wholesale. Upstream moved
allocator/linker initialization into ld_so's new lifecycle (the
mark_ready/run_fini work this merge brings in), superseding the RB
alloc_init cluster; the old model's function was already merged out
and its lone call would not compile.
- redox-rt/src/sys.rs: kept the RB refresh flow with the non-fatal
lseek fallback (upstream adopted the refresh as a fatal '?' —
RB's conservative fallback protects spawn for uid-dropped /
namespace-restricted exec where the kernel cannot refresh).
- src/platform/redox/exec.rs: kept the RB root exec-permission bypass
(ruid/euid != 0 gate, Linux-matching behavior).
- Cargo.lock: syn 2.0.118 -> 2.0.119 (upstream).
Verified: repo cook relibc --force-rebuild successful;
verify-fork-functions.sh --no-fetch relibc passes;
all 9 forks now pass the gate.
The dup2('refresh') added for O_CLOEXEC/stale-fd correctness fails for some
exec'd children (observed: a uid-dropped, namespace-restricted login shell)
and propagated as a spawn ENOENT. Fall back to the plain lseek when the
refresh syscall errors so process startup always succeeds; the refresh
still applies wherever the kernel permits it. Prevents any spawn
regression while the refresh path is stabilized for restricted children.
Backport of upstream relibc 580eab8b ('Refresh filetable data before
filetable creation'). FdTbl::from_binary_fd reconstructs an exec'd
process's fd table from the inherited filetable fd. A plain lseek(0) did
not force the backing scheme to re-materialize the current descriptor
set, so an exec'd child (e.g. a login shell) could read a STALE snapshot
and end up with a desynchronized fd -- observed as an interactive shell
whose pty-slave stdin (fd 0) returns nothing while writes to fd 1/2 work.
Issue a SYS_DUP2 'refresh' on the filetable fd before reading it.
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.
* Storing a pointer to the allocator in TCB is no longer necessary.
* `AtomicPtr` to store the allocator is no longer required as the
allocator is not swapped on init if the program was dynamically
linked.
Signed-off-by: Anhad Singh <andypython@protonmail.com>
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.