ProjectExplorer: Normalize DeviceProcess::start() signature

Change-Id: I2915be34d4a1eed64567874dcf0263b7583cc142
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-02-11 17:38:16 +01:00
parent 380d952221
commit 95c9579c58
24 changed files with 107 additions and 109 deletions

View File

@@ -1478,6 +1478,12 @@ void CommandLine::addCommandLineAsArgs(const CommandLine &cmd)
addArgs(cmd.splitArguments());
}
void CommandLine::addCommandLineAsArgs(const CommandLine &cmd, RawType)
{
addArg(cmd.executable().path());
addArgs(cmd.arguments(), Raw);
}
void CommandLine::addArgs(const QString &inArgs, RawType)
{
ProcessArgs::addArgs(&m_arguments, inArgs);

View File

@@ -145,6 +145,7 @@ public:
void addArgs(const QStringList &inArgs);
void addCommandLineAsArgs(const CommandLine &cmd);
void addCommandLineAsArgs(const CommandLine &cmd, RawType);
void addArgs(const QString &inArgs, RawType);

View File

@@ -635,6 +635,7 @@ public:
bool m_haveEnv = false;
bool m_useCtrlCStub = false;
ProcessSetupData m_setup;
QVariantHash m_extraData;
void slotTimeout();
void slotFinished(int exitCode, QProcess::ExitStatus e);
@@ -910,6 +911,26 @@ QString QtcProcess::toStandaloneCommandLine() const
return parts.join(" ");
}
void QtcProcess::setExtraData(const QString &key, const QVariant &value)
{
d->m_extraData.insert(key, value);
}
QVariant QtcProcess::extraData(const QString &key) const
{
return d->m_extraData.value(key);
}
void QtcProcess::setExtraData(const QVariantHash &extraData)
{
d->m_extraData = extraData;
}
QVariantHash QtcProcess::extraData() const
{
return d->m_extraData;
}
void QtcProcess::setRemoteProcessHooks(const DeviceProcessHooks &hooks)
{
s_deviceHooks = hooks;

View File

@@ -126,7 +126,7 @@ public:
void setAbortOnMetaChars(bool abort);
void start();
virtual void start();
virtual void terminate();
virtual void interrupt();
@@ -222,6 +222,12 @@ public:
QString toStandaloneCommandLine() const;
void setExtraData(const QString &key, const QVariant &value);
QVariant extraData(const QString &key) const;
void setExtraData(const QVariantHash &extraData);
QVariantHash extraData() const;
signals:
void started();
void finished();

View File

@@ -106,7 +106,7 @@ public:
DockerDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr);
~DockerDeviceProcess() {}
void start(const Runnable &runnable) override;
void start() override;
void interrupt() override;
};
@@ -117,13 +117,13 @@ DockerDeviceProcess::DockerDeviceProcess(const QSharedPointer<const IDevice> &de
setProcessMode(ProcessMode::Writer);
}
void DockerDeviceProcess::start(const Runnable &runnable)
void DockerDeviceProcess::start()
{
QTC_ASSERT(state() == QProcess::NotRunning, return);
DockerDevice::ConstPtr dockerDevice = qSharedPointerCast<const DockerDevice>(device());
QTC_ASSERT(dockerDevice, return);
const QStringList dockerRunFlags = runnable.extraData[Constants::DOCKER_RUN_FLAGS].toStringList();
const QStringList dockerRunFlags = extraData(Constants::DOCKER_RUN_FLAGS).toStringList();
connect(this, &DeviceProcess::readyReadStandardOutput, this, [this] {
MessageManager::writeSilently(QString::fromLocal8Bit(readAllStandardError()));
@@ -132,15 +132,12 @@ void DockerDeviceProcess::start(const Runnable &runnable)
MessageManager::writeDisrupting(QString::fromLocal8Bit(readAllStandardError()));
});
CommandLine command = runnable.command;
CommandLine command = commandLine();
command.setExecutable(
command.executable().withNewPath(dockerDevice->mapToDevicePath(command.executable())));
setCommand(command);
setEnvironment(runnable.environment);
setWorkingDirectory(runnable.workingDirectory);
LOG("Running process:" << command.toUserOutput()
<< "in" << runnable.workingDirectory.toUserOutput());
LOG("Running process:" << command.toUserOutput() << "in" << workingDirectory().toUserOutput());
dockerDevice->runProcess(*this);
}

View File

@@ -173,9 +173,8 @@ void PerfConfigWidget::readTracePoints()
messageBox.setText(tr("Replace events with trace points read from the device?"));
messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
if (messageBox.exec() == QMessageBox::Yes) {
ProjectExplorer::Runnable runnable;
runnable.command = {"perf", {"probe", "-l"}};
m_process->start(runnable);
m_process->setCommand({"perf", {"probe", "-l"}});
m_process->start();
useTracePointsButton->setEnabled(false);
}
}

View File

@@ -147,15 +147,13 @@ public:
Runnable perfRunnable = runnable();
QStringList arguments;
arguments << "record";
arguments += m_perfRecordArguments;
arguments << "-o" << "-" << "--" << perfRunnable.command.executable().toString()
<< ProcessArgs::splitArgs(perfRunnable.command.arguments(), OsTypeLinux);
CommandLine cmd({"perf", {"record"}});
cmd.addArgs(m_perfRecordArguments);
cmd.addArgs({"-o", "-", "--"});
cmd.addCommandLineAsArgs(perfRunnable.command, CommandLine::Raw);
perfRunnable.command.setExecutable("perf");
perfRunnable.command.setArguments(ProcessArgs::joinArgs(arguments, OsTypeLinux));
m_process->start(perfRunnable);
m_process->setCommand(cmd);
m_process->start();
}
void stop() override

View File

@@ -100,12 +100,11 @@ void PerfTracePointDialog::runScript()
m_process.reset(m_device->createProcess(this));
Runnable runnable;
const QString elevate = m_ui->privilegesChooser->currentText();
if (elevate != QLatin1String("n.a."))
runnable.command = {FilePath::fromString(elevate), {"sh"}};
m_process->setCommand({FilePath::fromString(elevate), {"sh"}});
else
runnable.command = {"sh", {}};
m_process->setCommand({"sh", {}});
connect(m_process.get(), &DeviceProcess::started,
this, &PerfTracePointDialog::feedScriptToProcess);
@@ -116,7 +115,7 @@ void PerfTracePointDialog::runScript()
connect(m_process.get(), &DeviceProcess::errorOccurred,
this, &PerfTracePointDialog::handleProcessError);
m_process->start(runnable);
m_process->start();
}
void PerfTracePointDialog::feedScriptToProcess()

View File

@@ -422,7 +422,11 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice::
this, &ApplicationLauncherPrivate::handleApplicationError);
connect(m_deviceProcess, &DeviceProcess::finished,
this, &ApplicationLauncherPrivate::handleApplicationFinished);
m_deviceProcess->start(runnable);
m_deviceProcess->setCommand(runnable.command);
m_deviceProcess->setWorkingDirectory(runnable.workingDirectory);
m_deviceProcess->setEnvironment(runnable.environment);
m_deviceProcess->setExtraData(runnable.extraData);
m_deviceProcess->start();
}
}

View File

@@ -44,16 +44,6 @@ DesktopDeviceProcess::DesktopDeviceProcess(const QSharedPointer<const IDevice> &
setProcessMode(ProcessMode::Writer);
}
void DesktopDeviceProcess::start(const Runnable &runnable)
{
QTC_ASSERT(state() == QProcess::NotRunning, return);
if (runnable.environment.size())
setEnvironment(runnable.environment);
setWorkingDirectory(runnable.workingDirectory);
setCommand(runnable.command);
QtcProcess::start();
}
void DesktopDeviceProcess::interrupt()
{
device()->signalOperation()->interruptProcess(processId());

View File

@@ -39,7 +39,6 @@ class DesktopDeviceProcess : public DeviceProcess
public:
DesktopDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr);
void start(const Runnable &runnable) override;
void interrupt() override;
};

View File

@@ -30,19 +30,14 @@
#include <utils/qtcprocess.h>
#include <QSharedPointer>
#include <QStringList>
namespace ProjectExplorer {
class IDevice;
class Runnable;
class PROJECTEXPLORER_EXPORT DeviceProcess : public Utils::QtcProcess
{
Q_OBJECT
public:
using Utils::QtcProcess::start;
virtual void start(const Runnable &runnable) = 0;
protected:
explicit DeviceProcess(const QSharedPointer<const IDevice> &device,

View File

@@ -86,9 +86,8 @@ void DeviceUsedPortsGatherer::start(const IDevice::ConstPtr &device)
connect(d->process.data(), &DeviceProcess::readyReadStandardError,
this, &DeviceUsedPortsGatherer::handleRemoteStdErr);
Runnable runnable;
runnable.command = d->portsGatheringMethod->commandLine(protocol);
d->process->start(runnable);
d->process->setCommand(d->portsGatheringMethod->commandLine(protocol));
d->process->start();
}
void DeviceUsedPortsGatherer::stop()

View File

@@ -54,7 +54,8 @@ public:
bool ignoreSelfSignals = true;
QSsh::SshConnection *connection = nullptr;
QSsh::SshRemoteProcessPtr remoteProcess;
Runnable runnable;
QString processName;
QString displayName;
QString errorMessage;
QProcess::ExitStatus exitStatus = QProcess::NormalExit;
DeviceProcessSignalOperation::Ptr killOperation;
@@ -63,11 +64,6 @@ public:
void setState(State newState);
void doSignal(Signal signal);
QString displayName() const
{
return runnable.extraData.value("Ssh.X11ForwardToDisplay").toString();
}
};
SshDeviceProcess::SshDeviceProcess(const IDevice::ConstPtr &device, QObject *parent)
@@ -95,17 +91,19 @@ SshDeviceProcess::~SshDeviceProcess()
d->setState(SshDeviceProcessPrivate::Inactive);
}
void SshDeviceProcess::start(const Runnable &runnable)
void SshDeviceProcess::start()
{
QTC_ASSERT(d->state == SshDeviceProcessPrivate::Inactive, return);
QTC_ASSERT(usesTerminal() || !runnable.command.isEmpty(), return);
QTC_ASSERT(usesTerminal() || !commandLine().isEmpty(), return);
d->setState(SshDeviceProcessPrivate::Connecting);
d->errorMessage.clear();
d->exitStatus = QProcess::NormalExit;
d->runnable = runnable;
d->processName = commandLine().executable().toString();
d->displayName = extraData("Ssh.X11ForwardToDisplay").toString();
QSsh::SshConnectionParameters params = device()->sshParameters();
params.x11DisplayName = d->displayName();
params.x11DisplayName = d->displayName;
d->connection = QSsh::SshConnectionManager::acquireConnection(params);
connect(d->connection, &QSsh::SshConnection::errorOccurred,
this, &SshDeviceProcess::handleConnectionError);
@@ -191,10 +189,10 @@ void SshDeviceProcess::handleConnected()
QTC_ASSERT(d->state == SshDeviceProcessPrivate::Connecting, return);
d->setState(SshDeviceProcessPrivate::Connected);
d->remoteProcess = usesTerminal() && d->runnable.command.isEmpty()
d->remoteProcess = usesTerminal() && d->processName.isEmpty()
? d->connection->createRemoteShell()
: d->connection->createRemoteProcess(fullCommandLine(d->runnable));
const QString display = d->displayName();
: d->connection->createRemoteProcess(fullCommandLine());
const QString display = d->displayName;
if (!display.isEmpty())
d->remoteProcess->requestX11Forwarding(display);
d->ignoreSelfSignals = !usesTerminal();
@@ -280,18 +278,14 @@ void SshDeviceProcess::handleKillOperationTimeout()
emit finished();
}
QString SshDeviceProcess::fullCommandLine(const Runnable &runnable) const
QString SshDeviceProcess::fullCommandLine() const
{
QString cmdLine = runnable.command.executable().toString();
// FIXME: That quotes wrongly.
if (!runnable.command.arguments().isEmpty())
cmdLine.append(QLatin1Char(' ')).append(runnable.command.arguments());
return cmdLine;
return commandLine().toUserOutput();
}
void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal)
{
if (runnable.command.isEmpty())
if (processName.isEmpty())
return;
switch (state) {
case SshDeviceProcessPrivate::Inactive:
@@ -310,7 +304,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal)
if (processId != 0)
signalOperation->interruptProcess(processId);
else
signalOperation->interruptProcess(runnable.command.executable().toString());
signalOperation->interruptProcess(processName);
} else {
if (killOperation) // We are already in the process of killing the app.
return;
@@ -321,7 +315,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal)
if (processId != 0)
signalOperation->killProcess(processId);
else
signalOperation->killProcess(runnable.command.executable().toString());
signalOperation->killProcess(processName);
}
break;
}

View File

@@ -31,8 +31,6 @@
namespace ProjectExplorer {
class Runnable;
class PROJECTEXPLORER_EXPORT SshDeviceProcess : public DeviceProcess
{
Q_OBJECT
@@ -40,7 +38,7 @@ public:
explicit SshDeviceProcess(const QSharedPointer<const IDevice> &device, QObject *parent = nullptr);
~SshDeviceProcess() override;
void start(const Runnable &runnable) override;
void start() override;
void interrupt() override;
void terminate() override;
void kill() override;
@@ -64,7 +62,7 @@ private:
void handleKillOperationFinished(const QString &errorMessage);
void handleKillOperationTimeout();
virtual QString fullCommandLine(const Runnable &runnable) const;
virtual QString fullCommandLine() const;
virtual qint64 processId() const;
class SshDeviceProcessPrivate;

View File

@@ -71,7 +71,7 @@ public:
Utils::FilePath workingDirectory;
Utils::Environment environment;
IDevice::ConstPtr device; // Override the kit's device. Keep unset by default.
QHash<Utils::Id, QVariant> extraData;
QVariantHash extraData;
// FIXME: Not necessarily a display name
QString displayName() const;

View File

@@ -104,9 +104,8 @@ void QnxDevice::updateVersionNumber() const
QObject::connect(&versionNumberProcess, &SshDeviceProcess::finished, &eventLoop, &QEventLoop::quit);
QObject::connect(&versionNumberProcess, &DeviceProcess::errorOccurred, &eventLoop, &QEventLoop::quit);
Runnable r;
r.command = {"uname", {"-r"}};
versionNumberProcess.start(r);
versionNumberProcess.setCommand({"uname", {"-r"}});
versionNumberProcess.start();
bool isGuiThread = QThread::currentThread() == QCoreApplication::instance()->thread();
if (isGuiThread)

View File

@@ -44,21 +44,22 @@ QnxDeviceProcess::QnxDeviceProcess(const QSharedPointer<const IDevice> &device,
m_pidFile = QString::fromLatin1("/var/run/qtc.%1.pid").arg(++pidFileCounter);
}
QString QnxDeviceProcess::fullCommandLine(const Runnable &runnable) const
QString QnxDeviceProcess::fullCommandLine() const
{
QStringList args = ProcessArgs::splitArgs(runnable.command.arguments());
args.prepend(runnable.command.executable().toString());
const CommandLine command = commandLine();
QStringList args = ProcessArgs::splitArgs(command.arguments());
args.prepend(command.executable().toString());
QString cmd = ProcessArgs::createUnixArgs(args).toString();
QString fullCommandLine =
"test -f /etc/profile && . /etc/profile ; "
"test -f $HOME/profile && . $HOME/profile ; ";
if (!runnable.workingDirectory.isEmpty())
if (!workingDirectory().isEmpty())
fullCommandLine += QString::fromLatin1("cd %1 ; ").arg(
ProcessArgs::quoteArg(runnable.workingDirectory.toString()));
ProcessArgs::quoteArg(workingDirectory().toString()));
const Environment env = runnable.environment;
const Environment env = environment();
for (auto it = env.constBegin(); it != env.constEnd(); ++it) {
fullCommandLine += QString::fromLatin1("%1='%2' ")
.arg(env.key(it)).arg(env.expandedValueForKey(env.key(it)));
@@ -72,11 +73,10 @@ QString QnxDeviceProcess::fullCommandLine(const Runnable &runnable) const
void QnxDeviceProcess::doSignal(int sig)
{
auto signaler = new SshDeviceProcess(device(), this);
Runnable r;
const QString args = QString("-%2 `cat %1`").arg(m_pidFile).arg(sig);
r.command = CommandLine(FilePath::fromString("kill"), args, CommandLine::Raw);
signaler->setCommand({"kill", args, CommandLine::Raw});
connect(signaler, &SshDeviceProcess::finished, signaler, &QObject::deleteLater);
signaler->start(r);
signaler->start();
}
} // namespace Internal

View File

@@ -40,7 +40,7 @@ public:
void interrupt() override { doSignal(2); }
void terminate() override { doSignal(15); }
void kill() override { doSignal(9); }
QString fullCommandLine(const ProjectExplorer::Runnable &runnable) const override;
QString fullCommandLine() const override;
private:
void doSignal(int sig);

View File

@@ -70,9 +70,8 @@ void Slog2InfoRunner::printMissingWarning()
void Slog2InfoRunner::start()
{
Runnable r;
r.command = {"slog2info", {}};
m_testProcess->start(r);
m_testProcess->setCommand({"slog2info", {}});
m_testProcess->start();
reportStarted();
}
@@ -108,9 +107,8 @@ void Slog2InfoRunner::handleTestProcessCompleted()
void Slog2InfoRunner::readLaunchTime()
{
Runnable r;
r.command = CommandLine("date", "+\"%d %H:%M:%S\"", CommandLine::Raw);
m_launchDateTimeProcess->start(r);
m_launchDateTimeProcess->setCommand({"date", "+\"%d %H:%M:%S\"", CommandLine::Raw});
m_launchDateTimeProcess->start();
}
void Slog2InfoRunner::launchSlog2Info()
@@ -124,9 +122,8 @@ void Slog2InfoRunner::launchSlog2Info()
m_launchDateTime = QDateTime::fromString(QString::fromLatin1(m_launchDateTimeProcess->readAllStandardOutput()).trimmed(),
QString::fromLatin1("dd HH:mm:ss"));
Runnable r;
r.command = {"slog2info", {"-w"}};
m_logProcess->start(r);
m_logProcess->setCommand({"slog2info", {"-w"}});
m_logProcess->start();
}
void Slog2InfoRunner::readLogStandardOutput()

View File

@@ -329,18 +329,16 @@ LinuxDevice::LinuxDevice()
Core::MessageManager::writeDisrupting(tr("Error starting remote shell."));
proc->deleteLater();
});
Runnable runnable;
runnable.device = sharedFromThis();
runnable.environment = env;
runnable.workingDirectory = workingDir;
// It seems we cannot pass an environment to OpenSSH dynamically
// without specifying an executable.
if (env.size() > 0)
runnable.command.setExecutable("/bin/sh");
proc->setCommand({"/bin/sh", {}});
proc->setTerminalMode(QtcProcess::TerminalOn);
proc->start(runnable);
proc->setEnvironment(env);
proc->setWorkingDirectory(workingDir);
proc->start();
});
if (Utils::HostOsInfo::isAnyUnixHost()) {

View File

@@ -79,7 +79,7 @@ qint64 LinuxDeviceProcess::processId() const
return m_processId < 0 ? 0 : m_processId;
}
QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
QString LinuxDeviceProcess::fullCommandLine() const
{
CommandLine cmd;
@@ -91,23 +91,22 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const
cmd.addArgs(";", CommandLine::Raw);
}
if (!runnable.workingDirectory.isEmpty()) {
cmd.addArgs({"cd", runnable.workingDirectory.path()});
if (!workingDirectory().isEmpty()) {
cmd.addArgs({"cd", workingDirectory().path()});
cmd.addArgs("&&", CommandLine::Raw);
}
if (!usesTerminal())
cmd.addArgs(QString("echo ") + pidMarker + "$$" + pidMarker + " && ", CommandLine::Raw);
const Environment &env = runnable.environment;
const Environment &env = environment();
for (auto it = env.constBegin(); it != env.constEnd(); ++it)
cmd.addArgs(env.key(it) + "='" + env.expandedValueForKey(env.key(it)) + '\'', CommandLine::Raw);
if (!usesTerminal())
cmd.addArg("exec");
cmd.addArg(runnable.command.executable().toString());
cmd.addArgs(runnable.command.arguments(), CommandLine::Raw);
cmd.addCommandLineAsArgs(commandLine(), CommandLine::Raw);
return cmd.arguments();
}

View File

@@ -43,7 +43,7 @@ public:
QByteArray readAllStandardOutput() override;
private:
QString fullCommandLine(const ProjectExplorer::Runnable &) const override;
QString fullCommandLine() const override;
qint64 processId() const override;
QByteArray m_output;

View File

@@ -58,9 +58,8 @@ void RemoteLinuxEnvironmentReader::start()
this, &RemoteLinuxEnvironmentReader::handleError);
connect(m_deviceProcess, &DeviceProcess::finished,
this, &RemoteLinuxEnvironmentReader::remoteProcessFinished);
Runnable runnable;
runnable.command.setExecutable("env");
m_deviceProcess->start(runnable);
m_deviceProcess->setCommand({"env", {}});
m_deviceProcess->start();
}
void RemoteLinuxEnvironmentReader::stop()