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;
|
QString m_errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class ControlSignal {
|
||||||
|
Terminate,
|
||||||
|
Kill,
|
||||||
|
Interrupt,
|
||||||
|
KickOff
|
||||||
|
};
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject
|
class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -80,11 +87,8 @@ public:
|
|||||||
ProcessInterface(ProcessSetupData::Ptr setup) : m_setup(setup) {}
|
ProcessInterface(ProcessSetupData::Ptr setup) : m_setup(setup) {}
|
||||||
|
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
virtual void interrupt() = 0;
|
|
||||||
virtual void terminate() = 0;
|
|
||||||
virtual void kill() = 0;
|
|
||||||
|
|
||||||
virtual qint64 write(const QByteArray &data) = 0;
|
virtual qint64 write(const QByteArray &data) = 0;
|
||||||
|
virtual void sendControlSignal(ControlSignal controlSignal) = 0;
|
||||||
|
|
||||||
virtual QProcess::ProcessState state() const = 0;
|
virtual QProcess::ProcessState state() const = 0;
|
||||||
|
|
||||||
@@ -92,8 +96,6 @@ public:
|
|||||||
virtual bool waitForReadyRead(int msecs) = 0;
|
virtual bool waitForReadyRead(int msecs) = 0;
|
||||||
virtual bool waitForFinished(int msecs) = 0;
|
virtual bool waitForFinished(int msecs) = 0;
|
||||||
|
|
||||||
virtual void kickoffProcess();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started(qint64 processId, qint64 applicationMainThreadId = 0);
|
void started(qint64 processId, qint64 applicationMainThreadId = 0);
|
||||||
void readyRead(const QByteArray &outputData, const QByteArray &errorData);
|
void readyRead(const QByteArray &outputData, const QByteArray &errorData);
|
||||||
@@ -121,9 +123,6 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void start() override { m_target->start(); }
|
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); }
|
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 waitForReadyRead(int msecs) override { return m_target->waitForReadyRead(msecs); }
|
||||||
bool waitForFinished(int msecs) override { return m_target->waitForFinished(msecs); }
|
bool waitForFinished(int msecs) override { return m_target->waitForFinished(msecs); }
|
||||||
|
|
||||||
void kickoffProcess() override { m_target->kickoffProcess(); }
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ProcessInterface *m_target;
|
ProcessInterface *m_target;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -347,10 +347,23 @@ public:
|
|||||||
}
|
}
|
||||||
~QProcessImpl() final { ProcessReaper::reap(m_process); }
|
~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); }
|
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(); }
|
QProcess::ProcessState state() const final { return m_process->state(); }
|
||||||
|
|
||||||
@@ -432,14 +445,24 @@ public:
|
|||||||
m_handle = nullptr;
|
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); }
|
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(); }
|
QProcess::ProcessState state() const final { return m_handle->state(); }
|
||||||
|
|
||||||
@@ -599,11 +622,6 @@ ProcessResult QtcProcessPrivate::interpretExitCode(int exitCode)
|
|||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
|
||||||
void ProcessInterface::kickoffProcess()
|
|
||||||
{
|
|
||||||
QTC_CHECK(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Utils::QtcProcess
|
\class Utils::QtcProcess
|
||||||
|
|
||||||
@@ -805,13 +823,25 @@ void QtcProcess::start()
|
|||||||
void QtcProcess::terminate()
|
void QtcProcess::terminate()
|
||||||
{
|
{
|
||||||
if (d->m_process)
|
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()
|
void QtcProcess::interrupt()
|
||||||
{
|
{
|
||||||
if (d->m_process)
|
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)
|
bool QtcProcess::startDetached(const CommandLine &cmd, const FilePath &workingDirectory, qint64 *pid)
|
||||||
@@ -1115,12 +1145,6 @@ Environment QtcProcess::systemEnvironmentForBinary(const FilePath &filePath)
|
|||||||
return Environment::systemEnvironment();
|
return Environment::systemEnvironment();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtcProcess::kickoffProcess()
|
|
||||||
{
|
|
||||||
if (d->m_process)
|
|
||||||
d->m_process->kickoffProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QtcProcess::applicationMainThreadId() const
|
qint64 QtcProcess::applicationMainThreadId() const
|
||||||
{
|
{
|
||||||
return d->m_applicationMainThreadId;
|
return d->m_applicationMainThreadId;
|
||||||
@@ -1181,12 +1205,6 @@ QByteArray QtcProcess::readAllStandardError()
|
|||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtcProcess::kill()
|
|
||||||
{
|
|
||||||
if (d->m_process)
|
|
||||||
d->m_process->kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 QtcProcess::write(const QByteArray &input)
|
qint64 QtcProcess::write(const QByteArray &input)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
|
QTC_ASSERT(processMode() == ProcessMode::Writer, return -1);
|
||||||
|
|||||||
@@ -60,9 +60,11 @@ public:
|
|||||||
// ProcessInterface related
|
// ProcessInterface related
|
||||||
|
|
||||||
virtual void start();
|
virtual void start();
|
||||||
virtual void interrupt();
|
|
||||||
virtual void terminate();
|
virtual void terminate();
|
||||||
virtual void kill();
|
virtual void kill();
|
||||||
|
virtual void interrupt();
|
||||||
|
void kickoffProcess();
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
virtual QByteArray readAllStandardOutput();
|
virtual QByteArray readAllStandardOutput();
|
||||||
@@ -70,6 +72,8 @@ public:
|
|||||||
virtual qint64 write(const QByteArray &input);
|
virtual qint64 write(const QByteArray &input);
|
||||||
|
|
||||||
virtual qint64 processId() const;
|
virtual qint64 processId() const;
|
||||||
|
qint64 applicationMainThreadId() const;
|
||||||
|
|
||||||
virtual QProcess::ProcessState state() const;
|
virtual QProcess::ProcessState state() const;
|
||||||
virtual ProcessResultData resultData() const;
|
virtual ProcessResultData resultData() const;
|
||||||
|
|
||||||
@@ -83,9 +87,6 @@ public:
|
|||||||
bool waitForReadyRead(int msecs = 30000);
|
bool waitForReadyRead(int msecs = 30000);
|
||||||
bool waitForFinished(int msecs = 30000);
|
bool waitForFinished(int msecs = 30000);
|
||||||
|
|
||||||
void kickoffProcess();
|
|
||||||
qint64 applicationMainThreadId() const;
|
|
||||||
|
|
||||||
// ProcessSetupData related
|
// ProcessSetupData related
|
||||||
|
|
||||||
void setProcessImpl(ProcessImpl processImpl);
|
void setProcessImpl(ProcessImpl processImpl);
|
||||||
|
|||||||
@@ -435,25 +435,29 @@ void TerminalImpl::cleanupAfterStartFailure(const QString &errorMessage)
|
|||||||
d->m_tempFile = nullptr;
|
d->m_tempFile = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TerminalImpl::kickoffProcess()
|
void TerminalImpl::sendControlSignal(ControlSignal controlSignal)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_WIN
|
switch (controlSignal) {
|
||||||
// Not used.
|
case Utils::ControlSignal::Terminate:
|
||||||
#else
|
case Utils::ControlSignal::Kill:
|
||||||
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
stopProcess();
|
||||||
d->m_stubSocket->write("c", 1);
|
break;
|
||||||
d->m_stubSocket->flush();
|
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
|
#ifdef Q_OS_WIN
|
||||||
// Not used.
|
Q_UNUSED(c)
|
||||||
#else
|
#else
|
||||||
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
||||||
d->m_stubSocket->write("i", 1);
|
d->m_stubSocket->write(&c, 1);
|
||||||
d->m_stubSocket->flush();
|
d->m_stubSocket->flush();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -467,10 +471,7 @@ void TerminalImpl::killProcess()
|
|||||||
cleanupInferior();
|
cleanupInferior();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
sendCommand('k');
|
||||||
d->m_stubSocket->write("k", 1);
|
|
||||||
d->m_stubSocket->flush();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
d->m_processId = 0;
|
d->m_processId = 0;
|
||||||
}
|
}
|
||||||
@@ -484,10 +485,7 @@ void TerminalImpl::killStub()
|
|||||||
cleanupStub();
|
cleanupStub();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (d->m_stubSocket && d->m_stubSocket->isWritable()) {
|
sendCommand('s');
|
||||||
d->m_stubSocket->write("s", 1);
|
|
||||||
d->m_stubSocket->flush();
|
|
||||||
}
|
|
||||||
stubServerShutdown();
|
stubServerShutdown();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,10 +45,9 @@ public:
|
|||||||
TerminalImpl();
|
TerminalImpl();
|
||||||
~TerminalImpl() final;
|
~TerminalImpl() final;
|
||||||
|
|
||||||
|
void start() final;
|
||||||
qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; }
|
qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; }
|
||||||
|
void sendControlSignal(ControlSignal controlSignal) final;
|
||||||
void terminate() final { stopProcess(); }
|
|
||||||
void kill() final { stopProcess(); }
|
|
||||||
|
|
||||||
// intentionally no-op without an assert
|
// intentionally no-op without an assert
|
||||||
bool waitForStarted(int) final { return false; }
|
bool waitForStarted(int) final { return false; }
|
||||||
@@ -56,13 +55,8 @@ public:
|
|||||||
// intentionally no-op without an assert
|
// intentionally no-op without an assert
|
||||||
bool waitForFinished(int) final { return false; }
|
bool waitForFinished(int) final { return false; }
|
||||||
|
|
||||||
void start() final;
|
|
||||||
|
|
||||||
QProcess::ProcessState state() const 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:
|
private:
|
||||||
// OK, however, impl looks a bit different (!= NotRunning vs == Running).
|
// OK, however, impl looks a bit different (!= NotRunning vs == Running).
|
||||||
// Most probably changing it into (== Running) should be OK.
|
// Most probably changing it into (== Running) should be OK.
|
||||||
@@ -81,6 +75,7 @@ private:
|
|||||||
void stubServerShutdown();
|
void stubServerShutdown();
|
||||||
void cleanupStub();
|
void cleanupStub();
|
||||||
void cleanupInferior();
|
void cleanupInferior();
|
||||||
|
void sendCommand(char c);
|
||||||
|
|
||||||
class TerminalProcessPrivate *d;
|
class TerminalProcessPrivate *d;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user