forked from qt-creator/qt-creator
Utils: Send __qtc marker from stub
Docker and ssh devices need the real process id on the remote device. The process stub now send this if it receives it as the first line of output. Change-Id: I5d3af39651958fc88d21c3854a0fa1d7f51547a6 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -29,8 +29,10 @@ int ProcessInterface::controlSignalToInt(ControlSignal controlSignal)
|
|||||||
case ControlSignal::Terminate: return 15;
|
case ControlSignal::Terminate: return 15;
|
||||||
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: return 19;
|
||||||
case ControlSignal::CloseWriteChannel: QTC_CHECK(false); return 0;
|
case ControlSignal::CloseWriteChannel:
|
||||||
|
QTC_CHECK(false);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -183,6 +183,8 @@ void TerminalInterface::onStubReadyRead()
|
|||||||
emitFinished(out.mid(5).toInt(), QProcess::NormalExit);
|
emitFinished(out.mid(5).toInt(), QProcess::NormalExit);
|
||||||
} else if (out.startsWith("crash ")) {
|
} else if (out.startsWith("crash ")) {
|
||||||
emitFinished(out.mid(6).toInt(), QProcess::CrashExit);
|
emitFinished(out.mid(6).toInt(), QProcess::CrashExit);
|
||||||
|
} else if (out.startsWith("qtc: ")) {
|
||||||
|
emit readyRead(out.mid(5) + "\n", {});
|
||||||
} else {
|
} else {
|
||||||
emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
|
emitError(QProcess::UnknownError, msgUnexpectedOutput(out));
|
||||||
break;
|
break;
|
||||||
|
@@ -164,7 +164,6 @@ 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 includeMarker = true,
|
|
||||||
bool withPty = false);
|
bool withPty = false);
|
||||||
|
|
||||||
bool prepareForBuild(const Target *target);
|
bool prepareForBuild(const Target *target);
|
||||||
@@ -315,16 +314,17 @@ void DockerProcessImpl::start()
|
|||||||
if (m_setup.m_lowPriority)
|
if (m_setup.m_lowPriority)
|
||||||
m_process.setLowPriority();
|
m_process.setLowPriority();
|
||||||
|
|
||||||
|
const bool inTerminal = m_setup.m_terminalMode != TerminalMode::Off;
|
||||||
|
|
||||||
const bool interactive = m_setup.m_processMode == ProcessMode::Writer
|
const bool interactive = m_setup.m_processMode == ProcessMode::Writer
|
||||||
|| !m_setup.m_writeData.isEmpty();
|
|| !m_setup.m_writeData.isEmpty() || inTerminal;
|
||||||
|
|
||||||
const CommandLine fullCommandLine
|
const CommandLine fullCommandLine
|
||||||
= m_devicePrivate->withDockerExecCmd(m_setup.m_commandLine,
|
= m_devicePrivate->withDockerExecCmd(m_setup.m_commandLine,
|
||||||
m_setup.m_environment,
|
m_setup.m_environment,
|
||||||
m_setup.m_workingDirectory,
|
m_setup.m_workingDirectory,
|
||||||
interactive,
|
interactive,
|
||||||
true,
|
inTerminal);
|
||||||
m_setup.m_ptyData.has_value());
|
|
||||||
|
|
||||||
m_process.setCommand(fullCommandLine);
|
m_process.setCommand(fullCommandLine);
|
||||||
m_process.start();
|
m_process.start();
|
||||||
@@ -472,7 +472,6 @@ 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 includeMarker,
|
|
||||||
bool withPty)
|
bool withPty)
|
||||||
{
|
{
|
||||||
if (!m_settings)
|
if (!m_settings)
|
||||||
@@ -501,20 +500,16 @@ CommandLine DockerDevicePrivate::withDockerExecCmd(const CommandLine &cmd,
|
|||||||
|
|
||||||
dockerCmd.addArg(m_container);
|
dockerCmd.addArg(m_container);
|
||||||
|
|
||||||
if (includeMarker) {
|
dockerCmd.addArgs({"/bin/sh", "-c"});
|
||||||
dockerCmd.addArgs({"/bin/sh", "-c"});
|
|
||||||
|
|
||||||
CommandLine exec("exec");
|
CommandLine exec("exec");
|
||||||
exec.addCommandLineAsArgs(cmd, CommandLine::Raw);
|
exec.addCommandLineAsArgs(cmd, CommandLine::Raw);
|
||||||
|
|
||||||
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.addCommandLineAsArgs(cmd, CommandLine::Raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dockerCmd;
|
return dockerCmd;
|
||||||
}
|
}
|
||||||
|
@@ -137,6 +137,11 @@ void sendMsg(const QByteArray &msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sendQtcMarker(const QByteArray &marker)
|
||||||
|
{
|
||||||
|
sendMsg(QByteArray("qtc: ") + marker + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
void sendPid(int inferiorPid)
|
void sendPid(int inferiorPid)
|
||||||
{
|
{
|
||||||
sendMsg(QString("pid %1\n").arg(inferiorPid).toUtf8());
|
sendMsg(QString("pid %1\n").arg(inferiorPid).toUtf8());
|
||||||
@@ -273,6 +278,26 @@ void setupPidPollTimer()
|
|||||||
pollPidTimer.start();
|
pollPidTimer.start();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class Out { StdOut, StdErr };
|
||||||
|
|
||||||
|
void writeToOut(const QByteArray &data, Out out)
|
||||||
|
{
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
static const HANDLE outHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
static const HANDLE errHandle = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
WriteFile(out == Out::StdOut ? outHandle : errHandle,
|
||||||
|
data.constData(),
|
||||||
|
data.size(),
|
||||||
|
nullptr,
|
||||||
|
nullptr);
|
||||||
|
#else
|
||||||
|
auto fp = out == Out::StdOut ? stdout : stderr;
|
||||||
|
::fwrite(data.constData(), 1, data.size(), fp);
|
||||||
|
::fflush(fp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void startProcess(const QString &executable, const QStringList &arguments, const QString &workingDir)
|
void startProcess(const QString &executable, const QStringList &arguments, const QString &workingDir)
|
||||||
{
|
{
|
||||||
setupPidPollTimer();
|
setupPidPollTimer();
|
||||||
@@ -292,7 +317,32 @@ void startProcess(const QString &executable, const QStringList &arguments, const
|
|||||||
QCoreApplication::instance(),
|
QCoreApplication::instance(),
|
||||||
&onInferiorStarted);
|
&onInferiorStarted);
|
||||||
|
|
||||||
inferiorProcess.setProcessChannelMode(QProcess::ForwardedChannels);
|
inferiorProcess.setProcessChannelMode(QProcess::SeparateChannels);
|
||||||
|
|
||||||
|
QObject::connect(&inferiorProcess,
|
||||||
|
&QProcess::readyReadStandardOutput,
|
||||||
|
QCoreApplication::instance(),
|
||||||
|
[] {
|
||||||
|
const QByteArray data = inferiorProcess.readAllStandardOutput();
|
||||||
|
static bool isFirst = true;
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
if (data.startsWith("__qtc")) {
|
||||||
|
int lineBreak = data.indexOf("\r\n");
|
||||||
|
sendQtcMarker(data.mid(0, lineBreak));
|
||||||
|
if (lineBreak != -1)
|
||||||
|
writeToOut(data.mid(lineBreak + 2), Out::StdOut);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeToOut(data, Out::StdOut);
|
||||||
|
});
|
||||||
|
|
||||||
|
QObject::connect(&inferiorProcess,
|
||||||
|
&QProcess::readyReadStandardError,
|
||||||
|
QCoreApplication::instance(),
|
||||||
|
[] { writeToOut(inferiorProcess.readAllStandardOutput(), Out::StdErr); });
|
||||||
|
|
||||||
if (!(testMode && debugMode))
|
if (!(testMode && debugMode))
|
||||||
inferiorProcess.setInputChannelMode(QProcess::ForwardedInputChannel);
|
inferiorProcess.setInputChannelMode(QProcess::ForwardedInputChannel);
|
||||||
inferiorProcess.setWorkingDirectory(workingDir);
|
inferiorProcess.setWorkingDirectory(workingDir);
|
||||||
|
Reference in New Issue
Block a user