LinuxDevice: Use LinuxProcessImpl for opening terminal

Don't use SshDeviceProcess anymore for opening linux terminal.
Fix running the empty command so that it opens ssh shell.
Don't leak terminal processes on shutdown.

One issue is that terminals are closed when closing settings,
as settings dialog operate on a copy of device, and in case
of no modifications applied the copy is being deleted.
The current workaround is to press the "Apply" button
before closing the settings dialog. This issue is to be
addressed separately.

Change-Id: I3c48b035daf1d099a1e8fa0762a6d6d0eca9592c
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
Jarek Kobus
2022-04-28 21:11:20 +02:00
parent 62f6c1e1d6
commit 709492ef11

View File

@@ -463,6 +463,7 @@ public:
QThread m_shellThread; QThread m_shellThread;
ShellThreadHandler *m_handler = nullptr; ShellThreadHandler *m_handler = nullptr;
mutable QMutex m_shellMutex; mutable QMutex m_shellMutex;
QList<QtcProcess *> m_terminals;
}; };
// SshProcessImpl // SshProcessImpl
@@ -601,12 +602,14 @@ QString LinuxProcessImpl::fullCommandLine(const CommandLine &commandLine) const
{ {
CommandLine cmd; CommandLine cmd;
const QStringList rcFilesToSource = {"/etc/profile", "$HOME/.profile"}; if (!commandLine.isEmpty()) {
for (const QString &filePath : rcFilesToSource) { const QStringList rcFilesToSource = {"/etc/profile", "$HOME/.profile"};
cmd.addArgs({"test", "-f", filePath}); for (const QString &filePath : rcFilesToSource) {
cmd.addArgs("&&", CommandLine::Raw); cmd.addArgs({"test", "-f", filePath});
cmd.addArgs({".", filePath}); cmd.addArgs("&&", CommandLine::Raw);
cmd.addArgs(";", CommandLine::Raw); cmd.addArgs({".", filePath});
cmd.addArgs(";", CommandLine::Raw);
}
} }
if (!m_setup.m_workingDirectory.isEmpty()) { if (!m_setup.m_workingDirectory.isEmpty()) {
@@ -624,7 +627,8 @@ QString LinuxProcessImpl::fullCommandLine(const CommandLine &commandLine) const
if (m_setup.m_terminalMode == TerminalMode::Off) if (m_setup.m_terminalMode == TerminalMode::Off)
cmd.addArg("exec"); cmd.addArg("exec");
cmd.addCommandLineAsArgs(commandLine, CommandLine::Raw); if (!commandLine.isEmpty())
cmd.addCommandLineAsArgs(commandLine, CommandLine::Raw);
return cmd.arguments(); return cmd.arguments();
} }
@@ -1041,8 +1045,9 @@ LinuxDevice::LinuxDevice()
}}); }});
setOpenTerminal([this](const Environment &env, const FilePath &workingDir) { setOpenTerminal([this](const Environment &env, const FilePath &workingDir) {
QtcProcess * const proc = createProcess(nullptr); QtcProcess * const proc = new QtcProcess;
QObject::connect(proc, &QtcProcess::done, [proc] { d->m_terminals.append(proc);
QObject::connect(proc, &QtcProcess::done, [this, proc] {
if (proc->error() != QProcess::UnknownError) { if (proc->error() != QProcess::UnknownError) {
const QString errorString = proc->errorString(); const QString errorString = proc->errorString();
QString message; QString message;
@@ -1055,15 +1060,13 @@ LinuxDevice::LinuxDevice()
Core::MessageManager::writeDisrupting(message); Core::MessageManager::writeDisrupting(message);
} }
proc->deleteLater(); proc->deleteLater();
d->m_terminals.removeOne(proc);
}); });
// It seems we cannot pass an environment to OpenSSH dynamically proc->setCommand({ mapToGlobalPath({}), {}});
// without specifying an executable.
if (env.size() > 0)
proc->setCommand({"/bin/sh", {}});
proc->setTerminalMode(TerminalMode::On); proc->setTerminalMode(TerminalMode::On);
proc->setEnvironment(env); proc->setEnvironment(env);
proc->setRemoteEnvironment(env);
proc->setWorkingDirectory(workingDir); proc->setWorkingDirectory(workingDir);
proc->start(); proc->start();
}); });
@@ -1182,6 +1185,7 @@ LinuxDevicePrivate::LinuxDevicePrivate(LinuxDevice *parent)
LinuxDevicePrivate::~LinuxDevicePrivate() LinuxDevicePrivate::~LinuxDevicePrivate()
{ {
qDeleteAll(m_terminals);
auto closeShell = [this] { auto closeShell = [this] {
m_shellThread.quit(); m_shellThread.quit();
m_shellThread.wait(); m_shellThread.wait();