summaryrefslogtreecommitdiffstats
path: root/src/3rdparty
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2022-02-24 16:00:53 -0800
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-04-05 19:58:00 +0000
commit0c1bf8b13e9fc27effd49c3aa001845cd5ef6707 (patch)
tree7d28ee5f818c2f1574356ec76cb713283e10db36 /src/3rdparty
parent6a2f613bb76c8a4e6b4cbf9908116cc22f8123ef (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 Change-Id: Ibf4acec0f166495998f7fffd16d6de6853a6e5a8 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit c4d78703e0052c9ffa9c9fd27cc5365b53811a32) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/3rdparty')
-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;
}