diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2020-02-17 11:56:46 -0800 |
---|---|---|
committer | Edward Welbourne <eddy@chaos.org.uk> | 2020-03-25 20:19:41 +0100 |
commit | 028ddf3633f394c930ddb82551ef2d1fa9b1a04a (patch) | |
tree | 54ac736f589b357e0b762a2515a496a517eeb7c7 /src | |
parent | defd49f7bfa07395a2f2a69e2f9db94b8ac5d64c (diff) |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 2186f23ab6..930007ff04 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -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; |