From b2216bbe06b8be2bef6d8bc2ffff1337f6d23358 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 6 Mar 2014 14:21:53 +0100 Subject: [PATCH] do not use fileno calls in forked child This fixes an issue that causes QProcess::start to silently fail on OS X 10.9. Apparently, fileno(stdout) locks the handle on OS X 10.9. It may happen that the parent process fflush()s stdout while the child has just been forked. The stdout lock of the parent is never released in the child and fileno(stdout) therefore locks forever. According to the fork documentation on opengroup.org one may only call async-signal-safe functions between fork and exec in the child. The fileno() function does not appear in the list of async-signal-safe functions. Also, fileno(stdout) and friends can be easily replaced by the standard constants STDOUT_FILENO etc. Done-with: Fawzi Mohamed Task-number: QTBUG-37306 Change-Id: I2b1f5f47cc48a1ad020fb0493a955d2bc27aeb47 Reviewed-by: Thiago Macieira --- src/corelib/io/qprocess_unix.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 4076ec58558..0e917ef4385 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -880,18 +880,18 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv // copy the stdin socket if asked to (without closing on exec) if (inputChannelMode != QProcess::ForwardedInputChannel) - qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0); + qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0); // copy the stdout and stderr if asked to if (processChannelMode != QProcess::ForwardedChannels) { if (processChannelMode != QProcess::ForwardedOutputChannel) - qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0); + qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0); // merge stdout and stderr if asked to if (processChannelMode == QProcess::MergedChannels) { - qt_safe_dup2(fileno(stdout), fileno(stderr), 0); + qt_safe_dup2(STDOUT_FILENO, STDERR_FILENO, 0); } else if (processChannelMode != QProcess::ForwardedErrorChannel) { - qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0); + qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0); } }