QProcess/Linux: use the FFD_VFORK_SEMANTICS flag

... when we are not using the FFD_USE_FORK flag. We use the FFD_USE_FORK
flag when we have user code to run in setupChildProcess(). This code is
enabled for all Unix, but forkfd() honors this flag only on Linux >=
5.4.

See the commit adding the flag for more information on what the flag
does and see the comment in this commit on why it's safe to use it.

Fixes: QTBUG-17331
Change-Id: I1bee3bc466a04f19bd6efffd15f448cb23ce1e91
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
This commit is contained in:
Thiago Macieira 2020-02-17 11:56:46 -08:00 committed by Edward Welbourne
parent defd49f7bf
commit 028ddf3633

View File

@ -450,12 +450,19 @@ void QProcessPrivate::startProcess()
workingDirPtr = encodedWorkingDirectory.constData();
}
// Start the process manager, and fork off the child process.
// ### Qt6: revisit whether the change in behavior due to not using fork()
// is acceptable for derived classes.
// Select FFD_USE_FORK and FFD_VFORK_SEMANTICS based on whether there's
// user code running in the child process: if there is, we don't know what
// the user will want to do, so we err on the safe side and request an
// actual fork() (for example, the user could attempt to do some
// synchronization with the parent process). But if there isn't, then our
// code in execChild() is just a handful of dup2() and a chdir(), so it's
// safe with vfork semantics: suspend the parent execution until the child
// either execve()s or _exit()s.
int ffdflags = FFD_CLOEXEC;
if (typeid(*q) != typeid(QProcess))
ffdflags |= FFD_USE_FORK;
else
ffdflags |= FFD_VFORK_SEMANTICS;
pid_t childPid;
forkfd = ::forkfd(ffdflags , &childPid);
int lastForkErrno = errno;