From 2588a5b24965d9afa0d6e368a9f42491d1cfb5f7 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 5 Jan 2012 18:24:53 +0100 Subject: QProcess/Win: direct forwarding of stdout and stderr We are now directly passing the standard out/err handles to CreateProcess instead of reading the output and writing it. The downside is, that we cannot automatically forward the process output of GUI applications anymore. This behaviour is intended by the CreateProcess API. Change-Id: Ic6e35c8c338dbea1a9f345567a37d938da1f34a2 Reviewed-by: Oswald Buddenhagen Reviewed-by: Joerg Bornemann --- src/corelib/io/qprocess_win.cpp | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'src/corelib/io/qprocess_win.cpp') diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index fd5f078ff0..8c6444d173 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -92,6 +92,15 @@ static void qt_create_pipe(Q_PIPE *pipe, bool in) CloseHandle(tmpHandle); } +static void duplicateStdWriteChannel(Q_PIPE *pipe, DWORD nStdHandle) +{ + pipe[0] = INVALID_Q_PIPE; + HANDLE hStdWriteChannel = GetStdHandle(nStdHandle); + HANDLE hCurrentProcess = GetCurrentProcess(); + DuplicateHandle(hCurrentProcess, hStdWriteChannel, hCurrentProcess, + &pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS); +} + /* Create the pipes to a QProcessPrivate::Channel. @@ -108,8 +117,11 @@ bool QProcessPrivate::createChannel(Channel &channel) if (channel.type == Channel::Normal) { // we're piping this channel to our own process - qt_create_pipe(channel.pipe, &channel == &stdinChannel); - + const bool isStdInChannel = (&channel == &stdinChannel); + if (isStdInChannel || processChannelMode != QProcess::ForwardedChannels) + qt_create_pipe(channel.pipe, isStdInChannel); + else + duplicateStdWriteChannel(channel.pipe, (&channel == &stdoutChannel) ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE); return true; } else if (channel.type == Channel::Redirect) { // we're redirecting the channel to/from a file @@ -465,18 +477,6 @@ qint64 QProcessPrivate::bytesAvailableFromStdout() const #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail); #endif - if (processChannelMode == QProcess::ForwardedChannels && bytesAvail > 0) { - QByteArray buf(bytesAvail, 0); - DWORD bytesRead = 0; - if (ReadFile(stdoutChannel.pipe[0], buf.data(), buf.size(), &bytesRead, 0) && bytesRead > 0) { - HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); - if (hStdout) { - DWORD bytesWritten = 0; - WriteFile(hStdout, buf.data(), bytesRead, &bytesWritten, 0); - } - } - bytesAvail = 0; - } return bytesAvail; } @@ -490,18 +490,6 @@ qint64 QProcessPrivate::bytesAvailableFromStderr() const #if defined QPROCESS_DEBUG qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail); #endif - if (processChannelMode == QProcess::ForwardedChannels && bytesAvail > 0) { - QByteArray buf(bytesAvail, 0); - DWORD bytesRead = 0; - if (ReadFile(stderrChannel.pipe[0], buf.data(), buf.size(), &bytesRead, 0) && bytesRead > 0) { - HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE); - if (hStderr) { - DWORD bytesWritten = 0; - WriteFile(hStderr, buf.data(), bytesRead, &bytesWritten, 0); - } - } - bytesAvail = 0; - } return bytesAvail; } -- cgit v1.2.3