diff --git a/src/libs/utils/launcherpackets.cpp b/src/libs/utils/launcherpackets.cpp index c7c541291d0..13c3a1560d4 100644 --- a/src/libs/utils/launcherpackets.cpp +++ b/src/libs/utils/launcherpackets.cpp @@ -90,17 +90,17 @@ void ProcessStartedPacket::doDeserialize(QDataStream &stream) } -StopProcessPacket::StopProcessPacket(quintptr token) - : LauncherPacket(LauncherPacketType::StopProcess, token) +ControlProcessPacket::ControlProcessPacket(quintptr token) + : LauncherPacket(LauncherPacketType::ControlProcess, token) { } -void StopProcessPacket::doSerialize(QDataStream &stream) const +void ControlProcessPacket::doSerialize(QDataStream &stream) const { stream << int(signalType); } -void StopProcessPacket::doDeserialize(QDataStream &stream) +void ControlProcessPacket::doDeserialize(QDataStream &stream) { int signalTypeInt; stream >> signalTypeInt; diff --git a/src/libs/utils/launcherpackets.h b/src/libs/utils/launcherpackets.h index 74f4c60f04e..2f0bae2915e 100644 --- a/src/libs/utils/launcherpackets.h +++ b/src/libs/utils/launcherpackets.h @@ -21,7 +21,7 @@ enum class LauncherPacketType { Shutdown, StartProcess, WriteIntoProcess, - StopProcess, + ControlProcess, // launcher -> client packets: ProcessStarted, ReadyReadStandardOutput, @@ -116,15 +116,16 @@ private: void doDeserialize(QDataStream &stream) override; }; -class StopProcessPacket : public LauncherPacket +class ControlProcessPacket : public LauncherPacket { public: - StopProcessPacket(quintptr token); + ControlProcessPacket(quintptr token); enum class SignalType { Kill, // Calls QProcess::kill 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; diff --git a/src/libs/utils/launchersocket.cpp b/src/libs/utils/launchersocket.cpp index d6ec9ae5a3d..6a7560f710c 100644 --- a/src/libs/utils/launchersocket.cpp +++ b/src/libs/utils/launchersocket.cpp @@ -171,7 +171,7 @@ QProcess::ProcessState CallerHandle::state() const return m_processState; } -void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType) +void CallerHandle::sendControlPacket(ControlProcessPacket::SignalType signalType) { if (m_processState == QProcess::NotRunning) return; @@ -180,7 +180,7 @@ void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType) // 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 // 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; sendPacket(packet); } @@ -188,19 +188,25 @@ void CallerHandle::sendStopPacket(StopProcessPacket::SignalType signalType) void CallerHandle::terminate() { QTC_ASSERT(isCalledFromCallersThread(), return); - sendStopPacket(StopProcessPacket::SignalType::Terminate); + sendControlPacket(ControlProcessPacket::SignalType::Terminate); } void CallerHandle::kill() { QTC_ASSERT(isCalledFromCallersThread(), return); - sendStopPacket(StopProcessPacket::SignalType::Kill); + sendControlPacket(ControlProcessPacket::SignalType::Kill); } void CallerHandle::close() { 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 diff --git a/src/libs/utils/launchersocket.h b/src/libs/utils/launchersocket.h index 96e8063d8fe..3a9be73e65e 100644 --- a/src/libs/utils/launchersocket.h +++ b/src/libs/utils/launchersocket.h @@ -62,10 +62,11 @@ public: // Called from caller's or launcher's thread. QProcess::ProcessState state() const; - void sendStopPacket(StopProcessPacket::SignalType signalType); + void sendControlPacket(ControlProcessPacket::SignalType signalType); void terminate(); void kill(); void close(); + void closeWriteChannel(); qint64 processId() const; diff --git a/src/libs/utils/processinterface.cpp b/src/libs/utils/processinterface.cpp index d0d28b8c27d..9e13494cda1 100644 --- a/src/libs/utils/processinterface.cpp +++ b/src/libs/utils/processinterface.cpp @@ -19,6 +19,7 @@ int ProcessInterface::controlSignalToInt(ControlSignal controlSignal) case ControlSignal::Kill: return 9; case ControlSignal::Interrupt: return 2; case ControlSignal::KickOff: QTC_CHECK(false); return 0; + case ControlSignal::CloseWriteChannel: QTC_CHECK(false); return 0; } return 0; } diff --git a/src/libs/utils/processinterface.h b/src/libs/utils/processinterface.h index 7ab7f8da852..d398d8fe139 100644 --- a/src/libs/utils/processinterface.h +++ b/src/libs/utils/processinterface.h @@ -55,7 +55,8 @@ enum class ControlSignal { Terminate, Kill, Interrupt, - KickOff + KickOff, + CloseWriteChannel }; enum class ProcessSignalType { diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 7936c2db0d0..c36f4097782 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -337,6 +337,9 @@ private: case ControlSignal::KickOff: QTC_CHECK(false); break; + case ControlSignal::CloseWriteChannel: + m_process->closeWriteChannel(); + break; } } @@ -464,6 +467,9 @@ private: case ControlSignal::KickOff: QTC_CHECK(false); break; + case ControlSignal::CloseWriteChannel: + m_handle->closeWriteChannel(); + break; } } @@ -1132,6 +1138,11 @@ void QtcProcess::kickoffProcess() d->sendControlSignal(ControlSignal::KickOff); } +void QtcProcess::closeWriteChannel() +{ + d->sendControlSignal(ControlSignal::CloseWriteChannel); +} + bool QtcProcess::startDetached(const CommandLine &cmd, const FilePath &workingDirectory, qint64 *pid) { return QProcess::startDetached(cmd.executable().toUserOutput(), diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 39daa57abad..ae99bd666c2 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -43,6 +43,7 @@ public: void kill(); void interrupt(); void kickoffProcess(); + void closeWriteChannel(); void close(); void stop(); diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index be2cb63ed1a..11157c77a81 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -434,6 +434,9 @@ void TerminalImpl::sendControlSignal(ControlSignal controlSignal) case ControlSignal::KickOff: sendCommand('c'); break; + case ControlSignal::CloseWriteChannel: + QTC_CHECK(false); + break; } } diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index c6371484779..6ab31035487 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -309,7 +309,11 @@ qint64 DockerProcessImpl::write(const QByteArray &data) void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal) { 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( {"kill", {QString("-%1").arg(signal), QString("%2").arg(m_remotePID)}}); } diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 03c54098778..465c03ed974 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -505,14 +505,19 @@ qint64 SshProcessInterface::write(const QByteArray &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()) { switch (controlSignal) { - case Utils::ControlSignal::Terminate: d->m_process.terminate(); break; - case Utils::ControlSignal::Kill: d->m_process.kill(); break; - case Utils::ControlSignal::Interrupt: d->m_process.interrupt(); break; - case Utils::ControlSignal::KickOff: d->m_process.kickoffProcess(); break; + case ControlSignal::Terminate: d->m_process.terminate(); break; + case ControlSignal::Kill: d->m_process.kill(); break; + case ControlSignal::Interrupt: d->m_process.interrupt(); break; + case ControlSignal::KickOff: d->m_process.kickoffProcess(); break; + case ControlSignal::CloseWriteChannel: break; } return; } @@ -532,6 +537,7 @@ LinuxProcessInterface::~LinuxProcessInterface() void LinuxProcessInterface::handleSendControlSignal(ControlSignal controlSignal) { QTC_ASSERT(controlSignal != ControlSignal::KickOff, return); + QTC_ASSERT(controlSignal != ControlSignal::CloseWriteChannel, return); const qint64 pid = processId(); QTC_ASSERT(pid, return); // TODO: try sending a signal based on process name const QString args = QString::fromLatin1("-%1 -%2") diff --git a/src/tools/processlauncher/launchersockethandler.cpp b/src/tools/processlauncher/launchersockethandler.cpp index b148b31ce14..21167f8d773 100644 --- a/src/tools/processlauncher/launchersockethandler.cpp +++ b/src/tools/processlauncher/launchersockethandler.cpp @@ -84,8 +84,8 @@ void LauncherSocketHandler::handleSocketData() case LauncherPacketType::WriteIntoProcess: handleWritePacket(); break; - case LauncherPacketType::StopProcess: - handleStopPacket(); + case LauncherPacketType::ControlProcess: + handleControlPacket(); break; case LauncherPacketType::Shutdown: handleShutdownPacket(); @@ -211,7 +211,7 @@ void LauncherSocketHandler::handleWritePacket() process->write(packet.inputData); } -void LauncherSocketHandler::handleStopPacket() +void LauncherSocketHandler::handleControlPacket() { Process * const process = m_processes.value(m_packetParser.token()); if (!process) { @@ -220,20 +220,23 @@ void LauncherSocketHandler::handleStopPacket() logDebug("Got stop request for unknown process"); return; } - const auto packet = LauncherPacket::extractPacket( + const auto packet = LauncherPacket::extractPacket( m_packetParser.token(), m_packetParser.packetData()); switch (packet.signalType) { - case StopProcessPacket::SignalType::Terminate: + case ControlProcessPacket::SignalType::Terminate: process->terminate(); break; - case StopProcessPacket::SignalType::Kill: + case ControlProcessPacket::SignalType::Kill: process->kill(); break; - case StopProcessPacket::SignalType::Close: + case ControlProcessPacket::SignalType::Close: removeProcess(process->token()); break; + case ControlProcessPacket::SignalType::CloseWriteChannel: + process->closeWriteChannel(); + break; } } diff --git a/src/tools/processlauncher/launchersockethandler.h b/src/tools/processlauncher/launchersockethandler.h index 48d59794a27..e3ec8a65b8f 100644 --- a/src/tools/processlauncher/launchersockethandler.h +++ b/src/tools/processlauncher/launchersockethandler.h @@ -39,7 +39,7 @@ private: void handleStartPacket(); void handleWritePacket(); - void handleStopPacket(); + void handleControlPacket(); void handleShutdownPacket(); void sendPacket(const LauncherPacket &packet);