1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
#include "app.h"
#include <QProcess>
#include <QProcessEnvironment>
#include <QDebug>
App::App(QObject *parent)
: QObject(parent)
, mProcess(new QProcess(this))
, mEnv(new QProcessEnvironment(QProcessEnvironment::systemEnvironment()))
, mPid(0)
{
mProcess->setProcessChannelMode(QProcess::SeparateChannels);
connect(mProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(processError(QProcess::ProcessError)));
connect(mProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(processFinished(int, QProcess::ExitStatus)));
connect(mProcess, SIGNAL(readyReadStandardError()), this, SLOT(processStderr()));
connect(mProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(processStdout()));
connect(mProcess, SIGNAL(started()), this, SLOT(processStarted()));
}
App::~App()
{
delete mEnv;
}
void App::start(const QString &binary, const QStringList &args)
{
stop();
mProcess->setProcessEnvironment(*mEnv);
mProcess->start(binary, args);
}
void App::stop()
{
if (mProcess->state() == QProcess::NotRunning)
return;
mProcess->terminate();
if (!mProcess->waitForFinished()) {
mProcess->kill();
if (!mProcess->waitForFinished()) {
emit error("Could not kill");
}
}
}
void App::debug()
{
emit error("Debugging not implemented.");
}
void App::addEnv(const QString &key, const QString &value)
{
mEnv->insert(key, value);
}
void App::delEnv(const QString &key)
{
mEnv->remove(key);
}
void App::write(const QByteArray &data)
{
if (mProcess->state() == QProcess::Running)
mProcess->write(data);
else
emit error("Could not write input: Process not running.");
}
void App::processError(QProcess::ProcessError err)
{
switch ( err ) {
case QProcess::FailedToStart:
emit error("Process failed to start.");
break;
case QProcess::Crashed:
// no error
// will be handled by: processFinished(...)
break;
case QProcess::Timedout: emit error("Last waitFor... timed out."); break;
case QProcess::WriteError: emit error("Error during write to process."); break;
case QProcess::ReadError: emit error("Error during read from process."); break;
case QProcess::UnknownError: emit error("Process had an unknown error."); break;
}
}
void App::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
if (exitStatus == QProcess::NormalExit) {
qDebug() << "Process exited with exitcode" << exitCode;
} else {
qDebug() << "Process crashed";
}
emit stopped(mPid, exitStatus, exitCode);
}
void App::processStderr()
{
QByteArray out = mProcess->readAllStandardError();
if (!out.isEmpty())
emit stdErr(mPid, out);
}
void App::processStdout()
{
QByteArray out = mProcess->readAllStandardOutput();
if (!out.isEmpty())
emit stdOut(mPid, out);
}
void App::processStarted()
{
mPid = mProcess->pid();
emit started(mPid);
qDebug() << "Process started";
}
|