diff --git a/src/libs/utils/processinterface.h b/src/libs/utils/processinterface.h index 7bceff4af0d..838215f7f75 100644 --- a/src/libs/utils/processinterface.h +++ b/src/libs/utils/processinterface.h @@ -71,6 +71,13 @@ public: QString m_errorString; }; +enum class ControlSignal { + Terminate, + Kill, + Interrupt, + KickOff +}; + class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject { Q_OBJECT @@ -80,11 +87,8 @@ public: ProcessInterface(ProcessSetupData::Ptr setup) : m_setup(setup) {} virtual void start() = 0; - virtual void interrupt() = 0; - virtual void terminate() = 0; - virtual void kill() = 0; - virtual qint64 write(const QByteArray &data) = 0; + virtual void sendControlSignal(ControlSignal controlSignal) = 0; virtual QProcess::ProcessState state() const = 0; @@ -92,8 +96,6 @@ public: virtual bool waitForReadyRead(int msecs) = 0; virtual bool waitForFinished(int msecs) = 0; - virtual void kickoffProcess(); - signals: void started(qint64 processId, qint64 applicationMainThreadId = 0); void readyRead(const QByteArray &outputData, const QByteArray &errorData); @@ -121,9 +123,6 @@ public: } void start() override { m_target->start(); } - void interrupt() override { m_target->interrupt(); } - void terminate() override { m_target->terminate(); } - void kill() override { m_target->kill(); } qint64 write(const QByteArray &data) override { return m_target->write(data); } @@ -133,8 +132,6 @@ public: bool waitForReadyRead(int msecs) override { return m_target->waitForReadyRead(msecs); } bool waitForFinished(int msecs) override { return m_target->waitForFinished(msecs); } - void kickoffProcess() override { m_target->kickoffProcess(); } - protected: ProcessInterface *m_target; }; diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 0dbf3e08f1a..36758d74c63 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -347,10 +347,23 @@ public: } ~QProcessImpl() final { ProcessReaper::reap(m_process); } - void interrupt() final { ProcessHelper::interruptProcess(m_process); } - void terminate() final { ProcessHelper::terminateProcess(m_process); } - void kill() final { m_process->kill(); } qint64 write(const QByteArray &data) final { return m_process->write(data); } + void sendControlSignal(ControlSignal controlSignal) final { + switch (controlSignal) { + case ControlSignal::Terminate: + ProcessHelper::terminateProcess(m_process); + break; + case ControlSignal::Kill: + m_process->kill(); + break; + case ControlSignal::Interrupt: + ProcessHelper::interruptProcess(m_process); + break; + case ControlSignal::KickOff: + QTC_CHECK(false); + break; + } + } QProcess::ProcessState state() const final { return m_process->state(); } @@ -432,14 +445,24 @@ public: m_handle = nullptr; } - void interrupt() final - { - if (m_setup->m_useCtrlCStub) // bypass launcher and interrupt directly - ProcessHelper::interruptPid(m_handle->processId()); - } - void terminate() final { m_handle->terminate(); } - void kill() final { m_handle->kill(); } qint64 write(const QByteArray &data) final { return m_handle->write(data); } + void sendControlSignal(ControlSignal controlSignal) final { + switch (controlSignal) { + case ControlSignal::Terminate: + m_handle->terminate(); + break; + case ControlSignal::Kill: + m_handle->kill(); + break; + case ControlSignal::Interrupt: + if (m_setup->m_useCtrlCStub) // bypass launcher and interrupt directly + ProcessHelper::interruptPid(m_handle->processId()); + break; + case ControlSignal::KickOff: + QTC_CHECK(false); + break; + } + } QProcess::ProcessState state() const final { return m_handle->state(); } @@ -599,11 +622,6 @@ ProcessResult QtcProcessPrivate::interpretExitCode(int exitCode) } // Internal -void ProcessInterface::kickoffProcess() -{ - QTC_CHECK(false); -} - /*! \class Utils::QtcProcess @@ -805,13 +823,25 @@ void QtcProcess::start() void QtcProcess::terminate() { if (d->m_process) - d->m_process->terminate(); + d->m_process->sendControlSignal(ControlSignal::Terminate); +} + +void QtcProcess::kill() +{ + if (d->m_process) + d->m_process->sendControlSignal(ControlSignal::Kill); } void QtcProcess::interrupt() { if (d->m_process) - d->m_process->interrupt(); + d->m_process->sendControlSignal(ControlSignal::Interrupt); +} + +void QtcProcess::kickoffProcess() +{ + if (d->m_process) + d->m_process->sendControlSignal(ControlSignal::KickOff); } bool QtcProcess::startDetached(const CommandLine &cmd, const FilePath &workingDirectory, qint64 *pid) @@ -1115,12 +1145,6 @@ Environment QtcProcess::systemEnvironmentForBinary(const FilePath &filePath) return Environment::systemEnvironment(); } -void QtcProcess::kickoffProcess() -{ - if (d->m_process) - d->m_process->kickoffProcess(); -} - qint64 QtcProcess::applicationMainThreadId() const { return d->m_applicationMainThreadId; @@ -1181,12 +1205,6 @@ QByteArray QtcProcess::readAllStandardError() return buf; } -void QtcProcess::kill() -{ - if (d->m_process) - d->m_process->kill(); -} - qint64 QtcProcess::write(const QByteArray &input) { QTC_ASSERT(processMode() == ProcessMode::Writer, return -1); diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 5357d96a698..54fe6bffbe9 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -60,9 +60,11 @@ public: // ProcessInterface related virtual void start(); - virtual void interrupt(); + virtual void terminate(); virtual void kill(); + virtual void interrupt(); + void kickoffProcess(); void close(); virtual QByteArray readAllStandardOutput(); @@ -70,6 +72,8 @@ public: virtual qint64 write(const QByteArray &input); virtual qint64 processId() const; + qint64 applicationMainThreadId() const; + virtual QProcess::ProcessState state() const; virtual ProcessResultData resultData() const; @@ -83,9 +87,6 @@ public: bool waitForReadyRead(int msecs = 30000); bool waitForFinished(int msecs = 30000); - void kickoffProcess(); - qint64 applicationMainThreadId() const; - // ProcessSetupData related void setProcessImpl(ProcessImpl processImpl); diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index 6c3502aa91c..8c962129efa 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -435,25 +435,29 @@ void TerminalImpl::cleanupAfterStartFailure(const QString &errorMessage) d->m_tempFile = nullptr; } -void TerminalImpl::kickoffProcess() +void TerminalImpl::sendControlSignal(ControlSignal controlSignal) { -#ifdef Q_OS_WIN - // Not used. -#else - if (d->m_stubSocket && d->m_stubSocket->isWritable()) { - d->m_stubSocket->write("c", 1); - d->m_stubSocket->flush(); + switch (controlSignal) { + case Utils::ControlSignal::Terminate: + case Utils::ControlSignal::Kill: + stopProcess(); + break; + case Utils::ControlSignal::Interrupt: + sendCommand('i'); + break; + case Utils::ControlSignal::KickOff: + sendCommand('c'); + break; } -#endif } -void TerminalImpl::interrupt() +void TerminalImpl::sendCommand(char c) { #ifdef Q_OS_WIN - // Not used. + Q_UNUSED(c) #else if (d->m_stubSocket && d->m_stubSocket->isWritable()) { - d->m_stubSocket->write("i", 1); + d->m_stubSocket->write(&c, 1); d->m_stubSocket->flush(); } #endif @@ -467,10 +471,7 @@ void TerminalImpl::killProcess() cleanupInferior(); } #else - if (d->m_stubSocket && d->m_stubSocket->isWritable()) { - d->m_stubSocket->write("k", 1); - d->m_stubSocket->flush(); - } + sendCommand('k'); #endif d->m_processId = 0; } @@ -484,10 +485,7 @@ void TerminalImpl::killStub() cleanupStub(); } #else - if (d->m_stubSocket && d->m_stubSocket->isWritable()) { - d->m_stubSocket->write("s", 1); - d->m_stubSocket->flush(); - } + sendCommand('s'); stubServerShutdown(); #endif } diff --git a/src/libs/utils/terminalprocess_p.h b/src/libs/utils/terminalprocess_p.h index 63cc4a51ccd..582202ac61b 100644 --- a/src/libs/utils/terminalprocess_p.h +++ b/src/libs/utils/terminalprocess_p.h @@ -45,10 +45,9 @@ public: TerminalImpl(); ~TerminalImpl() final; + void start() final; qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; } - - void terminate() final { stopProcess(); } - void kill() final { stopProcess(); } + void sendControlSignal(ControlSignal controlSignal) final; // intentionally no-op without an assert bool waitForStarted(int) final { return false; } @@ -56,13 +55,8 @@ public: // intentionally no-op without an assert bool waitForFinished(int) final { return false; } - void start() final; - QProcess::ProcessState state() const final; - void kickoffProcess() final; // only debugger terminal, only non-windows - void interrupt() final; // only debugger terminal, only non-windows - private: // OK, however, impl looks a bit different (!= NotRunning vs == Running). // Most probably changing it into (== Running) should be OK. @@ -81,6 +75,7 @@ private: void stubServerShutdown(); void cleanupStub(); void cleanupInferior(); + void sendCommand(char c); class TerminalProcessPrivate *d; };