diff --git a/UpdatePTUDevCtrl/process/command.cpp b/UpdatePTUDevCtrl/process/command.cpp index 0b06e7e..9687ccb 100644 --- a/UpdatePTUDevCtrl/process/command.cpp +++ b/UpdatePTUDevCtrl/process/command.cpp @@ -120,106 +120,156 @@ bool Command::start(QString workingDirectory, QStringList args) { return m_p->waitForStarted(m_waitForStartTimeout); } -bool Command::execute(QString workingDirectory, QStringList args) { - +bool Command::execute(QString workingDirectory, QStringList args) +{ if (!QDir::setCurrent(workingDirectory)) { - qCritical() << "SET WORKING_DIRECTORY" << workingDirectory - << "FAILED FOR" << m_command; + qCritical() << "SET WORKING_DIRECTORY" + << workingDirectory + << "FAILED FOR" + << m_command; return false; } QScopedPointer p(new QProcess(this)); + p->setWorkingDirectory(workingDirectory); p->setProcessChannelMode(QProcess::MergedChannels); - connect(&(*p), SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput())); - connect(&(*p), SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError())); + connect(p.data(), + SIGNAL(readyReadStandardOutput()), + this, + SLOT(readyReadStandardOutput())); + + connect(p.data(), + SIGNAL(readyReadStandardError()), + this, + SLOT(readyReadStandardError())); if (!args.isEmpty()) { - //qDebug() << "START COMMAND" << m_command << "WITH ARGS" << args - // << "IN" << p->workingDirectory(); p->start(m_command, args); - } else { - //qDebug() << "START COMMAND" << m_command - // << "IN" << p->workingDirectory(); + } + else { p->start(m_command); } - qint64 const start = QDateTime::currentDateTime().toMSecsSinceEpoch(); + const qint64 start = + QDateTime::currentDateTime().toMSecsSinceEpoch(); - if (p->waitForStarted(m_waitForStartTimeout)) { - // qDebug() << "PROCESS" << m_command << "STARTED IN" << p->workingDirectory(); - if (p->state() == QProcess::ProcessState::Running) { - // qDebug() << "PROCESS" << m_command << "RUNNING IN" << p->workingDirectory(); - // wait forever for git/opkg-commands to finish ------------------- wait for 30 min max! - int wait = m_waitForFinishTimeout; - if (m_command.trimmed().startsWith("git", Qt::CaseInsensitive) || - m_command.trimmed().startsWith("opkg", Qt::CaseInsensitive)) { - wait = 30 * 60 * 1000; - } + if (!p->waitForStarted(m_waitForStartTimeout)) { - if (!p->waitForFinished(wait)) { - qCritical() << "PROCESS TIMEOUT:" << m_command; + const qint64 end = + QDateTime::currentDateTime().toMSecsSinceEpoch(); - p->terminate(); + qCritical() << "PROCESS" + << m_command + << "TIMEOUT AT START" + << QString("(runtime %1ms)").arg(end - start) + << "IN" + << p->workingDirectory(); + + return false; + } + + if (p->state() != QProcess::Running) { + + qCritical() << "WRONG PROCESS STATE" + << p->state() + << "IN" + << p->workingDirectory(); + + return false; + } + + int wait = m_waitForFinishTimeout; + + if (m_command.trimmed().startsWith("git", Qt::CaseInsensitive) || + m_command.trimmed().startsWith("opkg", Qt::CaseInsensitive)) { + + wait = 30 * 60 * 1000; + } + + // IMPORTANT: waitForFinished() is called exactly once. + const bool finished = p->waitForFinished(wait); + + if (!finished) { + + const qint64 end = + QDateTime::currentDateTime().toMSecsSinceEpoch(); + + qCritical() << "PROCESS WAIT FAILED:" + << m_command + << "timeout =" << wait + << "runtime =" << (end - start) + << "error =" << p->error() + << "errorString =" << p->errorString() + << "state =" << p->state(); + + if (p->state() != QProcess::NotRunning) { + + p->terminate(); + + if (!p->waitForFinished(5000)) { + + qCritical() + << "Process did not terminate, killing:" + << m_command; + + p->kill(); if (!p->waitForFinished(5000)) { - qCritical() << "Process did not terminate, killing:" - << m_command; - - p->kill(); - - if (!p->waitForFinished(5000)) { - qCritical() << "ERROR: Process still did not finish after kill:" - << m_command; - } + qCritical() + << "ERROR: Process still did not finish after kill:" + << m_command; } - - m_exitCode = -1; - return false; } - - bool const no_timeout = p->waitForFinished(wait); - if (no_timeout) { - // qDebug() << "PROCESS" << m_command << "FINISHED IN" << p->workingDirectory(); - if (p->exitStatus() == QProcess::NormalExit) { - if ((m_exitCode = p->exitCode()) == 0) { - qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); - qDebug() << "EXECUTED" << m_command - << QString("(runtime %1ms)").arg(end-start) - << "with code" << m_exitCode - << "IN" << p->workingDirectory(); - return true; - } else { - qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); - qCritical() << "EXECUTED" << m_command - << QString("(runtime %1ms)").arg(end-start) - << "with code" << m_exitCode - << "IN" << p->workingDirectory(); - } - } else { - qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); - qCritical() << "PROCESS" << m_command << "CRASHED with code" - << p->exitCode() - << QString("(after %1ms)").arg(end-start) - << "IN" << p->workingDirectory(); - } - } else { - qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); - qCritical() << "PROCESS" << m_command - << "DID NOT FINISH WITH" << wait - << "MS IN" << p->workingDirectory() - << QString("(runtime %1ms)").arg(end-start); - } - } else { - qCritical() << "WRONG PROCESS STATE" << p->state() - << "IN" << p->workingDirectory(); } - } else { - qint64 const end = QDateTime::currentDateTime().toMSecsSinceEpoch(); - qCritical() << "PROCESS" << m_command << "TIMEOUT AT START" - << QString("(runtime %1ms)").arg(end-start) - << "IN" << p->workingDirectory(); + + m_exitCode = -1; + return false; } - return false; + + // From here onward the process has definitely finished. + + const qint64 end = + QDateTime::currentDateTime().toMSecsSinceEpoch(); + + if (p->exitStatus() != QProcess::NormalExit) { + + m_exitCode = p->exitCode(); + + qCritical() << "PROCESS" + << m_command + << "CRASHED with code" + << m_exitCode + << QString("(after %1ms)").arg(end - start) + << "IN" + << p->workingDirectory(); + + return false; + } + + m_exitCode = p->exitCode(); + + if (m_exitCode != 0) { + + qCritical() << "EXECUTED" + << m_command + << QString("(runtime %1ms)").arg(end - start) + << "with code" + << m_exitCode + << "IN" + << p->workingDirectory(); + + return false; + } + + qDebug() << "EXECUTED" + << m_command + << QString("(runtime %1ms)").arg(end - start) + << "with code" + << m_exitCode + << "IN" + << p->workingDirectory(); + + return true; }