forked from qt-creator/qt-creator
RemoteLinux: Make remote process PID parsing more robust
- Do not assume that the PID string is the first output. - Do not assume output has already been read when the process finishes. Fixes: QTCREATORBUG-25306 Change-Id: Ia7cec6113e7f86469da2e6e0c62e08b38213093a Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This commit is contained in:
@@ -34,15 +34,18 @@ using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
|
||||
const QByteArray pidMarker = "__qtc";
|
||||
|
||||
LinuxDeviceProcess::LinuxDeviceProcess(const QSharedPointer<const ProjectExplorer::IDevice> &device,
|
||||
QObject *parent)
|
||||
: ProjectExplorer::SshDeviceProcess(device, parent), m_processId(0)
|
||||
: ProjectExplorer::SshDeviceProcess(device, parent)
|
||||
{
|
||||
connect(this, &DeviceProcess::finished, this, [this]() {
|
||||
m_processId = -1;
|
||||
m_processId = 0;
|
||||
});
|
||||
connect(this, &DeviceProcess::started, this, [this]() {
|
||||
m_processId = 0;
|
||||
m_pidParsed = false;
|
||||
m_output.clear();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -54,18 +57,26 @@ void LinuxDeviceProcess::setRcFilesToSource(const QStringList &filePaths)
|
||||
QByteArray LinuxDeviceProcess::readAllStandardOutput()
|
||||
{
|
||||
QByteArray output = SshDeviceProcess::readAllStandardOutput();
|
||||
if (m_processId != 0 || runInTerminal())
|
||||
if (m_pidParsed || runInTerminal())
|
||||
return output;
|
||||
|
||||
m_processIdString.append(output);
|
||||
int cut = m_processIdString.indexOf('\n');
|
||||
if (cut != -1) {
|
||||
m_processId = m_processIdString.left(cut).toLongLong();
|
||||
output = m_processIdString.mid(cut + 1);
|
||||
m_processIdString.clear();
|
||||
return output;
|
||||
}
|
||||
return QByteArray();
|
||||
m_output.append(output);
|
||||
static const QByteArray endMarker = pidMarker + '\n';
|
||||
const int endMarkerOffset = m_output.indexOf(endMarker);
|
||||
if (endMarkerOffset == -1)
|
||||
return {};
|
||||
const int startMarkerOffset = m_output.indexOf(pidMarker);
|
||||
if (startMarkerOffset == endMarkerOffset) // Only theoretically possible.
|
||||
return {};
|
||||
const int pidStart = startMarkerOffset + pidMarker.length();
|
||||
const QByteArray pidString = m_output.mid(pidStart, endMarkerOffset - pidStart);
|
||||
m_pidParsed = true;
|
||||
m_processId = pidString.toLongLong();
|
||||
|
||||
// We don't want to show output from e.g. /etc/profile.
|
||||
const QByteArray actualOutput = m_output.mid(endMarkerOffset + endMarker.length());
|
||||
m_output.clear();
|
||||
return actualOutput;
|
||||
}
|
||||
|
||||
qint64 LinuxDeviceProcess::processId() const
|
||||
@@ -90,7 +101,7 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
|
||||
}
|
||||
|
||||
if (!runInTerminal())
|
||||
cmd.addArgs("echo $$ && ", CommandLine::Raw);
|
||||
cmd.addArgs(QString("echo ") + pidMarker + "$$" + pidMarker + " && ", CommandLine::Raw);
|
||||
|
||||
const Environment &env = runnable.environment;
|
||||
for (auto it = env.constBegin(); it != env.constEnd(); ++it)
|
||||
|
@@ -52,8 +52,9 @@ private:
|
||||
const QStringList rcFilesToSource() const;
|
||||
|
||||
QStringList m_rcFilesToSource;
|
||||
QByteArray m_processIdString;
|
||||
qint64 m_processId;
|
||||
QByteArray m_output;
|
||||
qint64 m_processId = 0;
|
||||
bool m_pidParsed = false;
|
||||
};
|
||||
|
||||
} // namespace RemoteLinux
|
||||
|
Reference in New Issue
Block a user