File indexing completed on 2024-05-12 05:51:07
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 "settings.h" 0008 0009 #include <QTimer> 0010 #include <memory> 0011 0012 #include "dapclient_debug.h" 0013 #include "socketprocessbus.h" 0014 0015 constexpr int TIMEOUT = 1000; 0016 0017 namespace dap 0018 { 0019 SocketProcessBus::SocketProcessBus(QObject *parent) 0020 : Bus(parent) 0021 { 0022 connect(&socket, &QTcpSocket::readyRead, this, &Bus::readyRead); 0023 connect(&socket, &QTcpSocket::stateChanged, this, &SocketProcessBus::onSocketStateChanged); 0024 connect(&process, &QProcess::stateChanged, this, &SocketProcessBus::onProcessStateChanged); 0025 0026 connect(&process, &QProcess::readyReadStandardError, this, &SocketProcessBus::readError); 0027 connect(&process, &QProcess::readyReadStandardOutput, this, &SocketProcessBus::readOutput); 0028 } 0029 0030 SocketProcessBus::~SocketProcessBus() 0031 { 0032 blockSignals(true); 0033 if (socket.state() == QTcpSocket::SocketState::ConnectedState) { 0034 socket.close(); 0035 } 0036 bool finished = process.state() == QProcess::NotRunning; 0037 if (!finished) { 0038 process.terminate(); 0039 finished = process.waitForFinished(500); 0040 } 0041 if (!finished) { 0042 process.kill(); 0043 process.waitForFinished(300); 0044 } 0045 } 0046 0047 QByteArray SocketProcessBus::read() 0048 { 0049 return socket.readAll(); 0050 } 0051 0052 quint16 SocketProcessBus::write(const QByteArray &data) 0053 { 0054 return socket.write(data); 0055 } 0056 0057 bool SocketProcessBus::start(const settings::BusSettings &configuration) 0058 { 0059 if (!configuration.hasConnection() || !configuration.hasCommand()) 0060 return false; 0061 0062 const auto &connection = configuration.connection.value(); 0063 0064 m_connectionHandler.reset(); 0065 m_connectionHandler = [this, connection]() { 0066 this->socket.connectToHost(connection.host, connection.port); 0067 }; 0068 0069 configuration.command->start(process); 0070 0071 return true; 0072 } 0073 0074 void SocketProcessBus::closeResources() 0075 { 0076 qCDebug(DAPCLIENT) << "[BUS] closing resources"; 0077 if (socket.state() == QTcpSocket::SocketState::ConnectedState) { 0078 socket.close(); 0079 } 0080 if (process.state() != QProcess::NotRunning) { 0081 if (m_tryClose == None) { 0082 m_tryClose = Terminate; 0083 process.terminate(); 0084 } else if (m_tryClose == None) { 0085 m_tryClose = Kill; 0086 process.kill(); 0087 } else { 0088 process.waitForFinished(500); 0089 } 0090 } 0091 } 0092 0093 void SocketProcessBus::onSocketStateChanged(const QAbstractSocket::SocketState &state) 0094 { 0095 qCDebug(DAPCLIENT) << "SOCKET STATE " << state; 0096 0097 const bool socketError = socket.error() != QAbstractSocket::SocketError::UnknownSocketError; 0098 if (socketError) 0099 qCDebug(DAPCLIENT) << socket.errorString(); 0100 0101 if (state == QTcpSocket::SocketState::ConnectedState) { 0102 m_connectionHandler.reset(); 0103 setState(State::Running); 0104 return; 0105 } 0106 if (socketError) { 0107 Q_EMIT error(process.errorString()); 0108 close(); 0109 } 0110 } 0111 0112 void SocketProcessBus::onProcessStateChanged(const QProcess::ProcessState &state) 0113 { 0114 qCDebug(DAPCLIENT) << "PROCESS STATE " << state; 0115 0116 const bool processError = process.error() != QProcess::ProcessError::UnknownError; 0117 if (processError) { 0118 Q_EMIT error(process.errorString()); 0119 close(); 0120 return; 0121 } 0122 switch (state) { 0123 case QProcess::ProcessState::Running: 0124 QTimer::singleShot(TIMEOUT, this, &SocketProcessBus::connectSocket); 0125 break; 0126 case QProcess::ProcessState::NotRunning: 0127 close(); 0128 break; 0129 default:; 0130 } 0131 } 0132 0133 void SocketProcessBus::connectSocket() 0134 { 0135 qCDebug(DAPCLIENT) << "connect to socket INIT"; 0136 if (!m_connectionHandler) 0137 return; 0138 qCDebug(DAPCLIENT) << "connect to socket with handler"; 0139 (*m_connectionHandler)(); 0140 } 0141 0142 void SocketProcessBus::close() 0143 { 0144 closeResources(); 0145 setState(State::Closed); 0146 } 0147 0148 void SocketProcessBus::readError() 0149 { 0150 const auto &message = process.readAllStandardError(); 0151 // process' standard error 0152 qCDebug(DAPCLIENT) << "[BUS] STDERR << " << message; 0153 0154 Q_EMIT serverOutput(QString::fromLocal8Bit(message)); 0155 } 0156 0157 void SocketProcessBus::readOutput() 0158 { 0159 const auto &message = process.readAllStandardOutput(); 0160 qCDebug(DAPCLIENT) << "[BUS] STDOUT << " << message; 0161 0162 Q_EMIT processOutput(QString::fromLocal8Bit(message)); 0163 } 0164 0165 } 0166 0167 #include "moc_socketprocessbus.cpp"