diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp index eda1dbc2c0e..f094cb14732 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp @@ -86,6 +86,7 @@ SshDeviceProcess::~SshDeviceProcess() void SshDeviceProcess::start(const Runnable &runnable) { QTC_ASSERT(d->state == SshDeviceProcessPrivate::Inactive, return); + QTC_ASSERT(runInTerminal() || !runnable.executable.isEmpty(), return); d->setState(SshDeviceProcessPrivate::Connecting); d->errorMessage.clear(); @@ -185,7 +186,9 @@ void SshDeviceProcess::handleConnected() QTC_ASSERT(d->state == SshDeviceProcessPrivate::Connecting, return); d->setState(SshDeviceProcessPrivate::Connected); - d->process = d->connection->createRemoteProcess(fullCommandLine(d->runnable).toUtf8()); + d->process = runInTerminal() && d->runnable.executable.isEmpty() + ? d->connection->createRemoteShell() + : d->connection->createRemoteProcess(fullCommandLine(d->runnable).toUtf8()); const QString display = d->displayName(); if (!display.isEmpty()) d->process->requestX11Forwarding(display); @@ -303,6 +306,8 @@ QString SshDeviceProcess::fullCommandLine(const Runnable &runnable) const void SshDeviceProcess::SshDeviceProcessPrivate::doSignal(Signal signal) { + if (runnable.executable.isEmpty()) + return; switch (state) { case SshDeviceProcessPrivate::Inactive: QTC_ASSERT(false, return); diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 426a12e04cc..83dd01c6d8b 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -34,10 +34,12 @@ #include "remotelinuxenvironmentreader.h" #include +#include #include #include #include #include +#include #include #include @@ -50,6 +52,9 @@ namespace RemoteLinux { const char Delimiter0[] = "x--"; const char Delimiter1[] = "---"; + +static Core::Id openShellActionId() { return "RemoteLinux.OpenShellAction"; } + static QString visualizeNull(QString s) { return s.replace(QLatin1Char('\0'), QLatin1String("")); @@ -182,7 +187,10 @@ IDeviceWidget *LinuxDevice::createWidget() QList LinuxDevice::actionIds() const { - return QList() << Core::Id(Constants::GenericDeployKeyToDeviceActionId); + QList ids({Core::Id(Constants::GenericDeployKeyToDeviceActionId)}); + if (Utils::HostOsInfo::isAnyUnixHost()) + ids << openShellActionId(); + return ids; } QString LinuxDevice::displayNameForActionId(Core::Id actionId) const @@ -191,6 +199,8 @@ QString LinuxDevice::displayNameForActionId(Core::Id actionId) const if (actionId == Constants::GenericDeployKeyToDeviceActionId) return tr("Deploy Public Key..."); + if (actionId == openShellActionId()) + return tr("Open Remote Shell"); return QString(); // Can't happen. } @@ -198,13 +208,35 @@ void LinuxDevice::executeAction(Core::Id actionId, QWidget *parent) { QTC_ASSERT(actionIds().contains(actionId), return); - QDialog *d = nullptr; - const LinuxDevice::ConstPtr device = sharedFromThis().staticCast(); - if (actionId == Constants::GenericDeployKeyToDeviceActionId) - d = PublicKeyDeploymentDialog::createDialog(device, parent); - if (d) - d->exec(); - delete d; + if (actionId == Constants::GenericDeployKeyToDeviceActionId) { + const LinuxDevice::ConstPtr device = sharedFromThis().staticCast(); + QDialog * const d = PublicKeyDeploymentDialog::createDialog(device, parent); + if (d) + d->exec(); + delete d; + return; + } + if (actionId == openShellActionId()) { + DeviceProcess * const proc = createProcess(nullptr); + QObject::connect(proc, &DeviceProcess::finished, [proc] { + if (!proc->errorString().isEmpty()) { + Core::MessageManager::write(tr("Error running remote shell: %1") + .arg(proc->errorString()), + Core::MessageManager::ModeSwitch); + } + proc->deleteLater(); + }); + QObject::connect(proc, &DeviceProcess::error, [proc] { + Core::MessageManager::write(tr("Error starting remote shell."), + Core::MessageManager::ModeSwitch); + proc->deleteLater(); + }); + Runnable runnable; + runnable.device = sharedFromThis().staticCast(); + proc->setRunInTerminal(true); + proc->start(runnable); + return; + } } Utils::OsType LinuxDevice::osType() const