diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 59b6db7c792076390564a79074342a0fc653c7a7..3de1345585e436003796a6e0dce38abeef11e1a9 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -1006,6 +1006,7 @@ bool QProcessPrivate::_q_processDied() return false; #endif #ifdef Q_OS_WIN + drainOutputPipes(); if (processFinishedNotifier) processFinishedNotifier->setEnabled(false); #endif diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index f658e54d4b2150be35681f8aeb6f7b03b29dfee0..bd6943c8d0561f02e5d31cbc208d1ae0f868086f 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -317,6 +317,7 @@ public: bool waitForDeadChild(); #endif #ifdef Q_OS_WIN + bool drainOutputPipes(); void flushPipeWriter(); qint64 pipeWriterBytesToWrite() const; #endif diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 0f36c3adbf6c14472ab02039f40284622ab570f0..77768522773c1f093adc3df7e586f96e731a1892 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -625,21 +625,21 @@ bool QProcessPrivate::waitForStarted(int) return false; } -static bool drainOutputPipes(QProcessPrivate *d) +bool QProcessPrivate::drainOutputPipes() { - if (!d->stdoutReader && !d->stderrReader) + if (!stdoutReader && !stderrReader) return false; bool readyReadEmitted = false; forever { bool readOperationActive = false; - if (d->stdoutReader) { - readyReadEmitted |= d->stdoutReader->waitForReadyRead(0); - readOperationActive = d->stdoutReader->isReadOperationActive(); + if (stdoutReader) { + readyReadEmitted |= stdoutReader->waitForReadyRead(0); + readOperationActive = stdoutReader->isReadOperationActive(); } - if (d->stderrReader) { - readyReadEmitted |= d->stderrReader->waitForReadyRead(0); - readOperationActive |= d->stderrReader->isReadOperationActive(); + if (stderrReader) { + readyReadEmitted |= stderrReader->waitForReadyRead(0); + readOperationActive |= stderrReader->isReadOperationActive(); } if (!readOperationActive) break; @@ -669,7 +669,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs) if (!pid) return false; if (WaitForSingleObject(pid->hProcess, 0) == WAIT_OBJECT_0) { - bool readyReadEmitted = drainOutputPipes(this); + bool readyReadEmitted = drainOutputPipes(); _q_processDied(); return readyReadEmitted; } @@ -772,12 +772,12 @@ bool QProcessPrivate::waitForFinished(int msecs) timer.resetIncrements(); if (!pid) { - drainOutputPipes(this); + drainOutputPipes(); return true; } if (WaitForSingleObject(pid->hProcess, timer.nextSleepTime()) == WAIT_OBJECT_0) { - drainOutputPipes(this); + drainOutputPipes(); _q_processDied(); return true; } diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index f01e3198727ef34a618e67e8681a9764bc8fc782..613bfd5c176288e3e8644ce5b7119c5295e91c4a 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -152,6 +152,7 @@ private slots: void invalidProgramString_data(); void invalidProgramString(); void onlyOneStartedSignal(); + void finishProcessBeforeReadingDone(); // keep these at the end, since they use lots of processes and sometimes // caused obscure failures to occur in tests that followed them (esp. on the Mac) @@ -2168,6 +2169,39 @@ void tst_QProcess::onlyOneStartedSignal() QCOMPARE(spyFinished.count(), 1); } +//----------------------------------------------------------------------------- + +class BlockOnReadStdOut : public QObject +{ + Q_OBJECT +public: + BlockOnReadStdOut(QProcess *process) + { + connect(process, SIGNAL(readyReadStandardOutput()), SLOT(block())); + } + +public slots: + void block() + { + QThread::sleep(1); + } +}; + +void tst_QProcess::finishProcessBeforeReadingDone() +{ + QProcess process; + BlockOnReadStdOut blocker(&process); + QEventLoop loop; + connect(&process, SIGNAL(finished(int)), &loop, SLOT(quit())); + process.start("testProcessOutput/testProcessOutput"); + QVERIFY(process.waitForStarted()); + loop.exec(); + QStringList lines = QString::fromLocal8Bit(process.readAllStandardOutput()).split( + QRegExp(QStringLiteral("[\r\n]")), QString::SkipEmptyParts); + QVERIFY(!lines.isEmpty()); + QCOMPARE(lines.last(), QStringLiteral("10239 -this is a number")); +} + #endif //QT_NO_PROCESS QTEST_MAIN(tst_QProcess)