forked from qt-creator/qt-creator
ProcessInterface: Add sendControlSignal() method
It substitutes terminate, kill, interrupt and kickoffProcess methods. Task-number: QTCREATORBUG-27358 Change-Id: I9e952c2f4c1a7e76339366566f2c804a3df30347 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user