QtcProcess: Add closeWriteChannel()

Change-Id: I080be230ec420ead2866f9481123125361e57033
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Jarek Kobus
2023-01-24 07:23:44 +01:00
parent 34fd5b3ced
commit 8e3a22329d
13 changed files with 67 additions and 29 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -55,7 +55,8 @@ enum class ControlSignal {
Terminate,
Kill,
Interrupt,
KickOff
KickOff,
CloseWriteChannel
};
enum class ProcessSignalType {

View File

@@ -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(),

View File

@@ -43,6 +43,7 @@ public:
void kill();
void interrupt();
void kickoffProcess();
void closeWriteChannel();
void close();
void stop();

View File

@@ -434,6 +434,9 @@ void TerminalImpl::sendControlSignal(ControlSignal controlSignal)
case ControlSignal::KickOff:
sendCommand('c');
break;
case ControlSignal::CloseWriteChannel:
QTC_CHECK(false);
break;
}
}

View File

@@ -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)}});
}

View File

@@ -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")

View File

@@ -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<StopProcessPacket>(
const auto packet = LauncherPacket::extractPacket<ControlProcessPacket>(
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;
}
}

View File

@@ -39,7 +39,7 @@ private:
void handleStartPacket();
void handleWritePacket();
void handleStopPacket();
void handleControlPacket();
void handleShutdownPacket();
void sendPacket(const LauncherPacket &packet);