summaryrefslogtreecommitdiffstats
path: root/tests/auto/qprocess
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/qprocess')
-rw-r--r--tests/auto/qprocess/.gitignore22
-rw-r--r--tests/auto/qprocess/fileWriterProcess/fileWriterProcess.pro10
-rw-r--r--tests/auto/qprocess/fileWriterProcess/main.cpp59
-rw-r--r--tests/auto/qprocess/qprocess.pro27
-rw-r--r--tests/auto/qprocess/test/test.pro49
-rwxr-xr-xtests/auto/qprocess/testBatFiles/simple.bat2
-rwxr-xr-xtests/auto/qprocess/testBatFiles/with space.bat2
-rw-r--r--tests/auto/qprocess/testDetached/main.cpp84
-rw-r--r--tests/auto/qprocess/testDetached/testDetached.pro7
-rw-r--r--tests/auto/qprocess/testExitCodes/main.cpp48
-rw-r--r--tests/auto/qprocess/testExitCodes/testExitCodes.pro5
-rw-r--r--tests/auto/qprocess/testGuiProcess/main.cpp57
-rw-r--r--tests/auto/qprocess/testGuiProcess/testGuiProcess.pro4
-rw-r--r--tests/auto/qprocess/testProcessCrash/main.cpp53
-rw-r--r--tests/auto/qprocess/testProcessCrash/testProcessCrash.pro8
-rw-r--r--tests/auto/qprocess/testProcessDeadWhileReading/main.cpp52
-rw-r--r--tests/auto/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro10
-rw-r--r--tests/auto/qprocess/testProcessEOF/main.cpp58
-rw-r--r--tests/auto/qprocess/testProcessEOF/testProcessEOF.pro9
-rw-r--r--tests/auto/qprocess/testProcessEcho/main.cpp59
-rw-r--r--tests/auto/qprocess/testProcessEcho/testProcessEcho.pro8
-rw-r--r--tests/auto/qprocess/testProcessEcho2/main.cpp58
-rw-r--r--tests/auto/qprocess/testProcessEcho2/testProcessEcho2.pro10
-rw-r--r--tests/auto/qprocess/testProcessEcho3/main.cpp61
-rw-r--r--tests/auto/qprocess/testProcessEcho3/testProcessEcho3.pro9
-rw-r--r--tests/auto/qprocess/testProcessEchoGui/main_win.cpp67
-rw-r--r--tests/auto/qprocess/testProcessEchoGui/testProcessEchoGui.pro13
-rw-r--r--tests/auto/qprocess/testProcessLoopback/main.cpp57
-rw-r--r--tests/auto/qprocess/testProcessLoopback/testProcessLoopback.pro8
-rw-r--r--tests/auto/qprocess/testProcessNormal/main.cpp46
-rw-r--r--tests/auto/qprocess/testProcessNormal/testProcessNormal.pro9
-rw-r--r--tests/auto/qprocess/testProcessOutput/main.cpp56
-rw-r--r--tests/auto/qprocess/testProcessOutput/testProcessOutput.pro9
-rw-r--r--tests/auto/qprocess/testProcessSpacesArgs/main.cpp54
-rw-r--r--tests/auto/qprocess/testProcessSpacesArgs/nospace.pro9
-rw-r--r--tests/auto/qprocess/testProcessSpacesArgs/onespace.pro11
-rw-r--r--tests/auto/qprocess/testProcessSpacesArgs/twospaces.pro12
-rw-r--r--tests/auto/qprocess/testSetWorkingDirectory/main.cpp51
-rw-r--r--tests/auto/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro7
-rw-r--r--tests/auto/qprocess/testSoftExit/main_unix.cpp62
-rw-r--r--tests/auto/qprocess/testSoftExit/main_win.cpp58
-rw-r--r--tests/auto/qprocess/testSoftExit/testSoftExit.pro16
-rw-r--r--tests/auto/qprocess/testSpaceInName/main.cpp56
-rw-r--r--tests/auto/qprocess/testSpaceInName/testSpaceInName.pro13
-rw-r--r--tests/auto/qprocess/tst_qprocess.cpp2004
45 files changed, 3389 insertions, 0 deletions
diff --git a/tests/auto/qprocess/.gitignore b/tests/auto/qprocess/.gitignore
new file mode 100644
index 0000000..a273810
--- /dev/null
+++ b/tests/auto/qprocess/.gitignore
@@ -0,0 +1,22 @@
+tst_qprocess
+fileWriterProcess/fileWriterProcess
+test Space In Name/
+testDetached/testDetached
+testExitCodes/testExitCodes
+testGuiProcess/testGuiProcess
+testProcessCrash/testProcessCrash
+testProcessDeadWhileReading/testProcessDeadWhileReading
+testProcessEOF/testProcessEOF
+testProcessEcho/testProcessEcho
+testProcessEcho2/testProcessEcho2
+testProcessEcho3/testProcessEcho3
+testProcessEnvironment/testProcessEnvironment
+testProcessLoopback/testProcessLoopback
+testProcessNormal/testProcessNormal
+testProcessOutput/testProcessOutput
+testProcessSpacesArgs/nospace
+testProcessSpacesArgs/one space
+testProcessSpacesArgs/two space s
+testSetWorkingDirectory/testSetWorkingDirectory
+testSoftExit/testSoftExit
+data
diff --git a/tests/auto/qprocess/fileWriterProcess/fileWriterProcess.pro b/tests/auto/qprocess/fileWriterProcess/fileWriterProcess.pro
new file mode 100644
index 0000000..c9f87ba
--- /dev/null
+++ b/tests/auto/qprocess/fileWriterProcess/fileWriterProcess.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= app_bundle
+QT = core
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/fileWriterProcess/main.cpp b/tests/auto/qprocess/fileWriterProcess/main.cpp
new file mode 100644
index 0000000..34c9cff
--- /dev/null
+++ b/tests/auto/qprocess/fileWriterProcess/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication ca(argc, argv);
+ QFile f;
+ f.open(stdin, QIODevice::ReadOnly);
+ QString input;
+ char buf[1024];
+ qint64 len;
+ while ((len = f.read(buf, 1024)) > 0)
+ input += QByteArray(buf, len);
+ f.close();
+ QFile f2("fileWriterProcess.txt");
+ f2.open(QIODevice::WriteOnly | QIODevice::Truncate);
+ f2.write(input.toLatin1());
+ f2.close();
+ return 0;
+}
diff --git a/tests/auto/qprocess/qprocess.pro b/tests/auto/qprocess/qprocess.pro
new file mode 100644
index 0000000..4600f02
--- /dev/null
+++ b/tests/auto/qprocess/qprocess.pro
@@ -0,0 +1,27 @@
+TEMPLATE = subdirs
+SUBDIRS = testProcessCrash \
+ testProcessEcho \
+ testProcessEcho2 \
+ testProcessEcho3 \
+ testProcessLoopback \
+ testProcessNormal \
+ testProcessOutput \
+ testProcessDeadWhileReading \
+ testProcessEOF \
+ testSoftExit \
+ testProcessSpacesArgs/nospace.pro \
+ testProcessSpacesArgs/onespace.pro \
+ testProcessSpacesArgs/twospaces.pro \
+ testExitCodes \
+ testSpaceInName \
+ testGuiProcess \
+ testDetached \
+ fileWriterProcess \
+ testSetWorkingDirectory
+
+
+win32:!wince*:SUBDIRS+=testProcessEchoGui
+
+SUBDIRS += test
+
+
diff --git a/tests/auto/qprocess/test/test.pro b/tests/auto/qprocess/test/test.pro
new file mode 100644
index 0000000..3741e3c
--- /dev/null
+++ b/tests/auto/qprocess/test/test.pro
@@ -0,0 +1,49 @@
+load(qttest_p4)
+
+SOURCES += ../tst_qprocess.cpp
+!wince*: {
+TARGET = ../tst_qprocess
+
+win32: {
+ CONFIG(debug, debug|release) {
+ TARGET = ../../debug/tst_qprocess
+} else {
+ TARGET = ../../release/tst_qprocess
+ }
+}
+} else {
+ TARGET = tst_qprocess
+}
+
+
+
+QT = core
+QT += network
+embedded: QT += gui
+
+wince*: {
+ addFiles.sources = \
+ ../fileWriterProcess \
+ "../test Space In Name" \
+ ../testBatFiles \
+ ../testDetached \
+ ../testExitCodes \
+ ../testGuiProcess \
+ ../testProcessCrash \
+ ../testProcessDeadWhileReading \
+ ../testProcessEcho \
+ ../testProcessEcho2 \
+ ../testProcessEcho3 \
+ ../testProcessEchoGui \
+ ../testProcessEOF \
+ ../testProcessLoopback \
+ ../testProcessNormal \
+ ../testProcessOutput \
+ ../testProcessSpacesArgs \
+ ../testSoftExit \
+ ../testSpaceInName
+
+ addFiles.path = \Program Files\tst_qprocess
+ DEPLOYMENT += addFiles
+}
+
diff --git a/tests/auto/qprocess/testBatFiles/simple.bat b/tests/auto/qprocess/testBatFiles/simple.bat
new file mode 100755
index 0000000..900f7ae
--- /dev/null
+++ b/tests/auto/qprocess/testBatFiles/simple.bat
@@ -0,0 +1,2 @@
+@echo off
+echo Hello \ No newline at end of file
diff --git a/tests/auto/qprocess/testBatFiles/with space.bat b/tests/auto/qprocess/testBatFiles/with space.bat
new file mode 100755
index 0000000..900f7ae
--- /dev/null
+++ b/tests/auto/qprocess/testBatFiles/with space.bat
@@ -0,0 +1,2 @@
+@echo off
+echo Hello \ No newline at end of file
diff --git a/tests/auto/qprocess/testDetached/main.cpp b/tests/auto/qprocess/testDetached/main.cpp
new file mode 100644
index 0000000..035929b
--- /dev/null
+++ b/tests/auto/qprocess/testDetached/main.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QCoreApplication>
+#include <QDebug>
+#include <QStringList>
+#include <QFile>
+#include <QDir>
+
+#include <stdio.h>
+
+#if defined(Q_OS_UNIX)
+#include <sys/types.h>
+#include <unistd.h>
+#elif defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QStringList args = app.arguments();
+ if (args.count() != 2) {
+ fprintf(stderr, "Usage: testDetached filename.txt\n");
+ return 128;
+ }
+
+ QFile f(args.at(1));
+ if (!f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+ fprintf(stderr, "Cannot open %s for writing", qPrintable(f.fileName()));
+ return 1;
+ }
+
+ f.write(QDir::currentPath().toUtf8());
+ f.putChar('\n');
+#if defined(Q_OS_UNIX)
+ f.write(QByteArray::number(quint64(getpid())));
+#elif defined(Q_OS_WIN)
+ f.write(QByteArray::number(quint64(GetCurrentProcessId())));
+#endif
+ f.putChar('\n');
+
+ f.close();
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testDetached/testDetached.pro b/tests/auto/qprocess/testDetached/testDetached.pro
new file mode 100644
index 0000000..6792ef4
--- /dev/null
+++ b/tests/auto/qprocess/testDetached/testDetached.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+INSTALLS =
+DESTDIR = ./
+
diff --git a/tests/auto/qprocess/testExitCodes/main.cpp b/tests/auto/qprocess/testExitCodes/main.cpp
new file mode 100644
index 0000000..477791f
--- /dev/null
+++ b/tests/auto/qprocess/testExitCodes/main.cpp
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdlib.h>
+int main(int /* argc */, char **argv)
+{
+ return atoi(argv[1]);
+}
+
diff --git a/tests/auto/qprocess/testExitCodes/testExitCodes.pro b/tests/auto/qprocess/testExitCodes/testExitCodes.pro
new file mode 100644
index 0000000..b083718
--- /dev/null
+++ b/tests/auto/qprocess/testExitCodes/testExitCodes.pro
@@ -0,0 +1,5 @@
+SOURCES += main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+
+DESTDIR = ./
diff --git a/tests/auto/qprocess/testGuiProcess/main.cpp b/tests/auto/qprocess/testGuiProcess/main.cpp
new file mode 100644
index 0000000..63e6aa1
--- /dev/null
+++ b/tests/auto/qprocess/testGuiProcess/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtGui>
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QLabel label("This process is just waiting to die");
+ label.show();
+
+ int c;
+ fgetc(stdin); // block until fed
+
+ qDebug("Process is running");
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testGuiProcess/testGuiProcess.pro b/tests/auto/qprocess/testGuiProcess/testGuiProcess.pro
new file mode 100644
index 0000000..15a9e8e
--- /dev/null
+++ b/tests/auto/qprocess/testGuiProcess/testGuiProcess.pro
@@ -0,0 +1,4 @@
+SOURCES += main.cpp
+CONFIG += console
+DESTDIR = ./
+
diff --git a/tests/auto/qprocess/testProcessCrash/main.cpp b/tests/auto/qprocess/testProcessCrash/main.cpp
new file mode 100644
index 0000000..b3e8272
--- /dev/null
+++ b/tests/auto/qprocess/testProcessCrash/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+struct Foo
+{
+ int i;
+};
+
+int main()
+{
+ *(char*)0 = 0;
+ Foo *f = 0;
+ return f->i;
+}
diff --git a/tests/auto/qprocess/testProcessCrash/testProcessCrash.pro b/tests/auto/qprocess/testProcessCrash/testProcessCrash.pro
new file mode 100644
index 0000000..abd8167
--- /dev/null
+++ b/tests/auto/qprocess/testProcessCrash/testProcessCrash.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= qt app_bundle
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
diff --git a/tests/auto/qprocess/testProcessDeadWhileReading/main.cpp b/tests/auto/qprocess/testProcessDeadWhileReading/main.cpp
new file mode 100644
index 0000000..f314dde
--- /dev/null
+++ b/tests/auto/qprocess/testProcessDeadWhileReading/main.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+ for (int i=0; i<10240; i++)
+ fprintf(stdout, "%d dead while reading\n", i);
+ fflush(stdout);
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro b/tests/auto/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
new file mode 100644
index 0000000..2168ba5
--- /dev/null
+++ b/tests/auto/qprocess/testProcessDeadWhileReading/testProcessDeadWhileReading.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testProcessEOF/main.cpp b/tests/auto/qprocess/testProcessEOF/main.cpp
new file mode 100644
index 0000000..30a0319
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEOF/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+ char buf[32];
+ memset(buf, 0, sizeof(buf));
+
+ char *cptr = buf;
+ int c;
+ while (cptr != buf + 31 && (c = fgetc(stdin)) != EOF)
+ *cptr++ = (char) c;
+
+ printf("%s", buf);
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessEOF/testProcessEOF.pro b/tests/auto/qprocess/testProcessEOF/testProcessEOF.pro
new file mode 100644
index 0000000..f406759
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEOF/testProcessEOF.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+
+!win32-g++:win32:!equals(TEMPLATE_PREFIX, "vc"):QMAKE_CXXFLAGS += /GS-
+DESTDIR = ./
+
+
+
diff --git a/tests/auto/qprocess/testProcessEcho/main.cpp b/tests/auto/qprocess/testProcessEcho/main.cpp
new file mode 100644
index 0000000..ed5e1ea
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho/main.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+#if defined(_WIN32_WCE) && defined(_X86_)
+ return 0;
+#else
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fflush(stdout);
+ }
+ return 0;
+#endif
+}
diff --git a/tests/auto/qprocess/testProcessEcho/testProcessEcho.pro b/tests/auto/qprocess/testProcessEcho/testProcessEcho.pro
new file mode 100644
index 0000000..a14c1fe
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho/testProcessEcho.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/qprocess/testProcessEcho2/main.cpp b/tests/auto/qprocess/testProcessEcho2/main.cpp
new file mode 100644
index 0000000..2f2134d
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho2/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fputc(c, stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessEcho2/testProcessEcho2.pro b/tests/auto/qprocess/testProcessEcho2/testProcessEcho2.pro
new file mode 100644
index 0000000..d8a303a
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho2/testProcessEcho2.pro
@@ -0,0 +1,10 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/qprocess/testProcessEcho3/main.cpp b/tests/auto/qprocess/testProcessEcho3/main.cpp
new file mode 100644
index 0000000..932939e
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho3/main.cpp
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+ int c;
+ for (;;) {
+ c = fgetc(stdin);
+ if (c == '\0')
+ break;
+ if (c != -1) {
+ fputc(c, stdout);
+ fputc(c, stderr);
+ fflush(stdout);
+ fflush(stderr);
+ }
+ }
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessEcho3/testProcessEcho3.pro b/tests/auto/qprocess/testProcessEcho3/testProcessEcho3.pro
new file mode 100644
index 0000000..3b8f2fb
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEcho3/testProcessEcho3.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testProcessEchoGui/main_win.cpp b/tests/auto/qprocess/testProcessEchoGui/main_win.cpp
new file mode 100644
index 0000000..0fab773
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEchoGui/main_win.cpp
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <windows.h>
+
+int APIENTRY WinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPSTR lpCmdLine,
+ int nCmdShow)
+{
+
+ HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
+ HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ HANDLE hStderr = GetStdHandle(STD_ERROR_HANDLE);
+
+ for (;;) {
+
+ char c = 0;
+ DWORD read = 0;
+ if (!ReadFile(hStdin, &c, 1, &read, 0) || read == 0 || c == 'q' || c == '\0')
+ break;
+ DWORD wrote = 0;
+ WriteFile(hStdout, &c, 1, &wrote, 0);
+ WriteFile(hStderr, &c, 1, &wrote, 0);
+ }
+ return 0;
+} \ No newline at end of file
diff --git a/tests/auto/qprocess/testProcessEchoGui/testProcessEchoGui.pro b/tests/auto/qprocess/testProcessEchoGui/testProcessEchoGui.pro
new file mode 100644
index 0000000..b3be74c
--- /dev/null
+++ b/tests/auto/qprocess/testProcessEchoGui/testProcessEchoGui.pro
@@ -0,0 +1,13 @@
+win32 {
+ SOURCES = main_win.cpp
+ !win32-borland:LIBS += -lUser32
+}
+
+CONFIG -= qt
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/qprocess/testProcessLoopback/main.cpp b/tests/auto/qprocess/testProcessLoopback/main.cpp
new file mode 100644
index 0000000..af09f95
--- /dev/null
+++ b/tests/auto/qprocess/testProcessLoopback/main.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+ char buffer[1024];
+ for (;;) {
+ size_t num = fread(buffer, 1, sizeof(buffer), stdin);
+ if (num <= 0)
+ break;
+ fwrite(buffer, num, 1, stdout);
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessLoopback/testProcessLoopback.pro b/tests/auto/qprocess/testProcessLoopback/testProcessLoopback.pro
new file mode 100644
index 0000000..a14c1fe
--- /dev/null
+++ b/tests/auto/qprocess/testProcessLoopback/testProcessLoopback.pro
@@ -0,0 +1,8 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/qprocess/testProcessNormal/main.cpp b/tests/auto/qprocess/testProcessNormal/main.cpp
new file mode 100644
index 0000000..cbe1981
--- /dev/null
+++ b/tests/auto/qprocess/testProcessNormal/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+int main()
+{
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessNormal/testProcessNormal.pro b/tests/auto/qprocess/testProcessNormal/testProcessNormal.pro
new file mode 100644
index 0000000..3c6a595
--- /dev/null
+++ b/tests/auto/qprocess/testProcessNormal/testProcessNormal.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG += console
+CONFIG -= qt app_bundle
+
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/qprocess/testProcessOutput/main.cpp b/tests/auto/qprocess/testProcessOutput/main.cpp
new file mode 100644
index 0000000..a2aa67f
--- /dev/null
+++ b/tests/auto/qprocess/testProcessOutput/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+#ifndef _WIN32_WCE
+ for (int i=0; i<10240; i++) {
+#else //fprintf Output is very slow on Windows CE
+ for (int i=0; i<240; i++) {
+#endif
+ fprintf(stdout, "%d -this is a number\n", i);
+ fflush(stderr);
+ }
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessOutput/testProcessOutput.pro b/tests/auto/qprocess/testProcessOutput/testProcessOutput.pro
new file mode 100644
index 0000000..3b8f2fb
--- /dev/null
+++ b/tests/auto/qprocess/testProcessOutput/testProcessOutput.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testProcessSpacesArgs/main.cpp b/tests/auto/qprocess/testProcessSpacesArgs/main.cpp
new file mode 100644
index 0000000..fea074a
--- /dev/null
+++ b/tests/auto/qprocess/testProcessSpacesArgs/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main(int argc, char ** argv)
+{
+ for (int i = 0; i < argc; ++i) {
+ if (i)
+ printf("|");
+ printf(argv[i]);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testProcessSpacesArgs/nospace.pro b/tests/auto/qprocess/testProcessSpacesArgs/nospace.pro
new file mode 100644
index 0000000..f55f02e
--- /dev/null
+++ b/tests/auto/qprocess/testProcessSpacesArgs/nospace.pro
@@ -0,0 +1,9 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/qprocess/testProcessSpacesArgs/onespace.pro
new file mode 100644
index 0000000..2a56a95
--- /dev/null
+++ b/tests/auto/qprocess/testProcessSpacesArgs/onespace.pro
@@ -0,0 +1,11 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+TARGET = "one space"
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/qprocess/testProcessSpacesArgs/twospaces.pro
new file mode 100644
index 0000000..d7c74a6
--- /dev/null
+++ b/tests/auto/qprocess/testProcessSpacesArgs/twospaces.pro
@@ -0,0 +1,12 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+TARGET = "two space s"
+
+# no install rule for application used by test
+INSTALLS =
+
+
+
diff --git a/tests/auto/qprocess/testSetWorkingDirectory/main.cpp b/tests/auto/qprocess/testSetWorkingDirectory/main.cpp
new file mode 100644
index 0000000..d4ff683
--- /dev/null
+++ b/tests/auto/qprocess/testSetWorkingDirectory/main.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtCore>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+ QByteArray currentPath = QDir::currentPath().toLocal8Bit();
+ fprintf(stdout, "%s", currentPath.constData());
+ app.exit();
+}
diff --git a/tests/auto/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro b/tests/auto/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
new file mode 100644
index 0000000..b723604
--- /dev/null
+++ b/tests/auto/qprocess/testSetWorkingDirectory/testSetWorkingDirectory.pro
@@ -0,0 +1,7 @@
+SOURCES = main.cpp
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
diff --git a/tests/auto/qprocess/testSoftExit/main_unix.cpp b/tests/auto/qprocess/testSoftExit/main_unix.cpp
new file mode 100644
index 0000000..d358ffd
--- /dev/null
+++ b/tests/auto/qprocess/testSoftExit/main_unix.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <sys/types.h>
+#include <signal.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+int main()
+{
+ struct sigaction noaction;
+ memset(&noaction, 0, sizeof(noaction));
+ noaction.sa_handler = SIG_IGN;
+ ::sigaction(SIGTERM, &noaction, 0);
+
+ printf("Ready\n");
+ fflush(stdout);
+
+ for (int i = 0; i < 5; ++i)
+ sleep(1);
+ return 0;
+}
diff --git a/tests/auto/qprocess/testSoftExit/main_win.cpp b/tests/auto/qprocess/testSoftExit/main_win.cpp
new file mode 100644
index 0000000..93b31e4
--- /dev/null
+++ b/tests/auto/qprocess/testSoftExit/main_win.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <windows.h>
+#include <stdio.h>
+
+int main()
+{
+ printf("Ready\n");
+ fflush(stdout);
+
+ MSG msg;
+ while (GetMessage(&msg, NULL, 0, 0)) {
+ if (msg.message == WM_CLOSE)
+ PostQuitMessage(0);
+ }
+
+ return msg.wParam;
+}
diff --git a/tests/auto/qprocess/testSoftExit/testSoftExit.pro b/tests/auto/qprocess/testSoftExit/testSoftExit.pro
new file mode 100644
index 0000000..9220359
--- /dev/null
+++ b/tests/auto/qprocess/testSoftExit/testSoftExit.pro
@@ -0,0 +1,16 @@
+win32 {
+ SOURCES = main_win.cpp
+ !win32-borland:!wince*:LIBS += -lUser32
+}
+unix {
+ SOURCES = main_unix.cpp
+}
+
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/testSpaceInName/main.cpp b/tests/auto/qprocess/testSpaceInName/main.cpp
new file mode 100644
index 0000000..622bcdf
--- /dev/null
+++ b/tests/auto/qprocess/testSpaceInName/main.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <stdio.h>
+
+int main()
+{
+ int c;
+ while ((c = fgetc(stdin)) != -1) {
+ if (c == '\0')
+ break;
+ fputc(c, stdout);
+ fflush(stdout);
+ }
+
+ return 0;
+}
diff --git a/tests/auto/qprocess/testSpaceInName/testSpaceInName.pro b/tests/auto/qprocess/testSpaceInName/testSpaceInName.pro
new file mode 100644
index 0000000..913e868
--- /dev/null
+++ b/tests/auto/qprocess/testSpaceInName/testSpaceInName.pro
@@ -0,0 +1,13 @@
+SOURCES = main.cpp
+CONFIG -= qt
+CONFIG += console
+DESTDIR = "../test Space In Name"
+
+mac {
+ CONFIG -= app_bundle
+}
+
+# no install rule for application used by test
+INSTALLS =
+
+
diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp
new file mode 100644
index 0000000..f0dae5d
--- /dev/null
+++ b/tests/auto/qprocess/tst_qprocess.cpp
@@ -0,0 +1,2004 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QtTest/QtTest>
+#include <QtCore/QProcess>
+#include <QtCore/QDir>
+#include <QtCore/QFile>
+#include <QtCore/QThread>
+#include <QtCore/QRegExp>
+#include <QtCore/QDebug>
+#include <QtNetwork/QHostInfo>
+#include <stdlib.h>
+
+#if defined(Q_OS_WIN)
+#include <windows.h>
+#endif
+
+//TESTED_CLASS=
+//TESTED_FILES=
+
+Q_DECLARE_METATYPE(QList<QProcess::ExitStatus>);
+Q_DECLARE_METATYPE(QProcess::ExitStatus);
+Q_DECLARE_METATYPE(QProcess::ProcessState);
+
+#define QPROCESS_VERIFY(Process, Fn) \
+{ \
+const bool ret = Process.Fn; \
+if (ret == false) \
+ qWarning("QProcess error: %d: %s", Process.error(), qPrintable(Process.errorString())); \
+QVERIFY(ret); \
+}
+
+class tst_QProcess : public QObject
+{
+ Q_OBJECT
+
+public:
+ tst_QProcess();
+ virtual ~tst_QProcess();
+
+public slots:
+ void init();
+ void cleanup();
+
+private slots:
+ void getSetCheck();
+ void constructing();
+ void simpleStart();
+ void startDetached();
+ void crashTest();
+ void crashTest2();
+ void echoTest_data();
+ void echoTest();
+ void echoTest2();
+ void echoTest_performance();
+#if defined Q_OS_WIN
+ void echoTestGui();
+ void batFiles_data();
+ void batFiles();
+#endif
+ void exitStatus_data();
+ void exitStatus();
+ void loopBackTest();
+ void readTimeoutAndThenCrash();
+ void waitForFinished();
+ void deadWhileReading();
+ void restartProcessDeadlock();
+ void closeWriteChannel();
+ void closeReadChannel();
+ void openModes();
+ void emitReadyReadOnlyWhenNewDataArrives();
+ void hardExit();
+ void softExit();
+ void softExitInSlots_data();
+ void softExitInSlots();
+ void mergedChannels();
+ void forwardedChannels();
+ void atEnd();
+ void atEnd2();
+ void processInAThread();
+ void processesInMultipleThreads();
+ void waitForFinishedWithTimeout();
+ void waitForReadyReadInAReadyReadSlot();
+ void waitForBytesWrittenInABytesWrittenSlot();
+ void spaceArgsTest_data();
+ void spaceArgsTest();
+ void exitCodeTest();
+ void systemEnvironment();
+ void spaceInName();
+ void lockupsInStartDetached();
+ void waitForReadyReadForNonexistantProcess();
+ void setStandardInputFile();
+ void setStandardOutputFile_data();
+ void setStandardOutputFile();
+ void setStandardOutputProcess_data();
+ void setStandardOutputProcess();
+ void removeFileWhileProcessIsRunning();
+ void fileWriterProcess();
+ void detachedWorkingDirectoryAndPid();
+ void switchReadChannels();
+ void setWorkingDirectory();
+ void startFinishStartFinish();
+
+ // 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)
+ void failToStart();
+ void failToStartWithWait();
+ void failToStartWithEventLoop();
+
+protected slots:
+ void readFromProcess();
+ void exitLoopSlot();
+ void restartProcess();
+ void waitForReadyReadInAReadyReadSlotSlot();
+ void waitForBytesWrittenInABytesWrittenSlotSlot();
+
+private:
+ QProcess *process;
+ qint64 bytesAvailable;
+};
+
+// Testing get/set functions
+void tst_QProcess::getSetCheck()
+{
+ QProcess obj1;
+ // ProcessChannelMode QProcess::readChannelMode()
+ // void QProcess::setReadChannelMode(ProcessChannelMode)
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::SeparateChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::SeparateChannels), obj1.readChannelMode());
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::MergedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::MergedChannels), obj1.readChannelMode());
+ obj1.setReadChannelMode(QProcess::ProcessChannelMode(QProcess::ForwardedChannels));
+ QCOMPARE(QProcess::ProcessChannelMode(QProcess::ForwardedChannels), obj1.readChannelMode());
+
+ // ProcessChannel QProcess::readChannel()
+ // void QProcess::setReadChannel(ProcessChannel)
+ obj1.setReadChannel(QProcess::ProcessChannel(QProcess::StandardOutput));
+ QCOMPARE(QProcess::ProcessChannel(QProcess::StandardOutput), obj1.readChannel());
+ obj1.setReadChannel(QProcess::ProcessChannel(QProcess::StandardError));
+ QCOMPARE(QProcess::ProcessChannel(QProcess::StandardError), obj1.readChannel());
+}
+
+tst_QProcess::tst_QProcess()
+{
+}
+
+tst_QProcess::~tst_QProcess()
+{
+}
+
+void tst_QProcess::init()
+{
+}
+
+void tst_QProcess::cleanup()
+{
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::constructing()
+{
+ QProcess process;
+ QCOMPARE(process.readChannel(), QProcess::StandardOutput);
+ QCOMPARE(process.workingDirectory(), QString());
+ QCOMPARE(process.environment(), QStringList());
+ QCOMPARE(process.error(), QProcess::UnknownError);
+ QCOMPARE(process.state(), QProcess::NotRunning);
+ QCOMPARE(process.pid(), Q_PID(0));
+ QCOMPARE(process.readAllStandardOutput(), QByteArray());
+ QCOMPARE(process.readAllStandardError(), QByteArray());
+ QCOMPARE(process.canReadLine(), false);
+
+ // QIODevice
+ QCOMPARE(process.openMode(), QIODevice::NotOpen);
+ QVERIFY(!process.isOpen());
+ QVERIFY(!process.isReadable());
+ QVERIFY(!process.isWritable());
+ QVERIFY(process.isSequential());
+ QCOMPARE(process.pos(), qlonglong(0));
+ QCOMPARE(process.size(), qlonglong(0));
+ QVERIFY(process.atEnd());
+ QCOMPARE(process.bytesAvailable(), qlonglong(0));
+ QCOMPARE(process.bytesToWrite(), qlonglong(0));
+ QVERIFY(!process.errorString().isEmpty());
+
+ char c;
+ QCOMPARE(process.read(&c, 1), qlonglong(-1));
+ QCOMPARE(process.write(&c, 1), qlonglong(-1));
+}
+
+void tst_QProcess::simpleStart()
+{
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+
+ process = new QProcess;
+ QSignalSpy spy(process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ connect(process, SIGNAL(readyRead()), this, SLOT(readFromProcess()));
+
+ /* valgrind dislike SUID binaries(those that have the `s'-flag set), which
+ * makes it fail to start the process. For this reason utilities like `ping' won't
+ * start, when the auto test is run through `valgrind'. */
+ process->start("testProcessNormal/testProcessNormal");
+ if (process->state() != QProcess::Starting)
+ QCOMPARE(process->state(), QProcess::Running);
+ QVERIFY(process->waitForStarted(5000));
+ QCOMPARE(process->state(), QProcess::Running);
+#if defined(Q_OS_WINCE)
+ while (process->waitForFinished(5000))
+ { }
+#else
+ while (process->waitForReadyRead(5000))
+ { }
+#endif
+ QCOMPARE(process->state(), QProcess::NotRunning);
+
+ delete process;
+ process = 0;
+
+ QCOMPARE(spy.count(), 3);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(0).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(1).at(0)), QProcess::Running);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(spy.at(2).at(0)), QProcess::NotRunning);
+}
+//-----------------------------------------------------------------------------
+void tst_QProcess::startDetached()
+{
+#if QT_VERSION >= 0x040200
+ QProcess proc;
+ QVERIFY(proc.startDetached("testProcessNormal/testProcessNormal",
+ QStringList() << "arg1" << "arg2"));
+#endif
+ QCOMPARE(QProcess::startDetached("nonexistingexe"), false);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::readFromProcess()
+{
+ int lines = 0;
+ while (process->canReadLine()) {
+ ++lines;
+ QByteArray line = process->readLine();
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::crashTest()
+{
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+#ifdef Q_OS_WIN
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+ process = new QProcess;
+ QSignalSpy stateSpy(process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ process->start("testProcessCrash/testProcessCrash");
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ExitStatus");
+
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy spy2(process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ QVERIFY(process->waitForFinished(5000));
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ QCOMPARE(spy2.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
+
+ QCOMPARE(process->exitStatus(), QProcess::CrashExit);
+
+ delete process;
+ process = 0;
+
+ QCOMPARE(stateSpy.count(), 3);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(0).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(1).at(0)), QProcess::Running);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(2).at(0)), QProcess::NotRunning);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::crashTest2()
+{
+#ifdef Q_OS_WIN
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+ process = new QProcess;
+ process->start("testProcessCrash/testProcessCrash");
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ExitStatus");
+
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy spy2(process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ QObject::connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot()));
+
+ QTestEventLoop::instance().enterLoop(5);
+ if (QTestEventLoop::instance().timeout())
+ QFAIL("Failed to detect crash : operation timed out");
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ QCOMPARE(spy2.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ExitStatus *>(spy2.at(0).at(1).constData()), QProcess::CrashExit);
+
+ QCOMPARE(process->exitStatus(), QProcess::CrashExit);
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest_data()
+{
+ QTest::addColumn<QByteArray>("input");
+
+ QTest::newRow("1") << QByteArray("H");
+ QTest::newRow("2") << QByteArray("He");
+ QTest::newRow("3") << QByteArray("Hel");
+ QTest::newRow("4") << QByteArray("Hell");
+ QTest::newRow("5") << QByteArray("Hello");
+ QTest::newRow("100 bytes") << QByteArray(100, '@');
+ QTest::newRow("1000 bytes") << QByteArray(1000, '@');
+ QTest::newRow("10000 bytes") << QByteArray(10000, '@');
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QFETCH(QByteArray, input);
+
+ process = new QProcess;
+ connect(process, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ process->write(input);
+
+ QTime stopWatch;
+ stopWatch.start();
+ do {
+ QVERIFY(process->isOpen());
+ QTestEventLoop::instance().enterLoop(2);
+ } while (stopWatch.elapsed() < 60000 && process->bytesAvailable() < input.size());
+ if (stopWatch.elapsed() >= 60000)
+ QFAIL("Timed out");
+
+ QByteArray message = process->readAll();
+ QCOMPARE(message.size(), input.size());
+
+ char *c1 = message.data();
+ char *c2 = input.data();
+ while (*c1 && *c2) {
+ if (*c1 != *c2)
+ QCOMPARE(*c1, *c2);
+ ++c1;
+ ++c2;
+ }
+ QCOMPARE(*c1, *c2);
+
+ process->write("", 1);
+
+ QVERIFY(process->waitForFinished(5000));
+
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitLoopSlot()
+{
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest2()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess;
+ connect(process, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process->start("testProcessEcho2/testProcessEcho2");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(!process->waitForReadyRead(250));
+ QCOMPARE(process->error(), QProcess::Timedout);
+
+ process->write("Hello");
+ QSignalSpy spy1(process, SIGNAL(readyReadStandardOutput()));
+ QSignalSpy spy2(process, SIGNAL(readyReadStandardError()));
+
+ QTime stopWatch;
+ stopWatch.start();
+ forever {
+ QTestEventLoop::instance().enterLoop(1);
+ if (stopWatch.elapsed() >= 30000)
+ QFAIL("Timed out");
+ process->setReadChannel(QProcess::StandardOutput);
+ qint64 baso = process->bytesAvailable();
+
+ process->setReadChannel(QProcess::StandardError);
+ qint64 base = process->bytesAvailable();
+ if (baso == 5 && base == 5)
+ break;
+ }
+
+ QVERIFY(spy1.count() > 0);
+ QVERIFY(spy2.count() > 0);
+
+ QCOMPARE(process->readAllStandardOutput(), QByteArray("Hello"));
+ QCOMPARE(process->readAllStandardError(), QByteArray("Hello"));
+
+ process->write("", 1);
+ QVERIFY(process->waitForFinished(5000));
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTest_performance()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+#ifdef Q_OS_MAC
+ process.start("testProcessLoopback/testProcessLoopback.app");
+#else
+ process.start("testProcessLoopback/testProcessLoopback");
+#endif
+
+ QByteArray array;
+ array.resize(1024 * 1024);
+ for (int j = 0; j < array.size(); ++j)
+ array[j] = 'a' + (j % 20);
+
+ QVERIFY(process.waitForStarted());
+
+ QTime stopWatch;
+ stopWatch.start();
+
+ qint64 totalBytes = 0;
+ QByteArray dump;
+ QSignalSpy readyReadSpy(&process, SIGNAL(readyRead()));
+ while (stopWatch.elapsed() < 2000) {
+ process.write(array);
+ while (process.bytesToWrite() > 0) {
+ int readCount = readyReadSpy.count();
+ QVERIFY(process.waitForBytesWritten(5000));
+ if (readyReadSpy.count() == readCount)
+ QVERIFY(process.waitForReadyRead(5000));
+ }
+
+ while (process.bytesAvailable() < array.size())
+ QVERIFY2(process.waitForReadyRead(5000), qPrintable(process.errorString()));
+ dump = process.readAll();
+ totalBytes += dump.size();
+ }
+
+ qDebug() << "Elapsed time:" << stopWatch.elapsed() << "ms;"
+ << "transfer rate:" << totalBytes / (1048.576) / stopWatch.elapsed()
+ << "MB/s";
+
+ for (int j = 0; j < array.size(); ++j)
+ QCOMPARE(char(dump.at(j)), char('a' + (j % 20)));
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished());
+}
+
+#if defined Q_OS_WIN
+//-----------------------------------------------------------------------------
+void tst_QProcess::echoTestGui()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+
+ process.start("testProcessEchoGui/testProcessEchoGui");
+
+
+ process.write("Hello");
+ process.write("q");
+
+ QVERIFY(process.waitForFinished(50000));
+
+ QCOMPARE(process.readAllStandardOutput(), QByteArray("Hello"));
+ QCOMPARE(process.readAllStandardError(), QByteArray("Hello"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::batFiles_data()
+{
+ QTest::addColumn<QString>("batFile");
+ QTest::addColumn<QByteArray>("output");
+
+ QTest::newRow("simple") << QString::fromLatin1("testBatFiles/simple.bat") << QByteArray("Hello");
+ QTest::newRow("with space") << QString::fromLatin1("testBatFiles/with space.bat") << QByteArray("Hello");
+}
+
+void tst_QProcess::batFiles()
+{
+#if defined(Q_OS_WINCE)
+ QSKIP("Batch files are not supported on Windows CE", SkipAll);
+#endif
+ QFETCH(QString, batFile);
+ QFETCH(QByteArray, output);
+
+ QProcess proc;
+
+ proc.start(batFile, QStringList());
+
+ QVERIFY(proc.waitForFinished(5000));
+
+ QVERIFY(proc.bytesAvailable() > 0);
+
+ QVERIFY(proc.readAll().startsWith(output));
+}
+
+#endif
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitStatus_data()
+{
+ QTest::addColumn<QStringList>("processList");
+ QTest::addColumn<QList<QProcess::ExitStatus> >("exitStatus");
+
+ QTest::newRow("normal") << (QStringList() << "testProcessNormal/testProcessNormal")
+ << (QList<QProcess::ExitStatus>() << QProcess::NormalExit);
+ QTest::newRow("crash") << (QStringList() << "testProcessCrash/testProcessCrash")
+ << (QList<QProcess::ExitStatus>() << QProcess::CrashExit);
+
+ QTest::newRow("normal-crash") << (QStringList()
+ << "testProcessNormal/testProcessNormal"
+ << "testProcessCrash/testProcessCrash")
+ << (QList<QProcess::ExitStatus>()
+ << QProcess::NormalExit
+ << QProcess::CrashExit);
+ QTest::newRow("crash-normal") << (QStringList()
+ << "testProcessCrash/testProcessCrash"
+ << "testProcessNormal/testProcessNormal")
+ << (QList<QProcess::ExitStatus>()
+ << QProcess::CrashExit
+ << QProcess::NormalExit);
+}
+
+void tst_QProcess::exitStatus()
+{
+ process = new QProcess;
+ QFETCH(QStringList, processList);
+ QFETCH(QList<QProcess::ExitStatus>, exitStatus);
+
+#ifdef Q_OS_WIN
+ if (exitStatus.contains(QProcess::CrashExit))
+ QSKIP("This test opens a crash dialog on Windows", SkipSingle);
+#endif
+
+ Q_ASSERT(processList.count() == exitStatus.count());
+ for (int i = 0; i < processList.count(); ++i) {
+ process->start(processList.at(i));
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(5000));
+
+ QCOMPARE(process->exitStatus(), exitStatus.at(i));
+ }
+
+ process->deleteLater();
+ process = 0;
+}
+//-----------------------------------------------------------------------------
+void tst_QProcess::loopBackTest()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess;
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ for (int i = 0; i < 100; ++i) {
+ process->write("Hello");
+ do {
+ QVERIFY(process->waitForReadyRead(5000));
+ } while (process->bytesAvailable() < 5);
+ QCOMPARE(process->readAll(), QByteArray("Hello"));
+ }
+
+ process->write("", 1);
+ QVERIFY(process->waitForFinished(5000));
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::readTimeoutAndThenCrash()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess;
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ if (process->state() != QProcess::Starting)
+ QCOMPARE(process->state(), QProcess::Running);
+
+ QVERIFY(process->waitForStarted(5000));
+ QCOMPARE(process->state(), QProcess::Running);
+
+ QVERIFY(!process->waitForReadyRead(5000));
+ QCOMPARE(process->error(), QProcess::Timedout);
+
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ QSignalSpy spy(process, SIGNAL(error(QProcess::ProcessError)));
+
+ process->kill();
+
+ QVERIFY(process->waitForFinished(5000));
+ QCOMPARE(process->state(), QProcess::NotRunning);
+
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(*static_cast<const QProcess::ProcessError *>(spy.at(0).at(0).constData()), QProcess::Crashed);
+
+ delete process;
+ process = 0;
+}
+
+void tst_QProcess::waitForFinished()
+{
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessOutput/testProcessOutput.app");
+#else
+ process.start("testProcessOutput/testProcessOutput");
+#endif
+
+#ifndef Q_OS_WINCE
+ QVERIFY(process.waitForFinished(5000));
+#else
+ QVERIFY(process.waitForFinished(15000));
+#endif
+ QCOMPARE(process.exitStatus(), QProcess::NormalExit);
+
+#if defined (Q_OS_WINCE)
+ QEXPECT_FAIL("", "Reading and writing to a process is not supported on Qt/CE", Continue);
+#endif
+ QString output = process.readAll();
+ QCOMPARE(output.count("\n"), 10*1024);
+
+ process.start("blurdybloop");
+ QVERIFY(!process.waitForFinished());
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+}
+
+
+void tst_QProcess::deadWhileReading()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessDeadWhileReading/testProcessDeadWhileReading.app");
+#else
+ process.start("testProcessDeadWhileReading/testProcessDeadWhileReading");
+#endif
+
+ QString output;
+
+ QVERIFY(process.waitForStarted(5000));
+ while (process.waitForReadyRead(5000))
+ output += process.readAll();
+
+ QCOMPARE(output.count("\n"), 10*1024);
+ process.waitForFinished();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::restartProcessDeadlock()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+ // The purpose of this test is to detect whether restarting a
+ // process in the finished() connected slot causes a deadlock
+ // because of the way QProcessManager uses its locks.
+ QProcess proc;
+ process = &proc;
+ connect(process, SIGNAL(finished(int)), this, SLOT(restartProcess()));
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+
+ QCOMPARE(process->write("", 1), qlonglong(1));
+ QVERIFY(process->waitForFinished(5000));
+
+ process->disconnect(SIGNAL(finished(int)));
+
+ QCOMPARE(process->write("", 1), qlonglong(1));
+ QVERIFY(process->waitForFinished(5000));
+}
+
+void tst_QProcess::restartProcess()
+{
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::closeWriteChannel()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess more;
+ more.start("testProcessEOF/testProcessEOF");
+
+ QVERIFY(more.waitForStarted(5000));
+ QVERIFY(!more.waitForReadyRead(250));
+ QCOMPARE(more.error(), QProcess::Timedout);
+
+ QVERIFY(more.write("Data to read") != -1);
+
+ QVERIFY(!more.waitForReadyRead(250));
+ QCOMPARE(more.error(), QProcess::Timedout);
+
+ more.closeWriteChannel();
+
+ QVERIFY(more.waitForReadyRead(5000));
+ QVERIFY(more.readAll().startsWith("Data to read"));
+
+ if (more.state() == QProcess::Running)
+ more.write("q");
+ QVERIFY(more.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::closeReadChannel()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ for (int i = 0; i < 10; ++i) {
+ QProcess::ProcessChannel channel1 = QProcess::StandardOutput;
+ QProcess::ProcessChannel channel2 = QProcess::StandardError;
+
+ QProcess proc;
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ proc.start("testProcessEcho2/testProcessEcho2");
+#endif
+ QVERIFY(proc.waitForStarted(5000));
+ proc.closeReadChannel(i&1 ? channel2 : channel1);
+ proc.setReadChannel(i&1 ? channel2 : channel1);
+ proc.write("Data");
+
+ QVERIFY(!proc.waitForReadyRead(5000));
+ QVERIFY(proc.readAll().isEmpty());
+
+ proc.setReadChannel(i&1 ? channel1 : channel2);
+
+ while (proc.bytesAvailable() < 4 && proc.waitForReadyRead(5000))
+ { }
+
+ QCOMPARE(proc.readAll(), QByteArray("Data"));
+
+ proc.write("", 1);
+ QVERIFY(proc.waitForFinished(5000));
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::openModes()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess proc;
+ QVERIFY(!proc.isOpen());
+ QVERIFY(proc.openMode() == QProcess::NotOpen);
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho3/testProcessEcho3.app");
+#else
+ proc.start("testProcessEcho3/testProcessEcho3");
+#endif
+ QVERIFY(proc.waitForStarted(5000));
+ QVERIFY(proc.isOpen());
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+ QVERIFY(proc.isWritable());
+
+ proc.write("Data");
+
+ proc.closeWriteChannel();
+
+ QVERIFY(proc.isWritable());
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+
+ while (proc.bytesAvailable() < 4 && proc.waitForReadyRead(5000))
+ { }
+
+ QCOMPARE(proc.readAll().constData(), QByteArray("Data").constData());
+
+ proc.closeReadChannel(QProcess::StandardOutput);
+
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+
+ proc.closeReadChannel(QProcess::StandardError);
+
+ QVERIFY(proc.openMode() == QProcess::ReadWrite);
+ QVERIFY(proc.isReadable());
+
+ proc.close();
+ QVERIFY(!proc.isOpen());
+ QVERIFY(!proc.isReadable());
+ QVERIFY(!proc.isWritable());
+ QCOMPARE(proc.state(), QProcess::NotRunning);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::emitReadyReadOnlyWhenNewDataArrives()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess proc;
+ connect(&proc, SIGNAL(readyRead()), this, SLOT(exitLoopSlot()));
+ QSignalSpy spy(&proc, SIGNAL(readyRead()));
+
+#ifdef Q_OS_MAC
+ proc.start("testProcessEcho/testProcessEcho.app");
+#else
+ proc.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QCOMPARE(spy.count(), 0);
+
+ proc.write("A");
+
+ QTestEventLoop::instance().enterLoop(5);
+ if (QTestEventLoop::instance().timeout())
+ QFAIL("Operation timed out");
+
+ QCOMPARE(spy.count(), 1);
+
+ QTestEventLoop::instance().enterLoop(1);
+ QVERIFY(QTestEventLoop::instance().timeout());
+ QVERIFY(!proc.waitForReadyRead(250));
+
+ QObject::disconnect(&proc, SIGNAL(readyRead()), 0, 0);
+ proc.write("B");
+ QVERIFY(proc.waitForReadyRead(5000));
+
+ proc.write("", 1);
+ QVERIFY(proc.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::hardExit()
+{
+ QProcess proc;
+
+#if defined(Q_OS_MAC)
+ proc.start("testProcessEcho/testProcessEcho.app");
+#elif defined(Q_OS_WINCE)
+ proc.start("testSoftExit/testSoftExit");
+#else
+ proc.start("testProcessEcho/testProcessEcho");
+#endif
+
+#ifndef Q_OS_WINCE
+ QVERIFY(proc.waitForStarted(5000));
+#else
+ QVERIFY(proc.waitForStarted(10000));
+#endif
+
+ proc.kill();
+
+ QVERIFY(proc.waitForFinished(5000));
+ QCOMPARE(int(proc.state()), int(QProcess::NotRunning));
+ QCOMPARE(int(proc.error()), int(QProcess::Crashed));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExit()
+{
+ QProcess proc;
+
+ proc.start("testSoftExit/testSoftExit");
+
+ QVERIFY(proc.waitForStarted(10000));
+#if !defined(Q_OS_WINCE)
+ QVERIFY(proc.waitForReadyRead(10000));
+#endif
+
+ proc.terminate();
+
+ QVERIFY(proc.waitForFinished(10000));
+ QCOMPARE(int(proc.state()), int(QProcess::NotRunning));
+ QCOMPARE(int(proc.error()), int(QProcess::UnknownError));
+}
+
+class SoftExitProcess : public QProcess
+{
+ Q_OBJECT
+public:
+ bool waitedForFinished;
+
+ SoftExitProcess(int n) : waitedForFinished(false), n(n), killing(false)
+ {
+ connect(this, SIGNAL(finished(int, QProcess::ExitStatus)),
+ this, SLOT(finishedSlot(int, QProcess::ExitStatus)));
+
+ switch (n) {
+ case 0:
+ setReadChannelMode(QProcess::MergedChannels);
+ connect(this, SIGNAL(readyRead()), this, SLOT(terminateSlot()));
+ break;
+ case 1:
+ connect(this, SIGNAL(readyReadStandardOutput()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 2:
+ connect(this, SIGNAL(readyReadStandardError()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 3:
+ connect(this, SIGNAL(started()),
+ this, SLOT(terminateSlot()));
+ break;
+ case 4:
+ default:
+ connect(this, SIGNAL(stateChanged(QProcess::ProcessState)),
+ this, SLOT(terminateSlot()));
+ break;
+ }
+ }
+
+public slots:
+ void terminateSlot()
+ {
+ if (killing || (n == 4 && state() != Running)) {
+ // Don't try to kill the process before it is running - that can
+ // be hazardous, as the actual child process might not be running
+ // yet. Also, don't kill it "recursively".
+ return;
+ }
+ killing = true;
+ readAll();
+ terminate();
+ if ((waitedForFinished = waitForFinished(5000)) == false) {
+ kill();
+ if (state() != NotRunning)
+ waitedForFinished = waitForFinished(5000);
+ }
+ }
+
+ void finishedSlot(int, QProcess::ExitStatus)
+ {
+ waitedForFinished = true;
+ }
+
+private:
+ int n;
+ bool killing;
+};
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExitInSlots_data()
+{
+ QTest::addColumn<QString>("appName");
+
+#ifdef Q_OS_MAC
+ QTest::newRow("gui app") << "testGuiProcess/testGuiProcess.app";
+#else
+ QTest::newRow("gui app") << "testGuiProcess/testGuiProcess";
+#endif
+#ifdef Q_OS_MAC
+ QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2.app";
+#else
+ QTest::newRow("console app") << "testProcessEcho2/testProcessEcho2";
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::softExitInSlots()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QFETCH(QString, appName);
+
+ for (int i = 0; i < 5; ++i) {
+ SoftExitProcess proc(i);
+ proc.start(appName);
+ proc.write("OLEBOLE", 8); // include the \0
+ QTestEventLoop::instance().enterLoop(1);
+ QCOMPARE(proc.state(), QProcess::NotRunning);
+ QVERIFY(proc.waitedForFinished);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::mergedChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+ process.setReadChannelMode(QProcess::MergedChannels);
+ QCOMPARE(process.readChannelMode(), QProcess::MergedChannels);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+
+ for (int i = 0; i < 100; ++i) {
+ QCOMPARE(process.write("abc"), qlonglong(3));
+ while (process.bytesAvailable() < 6)
+ QVERIFY(process.waitForReadyRead(5000));
+ QCOMPARE(process.readAll(), QByteArray("aabbcc"));
+ }
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::forwardedChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+ process.setReadChannelMode(QProcess::ForwardedChannels);
+ QCOMPARE(process.readChannelMode(), QProcess::ForwardedChannels);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+ QCOMPARE(process.write("forwarded\n"), qlonglong(10));
+ QVERIFY(!process.waitForReadyRead(250));
+ QCOMPARE(process.bytesAvailable(), qlonglong(0));
+
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+}
+
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::atEnd()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+ process.write("abcdefgh\n");
+
+ while (process.bytesAvailable() < 8)
+ QVERIFY(process.waitForReadyRead(5000));
+
+ QTextStream stream(&process);
+ QVERIFY(!stream.atEnd());
+ QString tmp = stream.readLine();
+ QVERIFY(stream.atEnd());
+ QCOMPARE(tmp, QString::fromLatin1("abcdefgh"));
+
+ process.write("", 1);
+ QVERIFY(process.waitForFinished(5000));
+}
+
+class TestThread : public QThread
+{
+ Q_OBJECT
+public:
+ inline int code()
+ {
+ return exitCode;
+ }
+
+protected:
+ inline void run()
+ {
+ exitCode = 90210;
+
+ QProcess process;
+ connect(&process, SIGNAL(finished(int)), this, SLOT(catchExitCode(int)),
+ Qt::DirectConnection);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+#if !defined(Q_OS_WINCE)
+ QCOMPARE(process.write("abc\0", 4), qint64(4));
+#endif
+ exitCode = exec();
+ }
+
+protected slots:
+ inline void catchExitCode(int exitCode)
+ {
+ this->exitCode = exitCode;
+ exit(exitCode);
+ }
+
+private:
+ int exitCode;
+};
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::processInAThread()
+{
+ for (int i = 0; i < 3; ++i) {
+ TestThread thread;
+ thread.start();
+ QVERIFY(thread.wait(10000));
+ QCOMPARE(thread.code(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::processesInMultipleThreads()
+{
+ for (int i = 0; i < 10; ++i) {
+ TestThread thread1;
+ TestThread thread2;
+ TestThread thread3;
+
+ thread1.start();
+ thread2.start();
+ thread3.start();
+
+ QVERIFY(thread2.wait(10000));
+ QVERIFY(thread3.wait(10000));
+ QVERIFY(thread1.wait(10000));
+
+ QCOMPARE(thread1.code(), 0);
+ QCOMPARE(thread2.code(), 0);
+ QCOMPARE(thread3.code(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForFinishedWithTimeout()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess(this);
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(!process->waitForFinished(1));
+
+ process->write("", 1);
+ QVERIFY(process->waitForFinished());
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadInAReadyReadSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess(this);
+ connect(process, SIGNAL(readyRead()), this, SLOT(waitForReadyReadInAReadyReadSlotSlot()));
+ connect(process, SIGNAL(finished(int)), this, SLOT(exitLoopSlot()));
+ bytesAvailable = 0;
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ QSignalSpy spy(process, SIGNAL(readyRead()));
+ process->write("foo");
+ QTestEventLoop::instance().enterLoop(30);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(spy.count(), 1);
+
+ process->disconnect();
+ QVERIFY(process->waitForFinished(5000));
+ QVERIFY(process->bytesAvailable() > bytesAvailable);
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadInAReadyReadSlotSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ bytesAvailable = process->bytesAvailable();
+ process->write("bar", 4);
+ QVERIFY(process->waitForReadyRead(5000));
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForBytesWrittenInABytesWrittenSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process = new QProcess(this);
+ connect(process, SIGNAL(bytesWritten(qint64)), this, SLOT(waitForBytesWrittenInABytesWrittenSlotSlot()));
+ bytesAvailable = 0;
+
+#ifdef Q_OS_MAC
+ process->start("testProcessEcho/testProcessEcho.app");
+#else
+ process->start("testProcessEcho/testProcessEcho");
+#endif
+ QVERIFY(process->waitForStarted(5000));
+
+ qRegisterMetaType<qint64>("qint64");
+ QSignalSpy spy(process, SIGNAL(bytesWritten(qint64)));
+ process->write("f");
+ QTestEventLoop::instance().enterLoop(30);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ QCOMPARE(spy.count(), 1);
+ process->write("", 1);
+ process->disconnect();
+ QVERIFY(process->waitForFinished());
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForBytesWrittenInABytesWrittenSlotSlot()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ process->write("b");
+ QVERIFY(process->waitForBytesWritten(5000));
+ QTestEventLoop::instance().exitLoop();
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceArgsTest_data()
+{
+ QTest::addColumn<QStringList>("args");
+ QTest::addColumn<QString>("stringArgs");
+
+ // arg1 | arg2
+ QTest::newRow("arg1 arg2") << (QStringList() << QString::fromLatin1("arg1") << QString::fromLatin1("arg2"))
+ << QString::fromLatin1("arg1 arg2");
+ // "arg1" | ar "g2
+ QTest::newRow("\"\"\"\"arg1\"\"\"\" \"ar \"\"\"g2\"") << (QStringList() << QString::fromLatin1("\"arg1\"") << QString::fromLatin1("ar \"g2"))
+ << QString::fromLatin1("\"\"\"\"arg1\"\"\"\" \"ar \"\"\"g2\"");
+ // ar g1 | a rg 2
+ QTest::newRow("\"ar g1\" \"a rg 2\"") << (QStringList() << QString::fromLatin1("ar g1") << QString::fromLatin1("a rg 2"))
+ << QString::fromLatin1("\"ar g1\" \"a rg 2\"");
+ // -lar g1 | -l"ar g2"
+ QTest::newRow("\"-lar g1\" \"-l\"\"\"ar g2\"\"\"\"") << (QStringList() << QString::fromLatin1("-lar g1") << QString::fromLatin1("-l\"ar g2\""))
+ << QString::fromLatin1("\"-lar g1\" \"-l\"\"\"ar g2\"\"\"\"");
+ // ar"g1
+ QTest::newRow("ar\"\"\"\"g1") << (QStringList() << QString::fromLatin1("ar\"g1"))
+ << QString::fromLatin1("ar\"\"\"\"g1");
+ // ar/g1
+ QTest::newRow("ar\\g1") << (QStringList() << QString::fromLatin1("ar\\g1"))
+ << QString::fromLatin1("ar\\g1");
+ // ar\g"1
+ QTest::newRow("ar\\g\"\"\"\"1") << (QStringList() << QString::fromLatin1("ar\\g\"1"))
+ << QString::fromLatin1("ar\\g\"\"\"\"1");
+ // arg\"1
+ QTest::newRow("arg\\\"\"\"1") << (QStringList() << QString::fromLatin1("arg\\\"1"))
+ << QString::fromLatin1("arg\\\"\"\"1");
+ // """"
+ QTest::newRow("\"\"\"\"\"\"\"\"\"\"\"\"") << (QStringList() << QString::fromLatin1("\"\"\"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\"\"\"\"\"\"");
+ // """" | "" ""
+ QTest::newRow("\"\"\"\"\"\"\"\"\"\"\"\" \"\"\"\"\"\"\" \"\"\"\"\"\"\"") << (QStringList() << QString::fromLatin1("\"\"\"\"") << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\"\"\"\"\"\" \"\"\"\"\"\"\" \"\"\"\"\"\"\"");
+ // "" ""
+ QTest::newRow("\"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" (bogus double quotes)") << (QStringList() << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1("\"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\"");
+ // "" ""
+ QTest::newRow(" \"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" (bogus double quotes)") << (QStringList() << QString::fromLatin1("\"\" \"\""))
+ << QString::fromLatin1(" \"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" ");
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceArgsTest()
+{
+ QFETCH(QStringList, args);
+ QFETCH(QString, stringArgs);
+
+ QStringList programs;
+ programs << QString::fromLatin1("testProcessSpacesArgs/nospace")
+ << QString::fromLatin1("testProcessSpacesArgs/one space")
+ << QString::fromLatin1("testProcessSpacesArgs/two space s");
+
+ process = new QProcess(this);
+
+ for (int i = 0; i < programs.size(); ++i) {
+
+ QString program = programs.at(i);
+
+ process->start(program, args);
+
+#ifndef Q_OS_WINCE
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(5000));
+#else
+ QVERIFY(process->waitForStarted(10000));
+ QVERIFY(process->waitForFinished(10000));
+#endif
+
+#if !defined(Q_OS_WINCE)
+ QStringList actual = QString::fromLatin1(process->readAll()).split("|");
+ QVERIFY(!actual.isEmpty());
+ // not onterested in the program name, it might be different.
+ actual.removeFirst();
+
+ QCOMPARE(actual, args);
+#endif
+
+ if (program.contains(" "))
+ program = "\"" + program + "\"";
+
+ if (!stringArgs.isEmpty())
+ program += QString::fromLatin1(" ") + stringArgs;
+
+ process->start(program);
+
+ QVERIFY(process->waitForStarted(5000));
+ QVERIFY(process->waitForFinished(5000));
+
+#if !defined(Q_OS_WINCE)
+ actual = QString::fromLatin1(process->readAll()).split("|");
+ QVERIFY(!actual.isEmpty());
+ // not onterested in the program name, it might be different.
+ actual.removeFirst();
+
+ QCOMPARE(actual, args);
+#endif
+ }
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::exitCodeTest()
+{
+ for (int i = 0; i < 255; ++i) {
+ QProcess process;
+ process.start("testExitCodes/testExitCodes " + QString::number(i));
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(process.exitCode(), i);
+ QCOMPARE(process.error(), QProcess::UnknownError);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStart()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+ qRegisterMetaType<QProcess::ProcessState>("QProcess::ProcessState");
+
+ QProcess process;
+ QSignalSpy stateSpy(&process, SIGNAL(stateChanged(QProcess::ProcessState)));
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+// Mac OS X and HP-UX have a really low defualt process limit (~100), so spawning
+// to many processes here will cause test failures later on.
+#if defined Q_OS_HPUX
+ const int attempts = 15;
+#elif defined Q_OS_MAC
+ const int attempts = 15;
+#else
+ const int attempts = 50;
+#endif
+
+ for (int j = 0; j < 8; ++j) {
+ for (int i = 0; i < attempts; ++i) {
+ QCOMPARE(errorSpy.count(), j * attempts + i);
+ process.start("/blurp");
+
+ switch (j) {
+ case 0:
+ case 1:
+ QVERIFY(!process.waitForStarted());
+ break;
+ case 2:
+ case 3:
+ QVERIFY(!process.waitForFinished());
+ break;
+ case 4:
+ case 5:
+ QVERIFY(!process.waitForReadyRead());
+ break;
+ case 6:
+ case 7:
+ default:
+ QVERIFY(!process.waitForBytesWritten());
+ break;
+ }
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), j * attempts + i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+
+ int it = j * attempts + i + 1;
+
+ QCOMPARE(stateSpy.count(), it * 2);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(it * 2 - 2).at(0)), QProcess::Starting);
+ QCOMPARE(qVariantValue<QProcess::ProcessState>(stateSpy.at(it * 2 - 1).at(0)), QProcess::NotRunning);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStartWithWait()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QEventLoop loop;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ for (int i = 0; i < 50; ++i) {
+ process.start("/blurp", QStringList() << "-v" << "-debug");
+ process.waitForStarted();
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::failToStartWithEventLoop()
+{
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QEventLoop loop;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+
+ // The error signal may be emitted before start() returns
+ connect(&process, SIGNAL(error(QProcess::ProcessError)), &loop, SLOT(quit()), Qt::QueuedConnection);
+
+
+ for (int i = 0; i < 50; ++i) {
+ process.start("/blurp", QStringList() << "-v" << "-debug");
+
+ loop.exec();
+
+ QCOMPARE(process.error(), QProcess::FailedToStart);
+ QCOMPARE(errorSpy.count(), i + 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+ }
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::removeFileWhileProcessIsRunning()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QFile file("removeFile.txt");
+ QVERIFY(file.open(QFile::WriteOnly));
+
+ QProcess process;
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QVERIFY(process.waitForStarted(5000));
+
+ QVERIFY(file.remove());
+
+ process.write("", 1);
+ QVERIFY(process.waitForFinished(5000));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::systemEnvironment()
+{
+#if defined (Q_OS_WINCE)
+ // there is no concept of system variables on Windows CE as there is no console
+ QVERIFY(QProcess::systemEnvironment().isEmpty());
+#else
+ QVERIFY(!QProcess::systemEnvironment().isEmpty());
+#endif
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::spaceInName()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+ QProcess process;
+ process.start("test Space In Name/testSpaceInName", QStringList());
+ QVERIFY(process.waitForStarted());
+ process.write("", 1);
+ QVERIFY(process.waitForFinished());
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::lockupsInStartDetached()
+{
+ QHostInfo::lookupHost(QString("something.invalid"), 0, 0);
+ QProcess::execute("yjhbrty");
+ QProcess::startDetached("yjhbrty");
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::atEnd2()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+ process.write("Foo\nBar\nBaz\nBodukon\nHadukan\nTorwukan\nend\n");
+ process.putChar('\0');
+ QVERIFY(process.waitForFinished());
+ QList<QByteArray> lines;
+ while (!process.atEnd()) {
+ lines << process.readLine();
+ }
+ QCOMPARE(lines.size(), 7);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::waitForReadyReadForNonexistantProcess()
+{
+ // This comes from task 108968
+ // Start a program that doesn't exist, process events and then try to waitForReadyRead
+ qRegisterMetaType<QProcess::ProcessError>("QProcess::ProcessError");
+ qRegisterMetaType<QProcess::ExitStatus>("QProcess::ExitStatus");
+
+ QProcess process;
+ QSignalSpy errorSpy(&process, SIGNAL(error(QProcess::ProcessError)));
+ QSignalSpy finishedSpy1(&process, SIGNAL(finished(int)));
+ QSignalSpy finishedSpy2(&process, SIGNAL(finished(int, QProcess::ExitStatus)));
+ QVERIFY(!process.waitForReadyRead()); // used to crash
+ process.start("doesntexist");
+ QVERIFY(!process.waitForReadyRead());
+ QCOMPARE(errorSpy.count(), 1);
+ QCOMPARE(errorSpy.at(0).at(0).toInt(), 0);
+ QCOMPARE(finishedSpy1.count(), 0);
+ QCOMPARE(finishedSpy2.count(), 0);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardInputFile()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ static const char data[] = "A bunch\1of\2data\3\4\5\6\7...";
+ QProcess process;
+ QFile file("data");
+
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write(data, sizeof data);
+ file.close();
+
+ process.setStandardInputFile("data");
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho/testProcessEcho.app");
+#else
+ process.start("testProcessEcho/testProcessEcho");
+#endif
+
+ QPROCESS_VERIFY(process, waitForFinished());
+ QByteArray all = process.readAll();
+ QCOMPARE(all.size(), int(sizeof data) - 1); // testProcessEcho drops the ending \0
+ QVERIFY(all == data);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardOutputFile_data()
+{
+ QTest::addColumn<int>("channelToTest");
+ QTest::addColumn<int>("_channelMode");
+ QTest::addColumn<bool>("append");
+
+ QTest::newRow("stdout-truncate") << int(QProcess::StandardOutput)
+ << int(QProcess::SeparateChannels)
+ << false;
+ QTest::newRow("stdout-append") << int(QProcess::StandardOutput)
+ << int(QProcess::SeparateChannels)
+ << true;
+
+ QTest::newRow("stderr-truncate") << int(QProcess::StandardError)
+ << int(QProcess::SeparateChannels)
+ << false;
+ QTest::newRow("stderr-append") << int(QProcess::StandardError)
+ << int(QProcess::SeparateChannels)
+ << true;
+
+ QTest::newRow("merged-truncate") << int(QProcess::StandardOutput)
+ << int(QProcess::MergedChannels)
+ << false;
+ QTest::newRow("merged-append") << int(QProcess::StandardOutput)
+ << int(QProcess::MergedChannels)
+ << true;
+}
+
+void tst_QProcess::setStandardOutputFile()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ static const char data[] = "Original data. ";
+ static const char testdata[] = "Test data.";
+
+ QFETCH(int, channelToTest);
+ QFETCH(int, _channelMode);
+ QFETCH(bool, append);
+
+ QProcess::ProcessChannelMode channelMode = QProcess::ProcessChannelMode(_channelMode);
+ QIODevice::OpenMode mode = append ? QIODevice::Append : QIODevice::Truncate;
+
+ // create the destination file with data
+ QFile file("data");
+ QVERIFY(file.open(QIODevice::WriteOnly));
+ file.write(data, sizeof data - 1);
+ file.close();
+
+ // run the process
+ QProcess process;
+ process.setReadChannelMode(channelMode);
+ if (channelToTest == QProcess::StandardOutput)
+ process.setStandardOutputFile("data", mode);
+ else
+ process.setStandardErrorFile("data", mode);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+ process.write(testdata, sizeof testdata);
+ QPROCESS_VERIFY(process,waitForFinished());
+
+ // open the file again and verify the data
+ QVERIFY(file.open(QIODevice::ReadOnly));
+ QByteArray all = file.readAll();
+ file.close();
+
+ int expectedsize = sizeof testdata - 1;
+ if (mode == QIODevice::Append) {
+ QVERIFY(all.startsWith(data));
+ expectedsize += sizeof data - 1;
+ }
+ if (channelMode == QProcess::MergedChannels) {
+ expectedsize += sizeof testdata - 1;
+ } else {
+ QVERIFY(all.endsWith(testdata));
+ }
+
+ QCOMPARE(all.size(), expectedsize);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setStandardOutputProcess_data()
+{
+ QTest::addColumn<bool>("merged");
+ QTest::newRow("separate") << false;
+ QTest::newRow("merged") << true;
+}
+
+void tst_QProcess::setStandardOutputProcess()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QProcess source;
+ QProcess sink;
+
+ QFETCH(bool, merged);
+ source.setReadChannelMode(merged ? QProcess::MergedChannels : QProcess::SeparateChannels);
+ source.setStandardOutputProcess(&sink);
+
+#ifdef Q_OS_MAC
+ source.start("testProcessEcho2/testProcessEcho2.app");
+ sink.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ source.start("testProcessEcho2/testProcessEcho2");
+ sink.start("testProcessEcho2/testProcessEcho2");
+#endif
+
+ QByteArray data("Hello, World");
+ source.write(data);
+ source.closeWriteChannel();
+ QPROCESS_VERIFY(source, waitForFinished());
+ QPROCESS_VERIFY(sink, waitForFinished());
+ QByteArray all = sink.readAll();
+
+ if (!merged)
+ QCOMPARE(all, data);
+ else
+ QCOMPARE(all, QByteArray("HHeelllloo,, WWoorrlldd"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::fileWriterProcess()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+
+ QString stdinStr;
+ for (int i = 0; i < 5000; ++i)
+ stdinStr += QString::fromLatin1("%1 -- testing testing 1 2 3\n").arg(i);
+
+ QTime stopWatch;
+ stopWatch.start();
+ do {
+ QFile::remove("fileWriterProcess.txt");
+ QProcess process;
+ process.start("fileWriterProcess/fileWriterProcess",
+ QIODevice::ReadWrite | QIODevice::Text);
+ process.write(stdinStr.toLatin1());
+ process.closeWriteChannel();
+ while (process.bytesToWrite()) {
+ QVERIFY(stopWatch.elapsed() < 3500);
+ QVERIFY(process.waitForBytesWritten(2000));
+ }
+ QVERIFY(process.waitForFinished());
+ QCOMPARE(QFile("fileWriterProcess.txt").size(), qint64(stdinStr.size()));
+ } while (stopWatch.elapsed() < 3000);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::detachedWorkingDirectoryAndPid()
+{
+ qint64 pid;
+
+#ifdef Q_OS_WINCE
+ QTest::qSleep(1000);
+#endif
+
+ QFile infoFile(QDir::currentPath() + QLatin1String("/detachedinfo.txt"));
+ infoFile.remove();
+
+ QString workingDir = QDir::currentPath() + "/testDetached";
+ QVERIFY(QFile::exists(workingDir));
+
+ QStringList args;
+ args << infoFile.fileName();
+ QVERIFY(QProcess::startDetached(QDir::currentPath() + QLatin1String("/testDetached/testDetached"), args, workingDir, &pid));
+
+ QFileInfo fi(infoFile);
+ fi.setCaching(false);
+ while (fi.size() == 0) {
+ QTest::qSleep(100);
+ }
+
+ QVERIFY(infoFile.open(QIODevice::ReadOnly | QIODevice::Text));
+ QString actualWorkingDir = QString::fromUtf8(infoFile.readLine());
+ actualWorkingDir.chop(1); // strip off newline
+ QByteArray processIdString = infoFile.readLine();
+ processIdString.chop(1);
+ infoFile.close();
+ infoFile.remove();
+
+ bool ok = false;
+ qint64 actualPid = processIdString.toLongLong(&ok);
+ QVERIFY(ok);
+
+ QCOMPARE(actualWorkingDir, workingDir);
+ QCOMPARE(actualPid, pid);
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::switchReadChannels()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll);
+#endif
+ const char data[] = "ABCD";
+
+ QProcess process;
+
+#ifdef Q_OS_MAC
+ process.start("testProcessEcho2/testProcessEcho2.app");
+#else
+ process.start("testProcessEcho2/testProcessEcho2");
+#endif
+ process.write(data);
+ process.closeWriteChannel();
+ QVERIFY(process.waitForFinished(5000));
+
+ for (int i = 0; i < 4; ++i) {
+ process.setReadChannel(QProcess::StandardOutput);
+ QCOMPARE(process.read(1), QByteArray(&data[i], 1));
+ process.setReadChannel(QProcess::StandardError);
+ QCOMPARE(process.read(1), QByteArray(&data[i], 1));
+ }
+
+ process.ungetChar('D');
+ process.setReadChannel(QProcess::StandardOutput);
+ process.ungetChar('D');
+ process.setReadChannel(QProcess::StandardError);
+ QCOMPARE(process.read(1), QByteArray("D"));
+ process.setReadChannel(QProcess::StandardOutput);
+ QCOMPARE(process.read(1), QByteArray("D"));
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::setWorkingDirectory()
+{
+#ifdef Q_OS_WINCE
+ QSKIP("Windows CE does not support working directory logic", SkipAll);
+#endif
+ process = new QProcess;
+ process->setWorkingDirectory("test");
+#ifdef Q_OS_MAC
+ process->start("testSetWorkingDirectory/testSetWorkingDirectory.app");
+#else
+ process->start("testSetWorkingDirectory/testSetWorkingDirectory");
+#endif
+#ifndef Q_OS_WIN
+ QSKIP("setWorkingDirectory will chdir before starting the process on unices", SkipAll);
+#endif
+ QVERIFY(process->waitForFinished());
+
+ QByteArray workingDir = process->readAllStandardOutput();
+ QCOMPARE(QDir("test").canonicalPath(), QDir(workingDir.constData()).canonicalPath());
+
+ delete process;
+ process = 0;
+}
+
+//-----------------------------------------------------------------------------
+void tst_QProcess::startFinishStartFinish()
+{
+ QProcess process;
+
+ for (int i = 0; i < 3; ++i) {
+ QCOMPARE(process.state(), QProcess::NotRunning);
+
+#ifdef Q_OS_MAC
+ process.start("testProcessOutput/testProcessOutput.app");
+#else
+ process.start("testProcessOutput/testProcessOutput");
+#endif
+#ifndef Q_OS_WINCE
+ QVERIFY(process.waitForReadyRead(10000));
+ QCOMPARE(QString::fromLatin1(process.readLine().trimmed()),
+ QString("0 -this is a number"));
+#endif
+ if (process.state() != QProcess::NotRunning)
+ QVERIFY(process.waitForFinished(10000));
+ }
+}
+
+QTEST_MAIN(tst_QProcess)
+#include "tst_qprocess.moc"