summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-02-24 16:00:53 -0800
committerThiago Macieira <thiago.macieira@intel.com>2022-03-08 09:18:40 -0800
commitc4d78703e0052c9ffa9c9fd27cc5365b53811a32 (patch)
tree1a28a662484f4a26bec335d30164d331441b438a
parent15ac809c9924b0bc7fd63d87fd68eac3d11f7364 (diff)
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 <oswald.buddenhagen@gmx.de> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/3rdparty/forkfd/forkfd_linux.c5
1 files 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;
}