Implement writing to process inside process launcher

Change-Id: I7321a941024d431cc52b3f6ae0b1ef38d851db8c
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-06 14:43:03 +02:00
parent 7696f4f37c
commit 535d312e93
7 changed files with 61 additions and 2 deletions

View File

@@ -98,6 +98,15 @@ void StopProcessPacket::doDeserialize(QDataStream &stream)
Q_UNUSED(stream);
}
void WritePacket::doSerialize(QDataStream &stream) const
{
stream << inputData;
}
void WritePacket::doDeserialize(QDataStream &stream)
{
stream >> inputData;
}
ProcessErrorPacket::ProcessErrorPacket(quintptr token)
: LauncherPacket(LauncherPacketType::ProcessError, token)

View File

@@ -40,6 +40,7 @@ enum class LauncherPacketType {
// client -> launcher packets:
Shutdown,
StartProcess,
WriteIntoProcess,
StopProcess,
// launcher -> client packets:
ProcessError,
@@ -139,6 +140,18 @@ private:
void doDeserialize(QDataStream &stream) override;
};
class WritePacket : public LauncherPacket
{
public:
WritePacket(quintptr token) : LauncherPacket(LauncherPacketType::WriteIntoProcess, token) { }
QByteArray inputData;
private:
void doSerialize(QDataStream &stream) const override;
void doDeserialize(QDataStream &stream) override;
};
class ShutdownPacket : public LauncherPacket
{
public:

View File

@@ -333,6 +333,18 @@ void LauncherHandle::start(const QString &program, const QStringList &arguments,
doStart();
}
qint64 LauncherHandle::write(const QByteArray &data)
{
QMutexLocker locker(&m_mutex);
if (m_processState != QProcess::Running)
return -1;
WritePacket p(m_token);
p.inputData = data;
sendPacket(p);
}
// Ensure it's called from caller's thread, after moving LauncherHandle into the launcher's thread
void LauncherHandle::createCallerHandle()
{

View File

@@ -89,6 +89,8 @@ public:
// Who should remove this object? deleteLater()?
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode);
qint64 write(const QByteArray &data);
QProcess::ProcessError error() const { QMutexLocker locker(&m_mutex); return m_error; }
QString program() const { QMutexLocker locker(&m_mutex); return m_command; }
void setStandardInputFile(const QString &fileName) { QMutexLocker locker(&m_mutex); m_standardInputFile = fileName; }

View File

@@ -306,7 +306,7 @@ public:
void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close?
void kill() override { cancel(); } // TODO: see above
void close() override { cancel(); } // TODO: see above
qint64 write(const QByteArray &data) override { QTC_CHECK(false); return -1; }
qint64 write(const QByteArray &data) override { return m_handle->write(data); }
void closeWriteChannel() override { /*QTC_CHECK(false);*/ }
void setStandardInputFile(const QString &fileName) override { m_handle->setStandardInputFile(fileName); }

View File

@@ -132,6 +132,9 @@ void LauncherSocketHandler::handleSocketData()
case LauncherPacketType::StartProcess:
handleStartPacket();
break;
case LauncherPacketType::WriteIntoProcess:
handleWritePacket();
break;
case LauncherPacketType::StopProcess:
handleStopPacket();
break;
@@ -235,7 +238,26 @@ void LauncherSocketHandler::handleStartPacket()
process->setProcessChannelMode(packet.channelMode);
process->setStandardInputFile(packet.standardInputFile);
process->start(packet.command, packet.arguments, packet.openMode);
process->closeWriteChannel();
const bool shouldCloseWriteChannel = !(packet.openMode & QIODevice::WriteOnly);
if (shouldCloseWriteChannel)
process->closeWriteChannel();
}
void LauncherSocketHandler::handleWritePacket()
{
Process * const process = m_processes.value(m_packetParser.token());
if (!process) {
logWarn("got write request for unknown process");
return;
}
if (process->state() != QProcess::Running) {
logDebug("can't write into not running process");
return;
}
const auto packet = LauncherPacket::extractPacket<WritePacket>(
m_packetParser.token(),
m_packetParser.packetData());
process->write(packet.inputData);
}
void LauncherSocketHandler::handleStopPacket()

View File

@@ -59,6 +59,7 @@ private:
void handleProcessFinished();
void handleStartPacket();
void handleWritePacket();
void handleStopPacket();
void handleShutdownPacket();