From 936c44f36781b3969baee6951b949d00d16d0fc5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 8 Apr 2022 17:24:59 +0200 Subject: [PATCH] Introduce ProcessResultData It should be useful when reimplementing ProcessInterface. It replaces 4 virtual methods with just 1. Task-number: QTCREATORBUG-27358 Change-Id: I2dafbfbc25f8f016ff2aa19c1a176335a4a7498c Reviewed-by: hjk --- src/libs/ssh/sshremoteprocess.cpp | 8 +- src/libs/ssh/sshremoteprocess.h | 2 +- src/libs/utils/launchersocket.cpp | 48 ++---- src/libs/utils/launchersocket.h | 11 +- src/libs/utils/processinterface.h | 19 ++- src/libs/utils/qtcprocess.cpp | 154 ++++++++---------- src/libs/utils/qtcprocess.h | 9 +- src/libs/utils/terminalprocess.cpp | 35 +--- src/libs/utils/terminalprocess_p.h | 8 +- .../devicesupport/sshdeviceprocess.cpp | 21 +-- .../devicesupport/sshdeviceprocess.h | 4 +- 11 files changed, 126 insertions(+), 193 deletions(-) diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index 97ca54dcc85..3c98482bbc5 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -29,6 +29,7 @@ #include "sshsettings.h" #include +#include #include #include @@ -80,11 +81,12 @@ void SshRemoteProcess::start() QtcProcess::start(); } -QString SshRemoteProcess::errorString() const +ProcessResultData SshRemoteProcess::resultData() const { + ProcessResultData result = QtcProcess::resultData(); if (!m_errorString.isEmpty()) - return m_errorString; - return QtcProcess::errorString(); + result.m_errorString = m_errorString; + return result; } void SshRemoteProcess::requestX11Forwarding(const QString &displayName) diff --git a/src/libs/ssh/sshremoteprocess.h b/src/libs/ssh/sshremoteprocess.h index 8f80ac1a5a4..305f4859e72 100644 --- a/src/libs/ssh/sshremoteprocess.h +++ b/src/libs/ssh/sshremoteprocess.h @@ -42,7 +42,7 @@ public: void requestX11Forwarding(const QString &displayName); void start() override; - QString errorString() const override; + Utils::ProcessResultData resultData() const override; Utils::CommandLine fullLocalCommandLine(bool inTerminal = false) const; diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index bab0bbe45cb..e6dd83d8bd4 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -204,12 +204,12 @@ void CallerHandle::handleError(const ErrorSignal *launcherSignal) { QTC_ASSERT(isCalledFromCallersThread(), return); m_processState = QProcess::NotRunning; - m_error = launcherSignal->error(); + m_result.m_error = launcherSignal->error(); if (!launcherSignal->errorString().isEmpty()) - m_errorString = launcherSignal->errorString(); - if (m_error == QProcess::FailedToStart) - m_exitCode = 255; // This code is being returned by QProcess when FailedToStart error occurred - emit errorOccurred(m_error); + m_result.m_errorString = launcherSignal->errorString(); + if (m_result.m_error == QProcess::FailedToStart) + m_result.m_exitCode = 255; // This code is being returned by QProcess when FailedToStart error occurred + emit errorOccurred(m_result.m_error); } void CallerHandle::handleStarted(const StartedSignal *launcherSignal) @@ -252,8 +252,8 @@ void CallerHandle::handleFinished(const FinishedSignal *launcherSignal) { QTC_ASSERT(isCalledFromCallersThread(), return); m_processState = QProcess::NotRunning; - m_exitStatus = launcherSignal->exitStatus(); - m_exitCode = launcherSignal->exitCode(); + m_result.m_exitStatus = launcherSignal->exitStatus(); + m_result.m_exitCode = launcherSignal->exitCode(); emit finished(); } @@ -315,13 +315,13 @@ void CallerHandle::cancel() case QProcess::NotRunning: break; case QProcess::Starting: - m_errorString = QCoreApplication::translate("Utils::LauncherHandle", + m_result.m_errorString = QCoreApplication::translate("Utils::LauncherHandle", "Process was canceled before it was started."); - m_error = QProcess::FailedToStart; + m_result.m_error = QProcess::FailedToStart; if (LauncherInterface::isReady()) // TODO: race condition with m_processState??? sendPacket(StopProcessPacket(m_token)); else - emit errorOccurred(m_error); + emit errorOccurred(m_result.m_error); break; case QProcess::Running: sendPacket(StopProcessPacket(m_token)); @@ -347,30 +347,24 @@ qint64 CallerHandle::processId() const return m_processId; } -int CallerHandle::exitCode() const -{ - QTC_ASSERT(isCalledFromCallersThread(), return -1); - return m_exitCode; -} - -QString CallerHandle::errorString() const +ProcessResultData CallerHandle::resultData() const { QTC_ASSERT(isCalledFromCallersThread(), return {}); - return m_errorString; + return m_result; } void CallerHandle::setErrorString(const QString &str) { QTC_ASSERT(isCalledFromCallersThread(), return); - m_errorString = str; + m_result.m_errorString = str; } void CallerHandle::start(const QString &program, const QStringList &arguments) { QTC_ASSERT(isCalledFromCallersThread(), return); if (!m_launcherHandle || m_launcherHandle->isSocketError()) { - m_error = QProcess::FailedToStart; - emit errorOccurred(m_error); + m_result.m_error = QProcess::FailedToStart; + emit errorOccurred(m_result.m_error); return; } @@ -444,12 +438,6 @@ qint64 CallerHandle::write(const QByteArray &data) return data.size(); } -QProcess::ProcessError CallerHandle::error() const -{ - QTC_ASSERT(isCalledFromCallersThread(), return QProcess::UnknownError); - return m_error; -} - QString CallerHandle::program() const { QMutexLocker locker(&m_mutex); @@ -468,12 +456,6 @@ void CallerHandle::setProcessSetupData(const ProcessSetupData::Ptr &setup) m_setup = setup; } -QProcess::ExitStatus CallerHandle::exitStatus() const -{ - QTC_ASSERT(isCalledFromCallersThread(), return QProcess::CrashExit); - return m_exitStatus; -} - bool CallerHandle::waitForSignal(int msecs, SignalType newSignal) { QTC_ASSERT(isCalledFromCallersThread(), return false); diff --git a/src/libs/utils/launchersocket.h b/src/libs/utils/launchersocket.h index 3e147019735..4696c516fbc 100644 --- a/src/libs/utils/launchersocket.h +++ b/src/libs/utils/launchersocket.h @@ -96,8 +96,8 @@ public: QByteArray readAllStandardError(); qint64 processId() const; - int exitCode() const; - QString errorString() const; + ProcessResultData resultData() const; + void setErrorString(const QString &str); void start(const QString &program, const QStringList &arguments); @@ -106,13 +106,11 @@ public: qint64 write(const QByteArray &data); - QProcess::ProcessError error() const; // Called from caller's or launcher's thread. QString program() const; // Called from caller's or launcher's thread. QStringList arguments() const; void setProcessSetupData(const ProcessSetupData::Ptr &setup); - QProcess::ExitStatus exitStatus() const; signals: void errorOccurred(QProcess::ProcessError error); @@ -159,12 +157,9 @@ private: std::atomic m_processState = QProcess::NotRunning; std::unique_ptr m_startPacket; int m_processId = 0; - int m_exitCode = 0; - QProcess::ExitStatus m_exitStatus = QProcess::ExitStatus::NormalExit; QByteArray m_stdout; QByteArray m_stderr; - QProcess::ProcessError m_error = QProcess::UnknownError; - QString m_errorString; + ProcessResultData m_result; QString m_command; QStringList m_arguments; diff --git a/src/libs/utils/processinterface.h b/src/libs/utils/processinterface.h index f6f2cb9ec6e..3f3f11ab2d2 100644 --- a/src/libs/utils/processinterface.h +++ b/src/libs/utils/processinterface.h @@ -63,6 +63,15 @@ public: bool m_belowNormalPriority = false; // internal, dependent on other fields and specific code path }; +class QTCREATOR_UTILS_EXPORT ProcessResultData +{ +public: + int m_exitCode = 0; + QProcess::ExitStatus m_exitStatus = QProcess::NormalExit; + QProcess::ProcessError m_error = QProcess::UnknownError; + QString m_errorString; +}; + class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject { Q_OBJECT @@ -83,11 +92,8 @@ public: virtual qint64 processId() const = 0; virtual QProcess::ProcessState state() const = 0; - virtual int exitCode() const = 0; - virtual QProcess::ExitStatus exitStatus() const = 0; - virtual QProcess::ProcessError error() const = 0; - virtual QString errorString() const = 0; + virtual ProcessResultData resultData() const = 0; virtual bool waitForStarted(int msecs) = 0; virtual bool waitForReadyRead(int msecs) = 0; @@ -140,11 +146,8 @@ public: qint64 processId() const override { return m_target->processId(); } QProcess::ProcessState state() const override { return m_target->state(); } - int exitCode() const override { return m_target->exitCode(); } - QProcess::ExitStatus exitStatus() const override { return m_target->exitStatus(); } - QProcess::ProcessError error() const override { return m_target->error(); } - QString errorString() const override { return m_target->errorString(); } + ProcessResultData resultData() const override { return m_target->resultData(); }; bool waitForStarted(int msecs) override { return m_target->waitForStarted(msecs); } bool waitForReadyRead(int msecs) override { return m_target->waitForReadyRead(msecs); } diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 3caf109358b..1b794286fa2 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -215,7 +215,7 @@ public: class DefaultImpl : public ProcessInterface { public: - virtual void start() { defaultStart(); } + virtual void start() final { defaultStart(); } protected: void defaultStart(); @@ -325,7 +325,7 @@ bool DefaultImpl::ensureProgramExists(const QString &program) return false; } -class QProcessImpl : public DefaultImpl +class QProcessImpl final : public DefaultImpl { public: QProcessImpl() : m_process(new ProcessHelper(this)) @@ -341,49 +341,32 @@ public: connect(m_process, &QProcess::readyReadStandardError, this, &ProcessInterface::readyReadStandardError); } - ~QProcessImpl() override - { - ProcessReaper::reap(m_process); - } + ~QProcessImpl() final { ProcessReaper::reap(m_process); } - QByteArray readAllStandardOutput() override { return m_process->readAllStandardOutput(); } - QByteArray readAllStandardError() override { return m_process->readAllStandardError(); } + QByteArray readAllStandardOutput() final { return m_process->readAllStandardOutput(); } + QByteArray readAllStandardError() final { return m_process->readAllStandardError(); } - void interrupt() override - { ProcessHelper::interruptProcess(m_process); } - void terminate() override - { ProcessHelper::terminateProcess(m_process); } - void kill() override - { m_process->kill(); } - void close() override - { m_process->close(); } - qint64 write(const QByteArray &data) override - { return m_process->write(data); } + void interrupt() final { ProcessHelper::interruptProcess(m_process); } + void terminate() final { ProcessHelper::terminateProcess(m_process); } + void kill() final { m_process->kill(); } + void close() final { m_process->close(); } + qint64 write(const QByteArray &data) final { return m_process->write(data); } - QProcess::ProcessError error() const override - { return m_process->error(); } - QProcess::ProcessState state() const override - { return m_process->state(); } - qint64 processId() const override - { return m_process->processId(); } - int exitCode() const override - { return m_process->exitCode(); } - QProcess::ExitStatus exitStatus() const override - { return m_process->exitStatus(); } - QString errorString() const override - { return m_process->errorString(); } - void setErrorString(const QString &str) override - { m_process->setErrorString(str); } + ProcessResultData resultData() const final { + return { m_process->exitCode(), m_process->exitStatus(), + m_process->error(), m_process->errorString() }; + }; + void setErrorString(const QString &str) final { m_process->setErrorString(str); } - bool waitForStarted(int msecs) override - { return m_process->waitForStarted(msecs); } - bool waitForReadyRead(int msecs) override - { return m_process->waitForReadyRead(msecs); } - bool waitForFinished(int msecs) override - { return m_process->waitForFinished(msecs); } + QProcess::ProcessState state() const final { return m_process->state(); } + qint64 processId() const final { return m_process->processId(); } + + bool waitForStarted(int msecs) final { return m_process->waitForStarted(msecs); } + bool waitForReadyRead(int msecs) final { return m_process->waitForReadyRead(msecs); } + bool waitForFinished(int msecs) final { return m_process->waitForFinished(msecs); } private: - void doDefaultStart(const QString &program, const QStringList &arguments) override + void doDefaultStart(const QString &program, const QStringList &arguments) final { ProcessStartHandler *handler = m_process->processStartHandler(); handler->setProcessMode(m_setup->m_processMode); @@ -418,7 +401,7 @@ static uint uniqueToken() return ++globalUniqueToken; } -class ProcessLauncherImpl : public DefaultImpl +class ProcessLauncherImpl final : public DefaultImpl { Q_OBJECT public: @@ -437,40 +420,38 @@ public: connect(m_handle, &CallerHandle::readyReadStandardError, this, &ProcessInterface::readyReadStandardError); } - ~ProcessLauncherImpl() override + ~ProcessLauncherImpl() final { cancel(); LauncherInterface::unregisterHandle(token()); m_handle = nullptr; } - QByteArray readAllStandardOutput() override { return m_handle->readAllStandardOutput(); } - QByteArray readAllStandardError() override { return m_handle->readAllStandardError(); } + QByteArray readAllStandardOutput() final { return m_handle->readAllStandardOutput(); } + QByteArray readAllStandardError() final { return m_handle->readAllStandardError(); } - void interrupt() override + void interrupt() final { if (m_setup->m_useCtrlCStub) // bypass launcher and interrupt directly ProcessHelper::interruptPid(processId()); } - void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close? - void kill() override { cancel(); } // TODO: see above - void close() override { cancel(); } // TODO: see above - qint64 write(const QByteArray &data) override { return m_handle->write(data); } + void terminate() final { cancel(); } // TODO: what are differences among terminate, kill and close? + void kill() final { cancel(); } // TODO: see above + void close() final { cancel(); } // TODO: see above + qint64 write(const QByteArray &data) final { return m_handle->write(data); } - QProcess::ProcessError error() const override { return m_handle->error(); } - QProcess::ProcessState state() const override { return m_handle->state(); } - qint64 processId() const override { return m_handle->processId(); } - int exitCode() const override { return m_handle->exitCode(); } - QProcess::ExitStatus exitStatus() const override { return m_handle->exitStatus(); } - QString errorString() const override { return m_handle->errorString(); } - void setErrorString(const QString &str) override { m_handle->setErrorString(str); } + ProcessResultData resultData() const final { return m_handle->resultData(); }; + void setErrorString(const QString &str) final { m_handle->setErrorString(str); } - bool waitForStarted(int msecs) override { return m_handle->waitForStarted(msecs); } - bool waitForReadyRead(int msecs) override { return m_handle->waitForReadyRead(msecs); } - bool waitForFinished(int msecs) override { return m_handle->waitForFinished(msecs); } + QProcess::ProcessState state() const final { return m_handle->state(); } + qint64 processId() const final { return m_handle->processId(); } + + bool waitForStarted(int msecs) final { return m_handle->waitForStarted(msecs); } + bool waitForReadyRead(int msecs) final { return m_handle->waitForReadyRead(msecs); } + bool waitForFinished(int msecs) final { return m_handle->waitForFinished(msecs); } private: - void doDefaultStart(const QString &program, const QStringList &arguments) override + void doDefaultStart(const QString &program, const QStringList &arguments) final { m_handle->start(program, arguments); } @@ -1052,15 +1033,35 @@ void QtcProcess::setResult(const ProcessResult &result) d->m_result = result; } -int QtcProcess::exitCode() const +ProcessResultData QtcProcess::resultData() const { + const ProcessResultData result = d->m_process ? d->m_process->resultData() + : ProcessResultData(); + // This code (255) is being returned by QProcess when FailedToStart error occurred if (d->m_startFailure == QtcProcessPrivate::WrongCommandFailure) - return 255; // This code is being returned by QProcess when FailedToStart error occurred - if (d->m_process) - return d->m_process->exitCode(); - return 0; + return { 255, result.m_exitStatus, QProcess::FailedToStart, result.m_errorString }; + return result; } +int QtcProcess::exitCode() const +{ + return resultData().m_exitCode; +} + +QProcess::ExitStatus QtcProcess::exitStatus() const +{ + return resultData().m_exitStatus; +} + +QProcess::ProcessError QtcProcess::error() const +{ + return resultData().m_error; +} + +QString QtcProcess::errorString() const +{ + return resultData().m_errorString; +} // Path utilities @@ -1169,15 +1170,6 @@ void QtcProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode) d->m_setup.m_processChannelMode = mode; } -QProcess::ProcessError QtcProcess::error() const -{ - if (d->m_startFailure == QtcProcessPrivate::WrongCommandFailure) - return QProcess::FailedToStart; - if (d->m_process) - return d->m_process->error(); - return QProcess::UnknownError; -} - QProcess::ProcessState QtcProcess::state() const { if (d->m_process) @@ -1190,13 +1182,6 @@ bool QtcProcess::isRunning() const return state() == QProcess::Running; } -QString QtcProcess::errorString() const -{ - if (d->m_process) - return d->m_process->errorString(); - return {}; -} - qint64 QtcProcess::processId() const { if (d->m_process) @@ -1236,13 +1221,6 @@ QByteArray QtcProcess::readAllStandardError() return buf; } -QProcess::ExitStatus QtcProcess::exitStatus() const -{ - if (d->m_process) - return d->m_process->exitStatus(); - return QProcess::NormalExit; -} - void QtcProcess::kill() { if (d->m_process) @@ -1621,7 +1599,7 @@ void QtcProcessPrivate::slotTimeout() void QtcProcessPrivate::slotFinished() { - handleFinished(m_process->exitCode(), m_process->exitStatus()); + handleFinished(m_process->resultData().m_exitCode, m_process->resultData().m_exitStatus); emitFinished(); } diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index cb019ef6b16..f4d26ee88e9 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -47,6 +47,7 @@ namespace Internal { class QtcProcessPrivate; } class DeviceProcessHooks; class ProcessInterface; +class ProcessResultData; class QTCREATOR_UTILS_EXPORT QtcProcess : public QObject { @@ -70,11 +71,13 @@ public: virtual qint64 processId() const; virtual QProcess::ProcessState state() const; - virtual int exitCode() const; - virtual QProcess::ExitStatus exitStatus() const; + virtual ProcessResultData resultData() const; + + int exitCode() const; + QProcess::ExitStatus exitStatus() const; QProcess::ProcessError error() const; - virtual QString errorString() const; + QString errorString() const; bool waitForStarted(int msecs = 30000); bool waitForReadyRead(int msecs = 30000); diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index 8869c11895e..7472be8f3e9 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -127,13 +127,10 @@ public: : m_process(parent) {} qint64 m_processId = 0; - int m_exitCode = 0; - QProcess::ExitStatus m_appStatus = QProcess::NormalExit; + ProcessResultData m_result; QLocalServer m_stubServer; QLocalSocket *m_stubSocket = nullptr; QTemporaryFile *m_tempFile = nullptr; - QProcess::ProcessError m_error = QProcess::UnknownError; - QString m_errorString; // Used on Unix only QtcProcess m_process; @@ -178,8 +175,7 @@ void TerminalImpl::start() if (isRunning()) return; - d->m_errorString.clear(); - d->m_error = QProcess::UnknownError; + d->m_result = {}; #ifdef Q_OS_WIN @@ -449,8 +445,8 @@ void TerminalImpl::cleanupAfterStartFailure(const QString &errorMessage) void TerminalImpl::finish(int exitCode, QProcess::ExitStatus exitStatus) { d->m_processId = 0; - d->m_exitCode = exitCode; - d->m_appStatus = exitStatus; + d->m_result.m_exitCode = exitCode; + d->m_result.m_exitStatus = exitStatus; emit finished(); } @@ -745,30 +741,15 @@ qint64 TerminalImpl::processId() const return d->m_processId; } -int TerminalImpl::exitCode() const +ProcessResultData TerminalImpl::resultData() const { - return d->m_exitCode; -} // This will be the signal number if exitStatus == CrashExit - -QProcess::ExitStatus TerminalImpl::exitStatus() const -{ - return d->m_appStatus; -} - -QProcess::ProcessError TerminalImpl::error() const -{ - return d->m_error; -} - -QString TerminalImpl::errorString() const -{ - return d->m_errorString; + return d->m_result; } void TerminalImpl::emitError(QProcess::ProcessError err, const QString &errorString) { - d->m_error = err; - d->m_errorString = errorString; + d->m_result.m_error = err; + d->m_result.m_errorString = errorString; emit errorOccurred(err); } diff --git a/src/libs/utils/terminalprocess_p.h b/src/libs/utils/terminalprocess_p.h index e30c8651c86..264e554d2db 100644 --- a/src/libs/utils/terminalprocess_p.h +++ b/src/libs/utils/terminalprocess_p.h @@ -39,7 +39,7 @@ class FilePath; namespace Internal { -class TerminalImpl : public ProcessInterface +class TerminalImpl final : public ProcessInterface { public: TerminalImpl(); @@ -60,15 +60,11 @@ public: // intentionally no-op without an assert bool waitForFinished(int) final { return false; } - QProcess::ProcessError error() const final; - QString errorString() const final; - void start() final; QProcess::ProcessState state() const final; qint64 processId() const final; - int exitCode() const final; - QProcess::ExitStatus exitStatus() const final; + ProcessResultData resultData() const final; void kickoffProcess() final; // only debugger terminal, only non-windows void interrupt() final; // only debugger terminal, only non-windows diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp index ab8e822868d..6b7ff6612c3 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -155,20 +156,14 @@ QProcess::ProcessState SshDeviceProcess::state() const } } -QProcess::ExitStatus SshDeviceProcess::exitStatus() const +ProcessResultData SshDeviceProcess::resultData() const { - return d->exitStatus == QProcess::NormalExit && exitCode() != 255 - ? QProcess::NormalExit : QProcess::CrashExit; -} - -int SshDeviceProcess::exitCode() const -{ - return usesTerminal() ? QtcProcess::exitCode() : d->remoteProcess->exitCode(); -} - -QString SshDeviceProcess::errorString() const -{ - return d->errorMessage; + const ProcessResultData result = QtcProcess::resultData(); + return { usesTerminal() ? result.m_exitCode : d->remoteProcess->exitCode(), + d->exitStatus == QProcess::NormalExit && result.m_exitCode != 255 + ? QProcess::NormalExit : QProcess::CrashExit, + result.m_error, + d->errorMessage }; } QByteArray SshDeviceProcess::readAllStandardOutput() diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.h b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.h index ebf6b53397d..9d0db52694c 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.h +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.h @@ -48,9 +48,7 @@ public: void kill() override; QProcess::ProcessState state() const override; - QProcess::ExitStatus exitStatus() const override; - int exitCode() const override; - QString errorString() const override; + Utils::ProcessResultData resultData() const override; QByteArray readAllStandardOutput() override; QByteArray readAllStandardError() override;