fix assertion in QProcess/Win
authorJoerg Bornemann <joerg.bornemann@theqtcompany.com>
Tue, 28 Jul 2015 11:43:54 +0000 (13:43 +0200)
committerJoerg Bornemann <joerg.bornemann@theqtcompany.com>
Mon, 17 Aug 2015 08:25:19 +0000 (08:25 +0000)
Do not call bytesAvailableInChannel if the source pipe end is
invalid. This is the case when redirecting channels on Windows.
The assertions in bytesAvailableInChannel were triggered whenever
an output process or output file was set and waitForBytesWritten
was called.

Task-number: QTBUG-45548
Change-Id: I225dfea2c5e27e122f75008a3a06d425554e00fe
Reviewed-by: Alex Trotsenko <alex1973tr@gmail.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@theqtcompany.com>
src/corelib/io/qprocess_win.cpp
tests/auto/corelib/io/qprocess/tst_qprocess.cpp

index cef961ecbde26b4aa3e0e6d032de5e9ae83a0986..eb88ded2c9788c38ac40727b82ea8fa85d33d9b2 100644 (file)
@@ -704,13 +704,15 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
             return true;
 
         // If we wouldn't write anything, check if we can read stdout.
-        if (bytesAvailableInChannel(&stdoutChannel) != 0) {
+        if (stdoutChannel.pipe[0] != INVALID_Q_PIPE
+                && bytesAvailableInChannel(&stdoutChannel) != 0) {
             tryReadFromChannel(&stdoutChannel);
             timer.resetIncrements();
         }
 
         // Check if we can read stderr.
-        if (bytesAvailableInChannel(&stderrChannel) != 0) {
+        if (stderrChannel.pipe[0] != INVALID_Q_PIPE
+                && bytesAvailableInChannel(&stderrChannel) != 0) {
             tryReadFromChannel(&stderrChannel);
             timer.resetIncrements();
         }
index 7064b45d07be5c2bfea7db2b819198ea5ebe3f0a..11bdaec9c454be2ea210c30da57ec7a57c825356 100644 (file)
@@ -118,6 +118,7 @@ private slots:
     void setStandardOutputFile_data();
     void setStandardOutputFile();
     void setStandardOutputFile2();
+    void setStandardOutputFileAndWaitForBytesWritten();
     void setStandardOutputProcess_data();
     void setStandardOutputProcess();
     void removeFileWhileProcessIsRunning();
@@ -2068,6 +2069,26 @@ void tst_QProcess::setStandardOutputFile()
 
     QCOMPARE(all.size(), expectedsize);
 }
+
+void tst_QProcess::setStandardOutputFileAndWaitForBytesWritten()
+{
+    static const char testdata[] = "Test data.";
+
+    QFile file("data");
+    QProcess process;
+    process.setStandardOutputFile(file.fileName());
+    process.start("testProcessEcho2/testProcessEcho2");
+    process.write(testdata, sizeof testdata);
+    process.waitForBytesWritten();
+    QPROCESS_VERIFY(process, waitForFinished());
+
+    // open the file again and verify the data
+    QVERIFY(file.open(QIODevice::ReadOnly));
+    QByteArray all = file.readAll();
+    file.close();
+
+    QCOMPARE(all, QByteArray::fromRawData(testdata, sizeof testdata - 1));
+}
 #endif
 
 //-----------------------------------------------------------------------------
@@ -2076,17 +2097,19 @@ void tst_QProcess::setStandardOutputFile()
 void tst_QProcess::setStandardOutputProcess_data()
 {
     QTest::addColumn<bool>("merged");
-    QTest::newRow("separate") << false;
-    QTest::newRow("merged") << true;
+    QTest::addColumn<bool>("waitForBytesWritten");
+    QTest::newRow("separate") << false << false;
+    QTest::newRow("separate with waitForBytesWritten") << false << true;
+    QTest::newRow("merged") << true << false;
 }
 
 void tst_QProcess::setStandardOutputProcess()
 {
-
     QProcess source;
     QProcess sink;
 
     QFETCH(bool, merged);
+    QFETCH(bool, waitForBytesWritten);
     source.setReadChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
     source.setStandardOutputProcess(&sink);
 
@@ -2095,6 +2118,8 @@ void tst_QProcess::setStandardOutputProcess()
 
     QByteArray data("Hello, World");
     source.write(data);
+    if (waitForBytesWritten)
+        source.waitForBytesWritten();
     source.closeWriteChannel();
     QPROCESS_VERIFY(source, waitForFinished());
     QPROCESS_VERIFY(sink, waitForFinished());