summaryrefslogtreecommitdiff
path: root/include/uapi
diff options
context:
space:
mode:
authorNickolai Zeldovich <nickolai@csail.mit.edu>2026-10-17 22:58:24 -0400
committerJens Axboe <axboe@kernel.dk>2026-10-19 15:01:45 -0600
commitc82621eb2c9a00b514a459951609e04843d467bb (patch)
tree843bb0d76d263e2c478880491dbd58166d32837e /include/uapi
parent96262cfab554cf11412de7a6247f0e82c94e130f (diff)
io_uring/waitid: return -EAGAIN for a non-blocking pidfd
IORING_OP_WAITID on a pidfd opened with PIDFD_NONBLOCK completes at once with res 0 and an all-zero siginfo when the child has not changed state, although WNOHANG was not requested. waitid(2) with the same arguments fails with -EAGAIN. An application that submits the same request it would pass to waitid(2) and treats res 0 as "the child changed state" sees si_signo 0 and si_pid 0 instead. kernel_waitid_prepare() turns an O_NONBLOCK pidfd into WNOHANG in wo->wo_flags. kernel_waitid() then maps the resulting 0 return to -EAGAIN when the caller did not ask for WNOHANG itself, as added in commit ba7d25f3dff6 ("exit: support non-blocking pidfds"). io_waitid() uses kernel_waitid_prepare() and __do_wait() directly and does not do that mapping. Do the same check in io_waitid() before completing the request. Only the inline path needs it: with WNOHANG set, __do_wait() never returns -ERESTARTSYS, so such a request is never armed on the wait queue. Reproduced on x86_64 under QEMU: with a PIDFD_NONBLOCK pidfd of a running child and options = WEXITED, waitid(2) fails with -EAGAIN and IORING_OP_WAITID completed with res 0 before the change; it completes with res -EAGAIN after it. Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support") Assisted-by: LLM Signed-off-by: Nickolai Zeldovich <nickolai@csail.mit.edu> Link: https://patch.msgid.link/20261018025824.799245-1-nickolai@csail.mit.edu Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'include/uapi')
0 files changed, 0 insertions, 0 deletions