From c4d78703e0052c9ffa9c9fd27cc5365b53811a32 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 24 Feb 2022 16:00:53 -0800 Subject: [PATCH] forkfd: don't attempt to guess EWOULDBLOCK when WNOHANG is active Reading the kernel sources, I was sure we'd get an ECHILD if the child hadn't exited yet, but that's not the case. We only get ECHILD if the current process has no child processes. But if we do have one and the one we're waiting for hasn't exited, waitid() returns 0. So let's not attempt to correct it with forkfd_wait() or forkfd_wait4(). Those have "wait" in the name, so they should behave exactly the same way. The man pages say: waitpid(): if WNOHANG was specified and one or more child(ren) specified by pid exist, but have not yet changed state, then 0 is returned. waitid(): returns 0 on success or if WNOHANG was specified and no child(ren) specified by id has yet changed state This was found while studying QTBUG-100174. QProcess does not use this code path (blocking mode forkfd only). Matching OpenDCDiag PR: https://github.com/opendcdiag/opendcdiag/pull/62 Pick-to: 6.2 6.3 Change-Id: Ibf4acec0f166495998f7fffd16d6de6853a6e5a8 Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd_linux.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd_linux.c b/src/3rdparty/forkfd/forkfd_linux.c index c86e138b63..4b3be7036b 100644 --- a/src/3rdparty/forkfd/forkfd_linux.c +++ b/src/3rdparty/forkfd/forkfd_linux.c @@ -184,10 +184,9 @@ int system_forkfd_wait(int ffd, struct forkfd_info *info, int ffdoptions, struct options |= WNOHANG; } + si.si_status = si.si_code = 0; ret = sys_waitid(P_PIDFD, ffd, &si, options, rusage); - if (ret == -1 && errno == ECHILD) { - errno = EWOULDBLOCK; - } else if (ret == 0 && info) { + if (info) { info->code = si.si_code; info->status = si.si_status; }