Docker: Fix windows terminal

Do not send the marker when running in a PTY. On windows it gets encased
in junk and duplicated otherwise.

Change-Id: I9017066b0f1d22d4700704bfa2120c4f5d66daa9
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Marcus Tillmanns
2023-04-04 15:34:52 +02:00
parent 3108892c5c
commit c378df273c

View File

@@ -164,7 +164,8 @@ public:
const std::optional<Environment> &env = std::nullopt, const std::optional<Environment> &env = std::nullopt,
const std::optional<FilePath> &workDir = std::nullopt, const std::optional<FilePath> &workDir = std::nullopt,
bool interactive = false, bool interactive = false,
bool withPty = false); bool withPty = false,
bool withMarker = true);
bool prepareForBuild(const Target *target); bool prepareForBuild(const Target *target);
Tasks validateMounts() const; Tasks validateMounts() const;
@@ -237,17 +238,27 @@ DockerProcessImpl::DockerProcessImpl(IDevice::ConstPtr device, DockerDevicePriva
{ {
connect(&m_process, &QtcProcess::started, this, [this] { connect(&m_process, &QtcProcess::started, this, [this] {
qCDebug(dockerDeviceLog) << "Process started:" << m_process.commandLine(); qCDebug(dockerDeviceLog) << "Process started:" << m_process.commandLine();
if (m_setup.m_ptyData.has_value()) {
m_hasReceivedFirstOutput = true;
emit started(m_process.processId(), m_process.applicationMainThreadId());
}
}); });
connect(&m_process, &QtcProcess::readyReadStandardOutput, this, [this] { connect(&m_process, &QtcProcess::readyReadStandardOutput, this, [this] {
if (m_hasReceivedFirstOutput)
emit readyRead(m_process.readAllRawStandardOutput(), {});
QByteArray output = m_process.readAllRawStandardOutput(); QByteArray output = m_process.readAllRawStandardOutput();
if (!m_hasReceivedFirstOutput) {
qsizetype idx = output.indexOf('\n'); qsizetype idx = output.indexOf('\n');
QByteArray firstLine = output.left(idx).trimmed(); QByteArray firstLine = output.left(idx).trimmed();
QByteArray rest = output.mid(idx + 1); QByteArray rest = output.mid(idx + 1);
qCDebug(dockerDeviceLog) qCDebug(dockerDeviceLog) << "Process first line received:" << m_process.commandLine()
<< "Process first line received:" << m_process.commandLine() << firstLine; << firstLine;
if (firstLine.startsWith("__qtc")) {
if (!firstLine.startsWith("__qtc"))
return;
bool ok = false; bool ok = false;
m_remotePID = firstLine.mid(5, firstLine.size() - 5 - 5).toLongLong(&ok); m_remotePID = firstLine.mid(5, firstLine.size() - 5 - 5).toLongLong(&ok);
@@ -260,10 +271,6 @@ DockerProcessImpl::DockerProcessImpl(IDevice::ConstPtr device, DockerDevicePriva
emit readyRead(rest, stdErr); emit readyRead(rest, stdErr);
m_hasReceivedFirstOutput = true; m_hasReceivedFirstOutput = true;
return;
}
}
emit readyRead(output, {});
}); });
connect(&m_process, &QtcProcess::readyReadStandardError, this, [this] { connect(&m_process, &QtcProcess::readyReadStandardError, this, [this] {
@@ -277,7 +284,7 @@ DockerProcessImpl::DockerProcessImpl(IDevice::ConstPtr device, DockerDevicePriva
Utils::ProcessResultData resultData = m_process.resultData(); Utils::ProcessResultData resultData = m_process.resultData();
if (m_remotePID == 0) { if (m_remotePID == 0 && !m_hasReceivedFirstOutput) {
resultData.m_error = QProcess::FailedToStart; resultData.m_error = QProcess::FailedToStart;
qCWarning(dockerDeviceLog) << "Process failed to start:" << m_process.commandLine(); qCWarning(dockerDeviceLog) << "Process failed to start:" << m_process.commandLine();
QByteArray stdOut = m_process.readAllRawStandardOutput(); QByteArray stdOut = m_process.readAllRawStandardOutput();
@@ -325,7 +332,8 @@ void DockerProcessImpl::start()
m_setup.m_environment, m_setup.m_environment,
m_setup.m_workingDirectory, m_setup.m_workingDirectory,
interactive, interactive,
inTerminal); inTerminal,
!m_process.ptyData().has_value());
m_process.setCommand(fullCommandLine); m_process.setCommand(fullCommandLine);
m_process.start(); m_process.start();
@@ -338,6 +346,7 @@ qint64 DockerProcessImpl::write(const QByteArray &data)
void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal) void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal)
{ {
if (!m_setup.m_ptyData.has_value()) {
QTC_ASSERT(m_remotePID, return); QTC_ASSERT(m_remotePID, return);
if (controlSignal == ControlSignal::CloseWriteChannel) { if (controlSignal == ControlSignal::CloseWriteChannel) {
m_process.closeWriteChannel(); m_process.closeWriteChannel();
@@ -346,6 +355,17 @@ void DockerProcessImpl::sendControlSignal(ControlSignal controlSignal)
const int signal = controlSignalToInt(controlSignal); 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)}});
} else {
// clang-format off
switch (controlSignal) {
case ControlSignal::Terminate: m_process.terminate(); break;
case ControlSignal::Kill: m_process.kill(); break;
case ControlSignal::Interrupt: m_process.interrupt(); break;
case ControlSignal::KickOff: m_process.kickoffProcess(); break;
case ControlSignal::CloseWriteChannel: break;
}
// clang-format on
}
} }
IDeviceWidget *DockerDevice::createWidget() IDeviceWidget *DockerDevice::createWidget()
@@ -473,7 +493,8 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd,
const std::optional<Environment> &env, const std::optional<Environment> &env,
const std::optional<FilePath> &workDir, const std::optional<FilePath> &workDir,
bool interactive, bool interactive,
bool withPty) bool withPty,
bool withMarker)
{ {
if (!m_settings) if (!m_settings)
return {}; return {};
@@ -506,11 +527,15 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd,
CommandLine exec("exec"); CommandLine exec("exec");
exec.addCommandLineAsArgs(cmd, CommandLine::Raw); exec.addCommandLineAsArgs(cmd, CommandLine::Raw);
if (withMarker) {
CommandLine echo("echo"); CommandLine echo("echo");
echo.addArgs("__qtc$$qtc__", CommandLine::Raw); echo.addArgs("__qtc$$qtc__", CommandLine::Raw);
echo.addCommandLineWithAnd(exec); echo.addCommandLineWithAnd(exec);
dockerCmd.addCommandLineAsSingleArg(echo); dockerCmd.addCommandLineAsSingleArg(echo);
} else {
dockerCmd.addCommandLineAsSingleArg(exec);
}
return dockerCmd; return dockerCmd;
} }