forked from qt-creator/qt-creator
QtcProcess: Add closeWriteChannel()
Change-Id: I080be230ec420ead2866f9481123125361e57033 Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
@@ -90,17 +90,17 @@ void ProcessStartedPacket::doDeserialize(QDataStream &stream)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
StopProcessPacket::StopProcessPacket(quintptr token)
|
ControlProcessPacket::ControlProcessPacket(quintptr token)
|
||||||
: LauncherPacket(LauncherPacketType::StopProcess, token)
|
: LauncherPacket(LauncherPacketType::ControlProcess, token)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopProcessPacket::doSerialize(QDataStream &stream) const
|
void ControlProcessPacket::doSerialize(QDataStream &stream) const
|
||||||
{
|
{
|
||||||
stream << int(signalType);
|
stream << int(signalType);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopProcessPacket::doDeserialize(QDataStream &stream)
|
void ControlProcessPacket::doDeserialize(QDataStream &stream)
|
||||||
{
|
{
|
||||||
int signalTypeInt;
|
int signalTypeInt;
|
||||||
stream >> signalTypeInt;
|
stream >> signalTypeInt;
|
||||||
|
@@ -21,7 +21,7 @@ enum class LauncherPacketType {
|
|||||||
Shutdown,
|
Shutdown,
|
||||||
StartProcess,
|
StartProcess,
|
||||||
WriteIntoProcess,
|
WriteIntoProcess,
|
||||||
StopProcess,
|
ControlProcess,
|
||||||
// launcher -> client packets:
|
// launcher -> client packets:
|
||||||
ProcessStarted,
|
ProcessStarted,
|
||||||
ReadyReadStandardOutput,
|
ReadyReadStandardOutput,
|
||||||
@@ -116,15 +116,16 @@ private:
|
|||||||
void doDeserialize(QDataStream &stream) override;
|
void doDeserialize(QDataStream &stream) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class StopProcessPacket : public LauncherPacket
|
class ControlProcessPacket : public LauncherPacket
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StopProcessPacket(quintptr token);
|
ControlProcessPacket(quintptr token);
|
||||||
|
|
||||||
enum class SignalType {
|
enum class SignalType {
|
||||||
Kill, // Calls QProcess::kill
|
Kill, // Calls QProcess::kill
|
||||||
Terminate, // Calls QProcess::terminate
|
Terminate, // Calls QProcess::terminate
|
||||||
Close // Puts the process into the reaper, no confirmation signal is being sent.
|
Close, // Puts the process into the reaper, no confirmation signal is being sent.
|
||||||
|
CloseWriteChannel
|
||||||
};
|
};
|
||||||
|
|
||||||
SignalType signalType = SignalType::Kill;
|
SignalType signalType = SignalType::Kill;
|
||||||
|
@@ -171,7 +171,7 @@ QProcess::ProcessState CallerHandle::state() const
|
|||||||
return m_processState;
|
return m_processState;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType)
|
void CallerHandle::sendControlPacket(ControlProcessPacket::SignalType signalType)
|
||||||
{
|
{
|
||||||
if (m_processState == QProcess::NotRunning)
|
if (m_processState == QProcess::NotRunning)
|
||||||
return;
|
return;
|
||||||
@@ -180,7 +180,7 @@ void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType)
|
|||||||
// we might want to remove posted start packet and finish the process immediately.
|
// we might want to remove posted start packet and finish the process immediately.
|
||||||
// In addition, we may always try to check if correspodning start packet for the m_token
|
// In addition, we may always try to check if correspodning start packet for the m_token
|
||||||
// is still awaiting and do the same (remove the packet from the stack and finish immediately).
|
// is still awaiting and do the same (remove the packet from the stack and finish immediately).
|
||||||
StopProcessPacket packet(m_token);
|
ControlProcessPacket packet(m_token);
|
||||||
packet.signalType = signalType;
|
packet.signalType = signalType;
|
||||||
sendPacket(packet);
|
sendPacket(packet);
|
||||||
}
|
}
|
||||||
@@ -188,19 +188,25 @@ void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType)
|
|||||||
void CallerHandle::terminate()
|
void CallerHandle::terminate()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return);
|
QTC_ASSERT(isCalledFromCallersThread(), return);
|
||||||
sendStopPacket(StopProcessPacket::SignalType::Terminate);
|
sendControlPacket(ControlProcessPacket::SignalType::Terminate);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallerHandle::kill()
|
void CallerHandle::kill()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return);
|
QTC_ASSERT(isCalledFromCallersThread(), return);
|
||||||
sendStopPacket(StopProcessPacket::SignalType::Kill);
|
sendControlPacket(ControlProcessPacket::SignalType::Kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallerHandle::close()
|
void CallerHandle::close()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return);
|
QTC_ASSERT(isCalledFromCallersThread(), return);
|
||||||
sendStopPacket(StopProcessPacket::SignalType::Close);
|
sendControlPacket(ControlProcessPacket::SignalType::Close);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallerHandle::closeWriteChannel()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(isCalledFromCallersThread(), return);
|
||||||
|
sendControlPacket(ControlProcessPacket::SignalType::CloseWriteChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
qint64 CallerHandle::processId() const
|
qint64 CallerHandle::processId() const
|
||||||
|
@@ -62,10 +62,11 @@ public:
|
|||||||
|
|
||||||
// Called from caller's or launcher's thread.
|
// Called from caller's or launcher's thread.
|
||||||
QProcess::ProcessState state() const;
|
QProcess::ProcessState state() const;
|
||||||
void sendStopPacket(StopProcessPacket::SignalType signalType);
|
void sendControlPacket(ControlProcessPacket::SignalType signalType);
|
||||||
void terminate();
|
void terminate();
|
||||||
void kill();
|
void kill();
|
||||||
void close();
|
void close();
|
||||||
|
void closeWriteChannel();
|
||||||
|
|
||||||
qint64 processId() const;
|
qint64 processId() const;
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ int ProcessInterface::controlSignalToInt(ControlSignal controlSignal)
|
|||||||
case ControlSignal::Kill: return 9;
|
case ControlSignal::Kill: return 9;
|
||||||
case ControlSignal::Interrupt: return 2;
|
case ControlSignal::Interrupt: return 2;
|
||||||
case ControlSignal::KickOff: QTC_CHECK(false); return 0;
|
case ControlSignal::KickOff: QTC_CHECK(false); return 0;
|
||||||
|
case ControlSignal::CloseWriteChannel: QTC_CHECK(false); return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -55,7 +55,8 @@ enum class ControlSignal {
|
|||||||
Terminate,
|
Terminate,
|
||||||
Kill,
|
Kill,
|
||||||
Interrupt,
|
Interrupt,
|
||||||
KickOff
|
KickOff,
|
||||||
|
CloseWriteChannel
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ProcessSignalType {
|
enum class ProcessSignalType {
|
||||||
|
@@ -337,6 +337,9 @@ private:
|
|||||||
case ControlSignal::KickOff:
|
case ControlSignal::KickOff:
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
break;
|
break;
|
||||||
|
case ControlSignal::CloseWriteChannel:
|
||||||
|
m_process->closeWriteChannel();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -464,6 +467,9 @@ private:
|
|||||||
case ControlSignal::KickOff:
|
case ControlSignal::KickOff:
|
||||||
QTC_CHECK(false);
|
QTC_CHECK(false);
|
||||||
break;
|
break;
|
||||||
|
case ControlSignal::CloseWriteChannel:
|
||||||
|
m_handle->closeWriteChannel();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1132,6 +1138,11 @@ void QtcProcess::kickoffProcess()
|
|||||||
d->sendControlSignal(ControlSignal::KickOff);
|
d->sendControlSignal(ControlSignal::KickOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtcProcess::closeWriteChannel()
|
||||||
|
{
|
||||||
|
d->sendControlSignal(ControlSignal::CloseWriteChannel);
|
||||||
|
}
|
||||||
|
|
||||||
bool QtcProcess::startDetached(const CommandLine &cmd, const FilePath &workingDirectory, qint64 *pid)
|
bool QtcProcess::startDetached(const CommandLine &cmd, const FilePath &workingDirectory, qint64 *pid)
|
||||||
{
|
{
|
||||||
return QProcess::startDetached(cmd.executable().toUserOutput(),
|
return QProcess::startDetached(cmd.executable().toUserOutput(),
|
||||||
|
@@ -43,6 +43,7 @@ public:
|
|||||||
void kill();
|
void kill();
|
||||||
void interrupt();
|
void interrupt();
|
||||||
void kickoffProcess();
|
void kickoffProcess();
|
||||||
|
void closeWriteChannel();
|
||||||
void close();
|
void close();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
@@ -434,6 +434,9 @@ void TerminalImpl::sendControlSignal(ControlSignal controlSignal)
|
|||||||
case ControlSignal::KickOff:
|
case ControlSignal::KickOff:
|
||||||
sendCommand('c');
|
sendCommand('c');
|
||||||
break;
|
break;
|
||||||
|
case ControlSignal::CloseWriteChannel:
|
||||||
|
QTC_CHECK(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -309,7 +309,11 @@ qint64 DockerProcessImpl::write(const QByteArray &data)
|
|||||||
void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal)
|
void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_remotePID, return);
|
QTC_ASSERT(m_remotePID, return);
|
||||||
int signal = controlSignalToInt(controlSignal);
|
if (controlSignal == ControlSignal::CloseWriteChannel) {
|
||||||
|
m_process.closeWriteChannel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int signal = controlSignalToInt(controlSignal);
|
||||||
m_devicePrivate->runInShell(
|
m_devicePrivate->runInShell(
|
||||||
{"kill", {QString("-%1").arg(signal), QString("%2").arg(m_remotePID)}});
|
{"kill", {QString("-%1").arg(signal), QString("%2").arg(m_remotePID)}});
|
||||||
}
|
}
|
||||||
|
@@ -505,14 +505,19 @@ qint64 SshProcessInterface::write(const QByteArray &data)
|
|||||||
return d->m_process.writeRaw(data);
|
return d->m_process.writeRaw(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshProcessInterface::sendControlSignal(Utils::ControlSignal controlSignal)
|
void SshProcessInterface::sendControlSignal(ControlSignal controlSignal)
|
||||||
{
|
{
|
||||||
|
if (controlSignal == ControlSignal::CloseWriteChannel) {
|
||||||
|
d->m_process.closeWriteChannel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (d->m_process.usesTerminal()) {
|
if (d->m_process.usesTerminal()) {
|
||||||
switch (controlSignal) {
|
switch (controlSignal) {
|
||||||
case Utils::ControlSignal::Terminate: d->m_process.terminate(); break;
|
case ControlSignal::Terminate: d->m_process.terminate(); break;
|
||||||
case Utils::ControlSignal::Kill: d->m_process.kill(); break;
|
case ControlSignal::Kill: d->m_process.kill(); break;
|
||||||
case Utils::ControlSignal::Interrupt: d->m_process.interrupt(); break;
|
case ControlSignal::Interrupt: d->m_process.interrupt(); break;
|
||||||
case Utils::ControlSignal::KickOff: d->m_process.kickoffProcess(); break;
|
case ControlSignal::KickOff: d->m_process.kickoffProcess(); break;
|
||||||
|
case ControlSignal::CloseWriteChannel: break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -532,6 +537,7 @@ LinuxProcessInterface::~LinuxProcessInterface()
|
|||||||
void LinuxProcessInterface::handleSendControlSignal(ControlSignal controlSignal)
|
void LinuxProcessInterface::handleSendControlSignal(ControlSignal controlSignal)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(controlSignal != ControlSignal::KickOff, return);
|
QTC_ASSERT(controlSignal != ControlSignal::KickOff, return);
|
||||||
|
QTC_ASSERT(controlSignal != ControlSignal::CloseWriteChannel, return);
|
||||||
const qint64 pid = processId();
|
const qint64 pid = processId();
|
||||||
QTC_ASSERT(pid, return); // TODO: try sending a signal based on process name
|
QTC_ASSERT(pid, return); // TODO: try sending a signal based on process name
|
||||||
const QString args = QString::fromLatin1("-%1 -%2")
|
const QString args = QString::fromLatin1("-%1 -%2")
|
||||||
|
@@ -84,8 +84,8 @@ void LauncherSocketHandler::handleSocketData()
|
|||||||
case LauncherPacketType::WriteIntoProcess:
|
case LauncherPacketType::WriteIntoProcess:
|
||||||
handleWritePacket();
|
handleWritePacket();
|
||||||
break;
|
break;
|
||||||
case LauncherPacketType::StopProcess:
|
case LauncherPacketType::ControlProcess:
|
||||||
handleStopPacket();
|
handleControlPacket();
|
||||||
break;
|
break;
|
||||||
case LauncherPacketType::Shutdown:
|
case LauncherPacketType::Shutdown:
|
||||||
handleShutdownPacket();
|
handleShutdownPacket();
|
||||||
@@ -211,7 +211,7 @@ void LauncherSocketHandler::handleWritePacket()
|
|||||||
process->write(packet.inputData);
|
process->write(packet.inputData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LauncherSocketHandler::handleStopPacket()
|
void LauncherSocketHandler::handleControlPacket()
|
||||||
{
|
{
|
||||||
Process * const process = m_processes.value(m_packetParser.token());
|
Process * const process = m_processes.value(m_packetParser.token());
|
||||||
if (!process) {
|
if (!process) {
|
||||||
@@ -220,20 +220,23 @@ void LauncherSocketHandler::handleStopPacket()
|
|||||||
logDebug("Got stop request for unknown process");
|
logDebug("Got stop request for unknown process");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto packet = LauncherPacket::extractPacket<StopProcessPacket>(
|
const auto packet = LauncherPacket::extractPacket<ControlProcessPacket>(
|
||||||
m_packetParser.token(),
|
m_packetParser.token(),
|
||||||
m_packetParser.packetData());
|
m_packetParser.packetData());
|
||||||
|
|
||||||
switch (packet.signalType) {
|
switch (packet.signalType) {
|
||||||
case StopProcessPacket::SignalType::Terminate:
|
case ControlProcessPacket::SignalType::Terminate:
|
||||||
process->terminate();
|
process->terminate();
|
||||||
break;
|
break;
|
||||||
case StopProcessPacket::SignalType::Kill:
|
case ControlProcessPacket::SignalType::Kill:
|
||||||
process->kill();
|
process->kill();
|
||||||
break;
|
break;
|
||||||
case StopProcessPacket::SignalType::Close:
|
case ControlProcessPacket::SignalType::Close:
|
||||||
removeProcess(process->token());
|
removeProcess(process->token());
|
||||||
break;
|
break;
|
||||||
|
case ControlProcessPacket::SignalType::CloseWriteChannel:
|
||||||
|
process->closeWriteChannel();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -39,7 +39,7 @@ private:
|
|||||||
|
|
||||||
void handleStartPacket();
|
void handleStartPacket();
|
||||||
void handleWritePacket();
|
void handleWritePacket();
|
||||||
void handleStopPacket();
|
void handleControlPacket();
|
||||||
void handleShutdownPacket();
|
void handleShutdownPacket();
|
||||||
|
|
||||||
void sendPacket(const LauncherPacket &packet);
|
void sendPacket(const LauncherPacket &packet);
|
||||||
|
Reference in New Issue
Block a user