File indexing completed on 2024-05-12 05:51:06

0001 /*
0002     SPDX-FileCopyrightText: 2022 Héctor Mesa Jiménez <wmj.py@gmx.com>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <QString>
0008 
0009 #include "dapclient_debug.h"
0010 #include "processbus.h"
0011 #include "settings.h"
0012 
0013 namespace dap
0014 {
0015 ProcessBus::ProcessBus(QObject *parent)
0016     : Bus(parent)
0017 {
0018     // IO
0019     connect(&process, &QProcess::readyReadStandardOutput, this, &Bus::readyRead);
0020     connect(&process, &QProcess::stateChanged, this, &ProcessBus::onStateChanged);
0021 
0022     // state/error
0023     connect(&process, &QProcess::errorOccurred, this, &ProcessBus::onError);
0024     connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &ProcessBus::onFinished);
0025     connect(&process, &QProcess::readyReadStandardError, this, &ProcessBus::readError);
0026 }
0027 
0028 ProcessBus::~ProcessBus()
0029 {
0030     blockSignals(true);
0031     bool finished = process.state() == QProcess::NotRunning;
0032     if (!finished) {
0033         process.terminate();
0034         finished = process.waitForFinished(500);
0035     }
0036     if (!finished) {
0037         process.kill();
0038         process.waitForFinished(300);
0039     }
0040 }
0041 
0042 QByteArray ProcessBus::read()
0043 {
0044     return process.readAllStandardOutput();
0045 }
0046 
0047 quint16 ProcessBus::write(const QByteArray &data)
0048 {
0049     return process.write(data);
0050 }
0051 
0052 bool ProcessBus::start(const settings::BusSettings &configuration)
0053 {
0054     if (!configuration.hasCommand())
0055         return false;
0056 
0057     configuration.command->start(process);
0058 
0059     return true;
0060 }
0061 
0062 void ProcessBus::close()
0063 {
0064     if (process.state() != QProcess::NotRunning) {
0065         if (m_tryClose == None) {
0066             m_tryClose = Terminate;
0067             process.terminate();
0068         } else if (m_tryClose == None) {
0069             m_tryClose = Kill;
0070             process.kill();
0071         } else {
0072             process.waitForFinished(500);
0073         }
0074     }
0075     setState(State::Closed);
0076 }
0077 
0078 void ProcessBus::onStateChanged(QProcess::ProcessState state)
0079 {
0080     // starting
0081     //  running
0082     //    notrunning
0083     //  notrunning
0084 
0085     switch (state) {
0086     case QProcess::ProcessState::NotRunning:
0087         setState(State::Closed);
0088         break;
0089     case QProcess::ProcessState::Running:
0090         setState(State::Running);
0091         break;
0092     default:;
0093     }
0094 }
0095 
0096 void ProcessBus::onError(QProcess::ProcessError processError)
0097 {
0098     qCWarning(DAPCLIENT) << "PROCESS ERROR: " << processError << " (" << process.errorString() << ")";
0099     Q_EMIT error(process.errorString());
0100 }
0101 
0102 void ProcessBus::onFinished(int exitCode, QProcess::ExitStatus exitStatus)
0103 {
0104     if (exitStatus == QProcess::ExitStatus::CrashExit) {
0105         qCWarning(DAPCLIENT) << "ABNORMAL PROCESS EXIT: code " << exitCode;
0106         Q_EMIT error(QStringLiteral("process exited with code %1").arg(exitCode));
0107     }
0108 }
0109 
0110 void ProcessBus::readError()
0111 {
0112     const auto &message = process.readAllStandardError();
0113     // process' standard error
0114     qCDebug(DAPCLIENT) << "[BUS] STDERR << " << message;
0115 
0116     Q_EMIT serverOutput(QString::fromLocal8Bit(message));
0117 }
0118 
0119 }
0120 
0121 #include "moc_processbus.cpp"