diff --git a/src/libs/ssh/sshremoteprocess.cpp b/src/libs/ssh/sshremoteprocess.cpp index ca38f48b398..aa46214afbb 100644 --- a/src/libs/ssh/sshremoteprocess.cpp +++ b/src/libs/ssh/sshremoteprocess.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -84,20 +85,15 @@ SshRemoteProcess::SshRemoteProcess(const QByteArray &command, const QStringList void SshRemoteProcess::doStart() { QTC_ASSERT(!isRunning(), return); - QStringList args = QStringList("-q") << d->connectionArgs; - if (d->useTerminal) - args.prepend("-tt"); + const QStringList args = fullLocalCommandLine(); if (!d->displayName.isEmpty()) { - args.prepend("-X"); QProcessEnvironment env = processEnvironment(); env.insert("DISPLAY", d->displayName); setProcessEnvironment(env); } - if (!d->remoteCommand.isEmpty()) - args << QLatin1String(d->remoteCommand); - qCDebug(sshLog) << "starting remote process:" << SshSettings::sshFilePath().toUserOutput() + qCDebug(sshLog) << "starting remote process:" << QDir::toNativeSeparators(args.first()) << args; - QProcess::start(SshSettings::sshFilePath().toString(), args); + QProcess::start(args.first(), args.mid(1)); } SshRemoteProcess::~SshRemoteProcess() @@ -125,4 +121,17 @@ bool SshRemoteProcess::isRunning() const return state() == QProcess::Running; } +QStringList SshRemoteProcess::fullLocalCommandLine() const +{ + QStringList args = QStringList("-q") << d->connectionArgs; + if (d->useTerminal) + args.prepend("-tt"); + if (!d->displayName.isEmpty()) + args.prepend("-X"); + if (!d->remoteCommand.isEmpty()) + args << QLatin1String(d->remoteCommand); + args.prepend(SshSettings::sshFilePath().toString()); + return args; +} + } // namespace QSsh diff --git a/src/libs/ssh/sshremoteprocess.h b/src/libs/ssh/sshremoteprocess.h index 8d62df2390b..82dd1b9dcbe 100644 --- a/src/libs/ssh/sshremoteprocess.h +++ b/src/libs/ssh/sshremoteprocess.h @@ -50,6 +50,7 @@ public: void start(); bool isRunning() const; + QStringList fullLocalCommandLine() const; signals: void done(const QString &error); diff --git a/src/plugins/projectexplorer/applicationlauncher.cpp b/src/plugins/projectexplorer/applicationlauncher.cpp index 8cb71a9bec0..61a2fcb3350 100644 --- a/src/plugins/projectexplorer/applicationlauncher.cpp +++ b/src/plugins/projectexplorer/applicationlauncher.cpp @@ -411,6 +411,7 @@ void ApplicationLauncherPrivate::start(const Runnable &runnable, const IDevice:: m_success = true; m_deviceProcess = device->createProcess(this); + m_deviceProcess->setRunInTerminal(m_useTerminal); connect(m_deviceProcess, &DeviceProcess::started, q, &ApplicationLauncher::remoteProcessStarted); connect(m_deviceProcess, &DeviceProcess::readyReadStandardOutput, diff --git a/src/plugins/projectexplorer/devicesupport/deviceprocess.h b/src/plugins/projectexplorer/devicesupport/deviceprocess.h index f8d4d05b41f..e26151d251b 100644 --- a/src/plugins/projectexplorer/devicesupport/deviceprocess.h +++ b/src/plugins/projectexplorer/devicesupport/deviceprocess.h @@ -57,6 +57,9 @@ public: virtual qint64 write(const QByteArray &data) = 0; + void setRunInTerminal(bool term) { m_runInTerminal = term; } + bool runInTerminal() const { return m_runInTerminal; } + signals: void started(); void finished(); @@ -71,6 +74,7 @@ protected: private: const QSharedPointer m_device; + bool m_runInTerminal = false; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp index 4f447214f5e..eda1dbc2c0e 100644 --- a/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp +++ b/src/plugins/projectexplorer/devicesupport/sshdeviceprocess.cpp @@ -31,12 +31,15 @@ #include #include #include +#include #include #include #include #include +using namespace Utils; + namespace ProjectExplorer { enum class Signal { Interrupt, Terminate, Kill }; @@ -49,6 +52,7 @@ public: SshDeviceProcess * const q; QSsh::SshConnection *connection = nullptr; QSsh::SshRemoteProcessPtr process; + ConsoleProcess consoleProcess; Runnable runnable; QString errorMessage; QProcess::ExitStatus exitStatus = QProcess::NormalExit; @@ -114,11 +118,15 @@ void SshDeviceProcess::interrupt() void SshDeviceProcess::terminate() { d->doSignal(Signal::Terminate); + if (runInTerminal()) + d->consoleProcess.stop(); } void SshDeviceProcess::kill() { d->doSignal(Signal::Kill); + if (runInTerminal()) + d->consoleProcess.stop(); } QProcess::ProcessState SshDeviceProcess::state() const @@ -178,15 +186,31 @@ void SshDeviceProcess::handleConnected() d->setState(SshDeviceProcessPrivate::Connected); d->process = d->connection->createRemoteProcess(fullCommandLine(d->runnable).toUtf8()); - connect(d->process.get(), &QSsh::SshRemoteProcess::started, this, &SshDeviceProcess::handleProcessStarted); - connect(d->process.get(), &QSsh::SshRemoteProcess::done, this, &SshDeviceProcess::handleProcessFinished); - connect(d->process.get(), &QSsh::SshRemoteProcess::readyReadStandardOutput, this, &SshDeviceProcess::handleStdout); - connect(d->process.get(), &QSsh::SshRemoteProcess::readyReadStandardError, this, &SshDeviceProcess::handleStderr); - const QString display = d->displayName(); if (!display.isEmpty()) d->process->requestX11Forwarding(display); - d->process->start(); + if (runInTerminal()) { + d->process->requestTerminal(); + const QStringList cmdLine = d->process->fullLocalCommandLine(); + connect(&d->consoleProcess, + static_cast(&ConsoleProcess::error), + this, &DeviceProcess::error); + connect(&d->consoleProcess, &ConsoleProcess::processStarted, + this, &SshDeviceProcess::handleProcessStarted); + connect(&d->consoleProcess, &ConsoleProcess::stubStopped, + this, [this] { handleProcessFinished(d->consoleProcess.errorString()); }); + d->consoleProcess.start(cmdLine.first(), cmdLine.mid(1).join(' ')); + } else { + connect(d->process.get(), &QSsh::SshRemoteProcess::started, + this, &SshDeviceProcess::handleProcessStarted); + connect(d->process.get(), &QSsh::SshRemoteProcess::done, + this, &SshDeviceProcess::handleProcessFinished); + connect(d->process.get(), &QSsh::SshRemoteProcess::readyReadStandardOutput, + this, &SshDeviceProcess::handleStdout); + connect(d->process.get(), &QSsh::SshRemoteProcess::readyReadStandardError, + this, &SshDeviceProcess::handleStderr); + d->process->start(); + } } void SshDeviceProcess::handleConnectionError() @@ -226,7 +250,7 @@ void SshDeviceProcess::handleProcessStarted() void SshDeviceProcess::handleProcessFinished(const QString &error) { d->errorMessage = error; - d->exitCode = d->process->exitCode(); + d->exitCode = runInTerminal() ? d->consoleProcess.exitCode() : d->process->exitCode(); d->setState(SshDeviceProcessPrivate::Inactive); emit finished(); } @@ -327,6 +351,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::setState(SshDeviceProcess::SshDe killOperation.clear(); } killTimer.stop(); + consoleProcess.disconnect(); if (process) process->disconnect(q); if (connection) { @@ -338,6 +363,7 @@ void SshDeviceProcess::SshDeviceProcessPrivate::setState(SshDeviceProcess::SshDe qint64 SshDeviceProcess::write(const QByteArray &data) { + QTC_ASSERT(!runInTerminal(), return -1); return d->process->write(data); } diff --git a/src/plugins/remotelinux/linuxdeviceprocess.cpp b/src/plugins/remotelinux/linuxdeviceprocess.cpp index 11f8624b9a1..a4e937a570f 100644 --- a/src/plugins/remotelinux/linuxdeviceprocess.cpp +++ b/src/plugins/remotelinux/linuxdeviceprocess.cpp @@ -54,7 +54,7 @@ void LinuxDeviceProcess::setRcFilesToSource(const QStringList &filePaths) QByteArray LinuxDeviceProcess::readAllStandardOutput() { QByteArray output = SshDeviceProcess::readAllStandardOutput(); - if (m_processId != 0) + if (m_processId != 0 || runInTerminal()) return output; m_processIdString.append(output); @@ -91,10 +91,12 @@ QString LinuxDeviceProcess::fullCommandLine(const Runnable &runnable) const envString.append(env.key(it)).append(QLatin1String("='")).append(env.value(it)) .append(QLatin1Char('\'')); } - fullCommandLine.append("echo $$ && "); + if (!runInTerminal()) + fullCommandLine.append("echo $$ && "); if (!envString.isEmpty()) fullCommandLine.append(envString); - fullCommandLine.append(" exec "); + if (!runInTerminal()) + fullCommandLine.append(" exec "); fullCommandLine.append(quote(runnable.executable)); if (!runnable.commandLineArguments.isEmpty()) { fullCommandLine.append(QLatin1Char(' ')); diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp index e19b5b34f43..8a89ac30add 100644 --- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp @@ -60,6 +60,8 @@ RemoteLinuxCustomRunConfiguration::RemoteLinuxCustomRunConfiguration(Target *tar addAspect(); addAspect(); + if (HostOsInfo::isAnyUnixHost()) + addAspect(); addAspect(target); if (Utils::HostOsInfo::isAnyUnixHost()) addAspect(); diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index d098e92493e..eebf891e91b 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -34,7 +34,7 @@ namespace RemoteLinux { namespace Internal { LinuxDeviceDebugSupport::LinuxDeviceDebugSupport(RunControl *runControl) - : DebuggerRunTool(runControl) + : DebuggerRunTool(runControl, nullptr, false) { setId("LinuxDeviceDebugSupport"); diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp index 9a1fcc542a6..b39ebc78469 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp @@ -38,6 +38,8 @@ #include +#include + using namespace ProjectExplorer; using namespace Utils; @@ -60,6 +62,8 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Core::I addAspect(); addAspect(); + if (HostOsInfo::isAnyUnixHost()) + addAspect(); addAspect(target); if (id == IdPrefix && Utils::HostOsInfo::isAnyUnixHost()) addAspect();