summaryrefslogtreecommitdiffstats
path: root/app.cpp
blob: 29bd05e28bb0dad52ac99a987fa2ea7059031422 (plain)
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";
}