diff --git a/src/externalprocess/processjob.cpp b/src/externalprocess/processjob.cpp index 6457ffa..cb24dd8 100644 --- a/src/externalprocess/processjob.cpp +++ b/src/externalprocess/processjob.cpp @@ -1,137 +1,137 @@ /* Copyright 2015 Aleix Pol Gonzalez This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "processjob.h" #include "cmake-paths.h" #include "purpose_external_process_debug.h" #include -#include #include #include #include #include #include #include #include +#include using namespace Purpose; ProcessJob::ProcessJob(const QString &pluginPath, const QString &pluginType, const QJsonObject& data, QObject* parent) : Job(parent) , m_process(new QProcess(this)) , m_pluginPath(pluginPath) , m_pluginType(pluginType) , m_data(data) , m_localSocket(nullptr) { if (QLibrary::isLibrary(pluginPath)) { QString exec = QStandardPaths::findExecutable(QStringLiteral("purposeprocess"), QStringList(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5))); Q_ASSERT(!exec.isEmpty()); m_process->setProgram(exec); } else { Q_ASSERT(QFile::exists(pluginPath)); Q_ASSERT(QFileInfo(pluginPath).permission(QFile::ExeOther | QFile::ExeGroup | QFile::ExeUser)); m_process->setProgram(pluginPath); } m_process->setProcessChannelMode(QProcess::ForwardedChannels); connect(static_cast(m_process), &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { qCWarning(PURPOSE_EXTERNAL_PROCESS_LOG) << "error!" << error; } ); connect(static_cast(m_process), &QProcess::stateChanged, this, &ProcessJob::processStateChanged); m_socket.setMaxPendingConnections(1); m_socket.setSocketOptions(QLocalServer::UserAccessOption); - bool b = m_socket.listen(QStringLiteral("randomname-%1").arg(KRandom::random())); + bool b = m_socket.listen(QStringLiteral("randomname-%1").arg(QRandomGenerator::global()->generate())); Q_ASSERT(b); connect(&m_socket, &QLocalServer::newConnection, this, &ProcessJob::writeSocket); } ProcessJob::~ProcessJob() { m_process->kill(); delete m_process; } void ProcessJob::writeSocket() { m_localSocket = m_socket.nextPendingConnection(); connect(static_cast(m_localSocket), &QIODevice::readyRead, this, &ProcessJob::readSocket); m_socket.removeServer(m_socket.serverName()); const QByteArray data = QCborValue::fromJsonValue(m_data).toCbor(); m_localSocket->write(QByteArray::number(data.size()) + '\n'); const auto ret = m_localSocket->write(data); Q_ASSERT(ret == data.size()); m_localSocket->flush(); } void ProcessJob::readSocket() { QJsonParseError error; while(m_localSocket && m_localSocket->canReadLine()) { const QByteArray json = m_localSocket->readLine(); const QJsonObject object = QJsonDocument::fromJson(json, &error).object(); if (error.error != QJsonParseError::NoError) { qCWarning(PURPOSE_EXTERNAL_PROCESS_LOG) << "error!" << error.errorString() << json; continue; } for(auto it=object.constBegin(), itEnd=object.constEnd(); it!=itEnd; ++it) { const QByteArray propName = it.key().toLatin1(); if (propName == "percent") { setPercent(it->toInt()); } else if (propName == "error") { setError(it->toInt()); } else if (propName == "errorText") { setErrorText(it->toString()); } else if (propName == "output") { setOutput(it->toObject()); } } } } void ProcessJob::start() { m_process->setArguments({ QStringLiteral("--server"), m_socket.fullServerName(), QStringLiteral("--pluginType"), m_pluginType, QStringLiteral("--pluginPath"), m_pluginPath }); qCDebug(PURPOSE_EXTERNAL_PROCESS_LOG) << "launching..." << m_process->program() << m_process->arguments().join(QLatin1Char(' ')).constData(); m_process->start(); } void Purpose::ProcessJob::processStateChanged(QProcess::ProcessState state) { if (state == QProcess::NotRunning) { Q_ASSERT(m_process->exitCode()!=0 || m_localSocket); if (m_process->exitCode()!=0) { qCWarning(PURPOSE_EXTERNAL_PROCESS_LOG) << "process exited with code:" << m_process->exitCode(); } do { readSocket(); } while (m_localSocket->waitForReadyRead()); emitResult(); } }