SSH: Improve SshRemoteProcessRunner API.

It's silly that we fix the connection parameters in the constructor. A
given object of the class, once created, should be able to repeatedly
run any command with any connection.

Change-Id: Ia45b9d5b6f25c25fb46751cdb47cf81877d8f9a9
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
Christian Kandeler
2011-11-09 14:19:50 +01:00
parent f9623b5ad6
commit fd26ab22e9
14 changed files with 116 additions and 172 deletions

View File

@@ -50,17 +50,14 @@ class SshRemoteProcessRunnerPrivate : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
SshRemoteProcessRunnerPrivate(const SshConnectionParameters &params, SshRemoteProcessRunnerPrivate(QObject *parent);
QObject *parent);
SshRemoteProcessRunnerPrivate(const SshConnection::Ptr &connection,
QObject *parent);
~SshRemoteProcessRunnerPrivate(); ~SshRemoteProcessRunnerPrivate();
void runWithoutTerminal(const QByteArray &command); void runWithoutTerminal(const QByteArray &command, const SshConnectionParameters &sshParams);
void runInTerminal(const QByteArray &command, void runInTerminal(const QByteArray &command, const SshPseudoTerminal &terminal,
const SshPseudoTerminal &terminal); const SshConnectionParameters &sshParams);
QByteArray command() const { return m_command; } QByteArray command() const { return m_command; }
const SshConnection::Ptr m_connection; SshConnection::Ptr m_connection;
SshRemoteProcess::Ptr m_process; SshRemoteProcess::Ptr m_process;
signals: signals:
@@ -80,34 +77,20 @@ private slots:
private: private:
enum State { Inactive, Connecting, Connected, ProcessRunning }; enum State { Inactive, Connecting, Connected, ProcessRunning };
void run(const QByteArray &command); void run(const QByteArray &command, const SshConnectionParameters &sshParams);
void setState(State state); void setState(State state);
void assertState(const QList<State> &allowedStates, const char *func); void assertState(const QList<State> &allowedStates, const char *func);
void assertState(State allowedState, const char *func); void assertState(State allowedState, const char *func);
State m_state; State m_state;
bool m_needsRelease;
bool m_runInTerminal; bool m_runInTerminal;
SshPseudoTerminal m_terminal; SshPseudoTerminal m_terminal;
QByteArray m_command; QByteArray m_command;
}; };
SshRemoteProcessRunnerPrivate::SshRemoteProcessRunnerPrivate(const SshConnectionParameters &params, SshRemoteProcessRunnerPrivate::SshRemoteProcessRunnerPrivate(QObject *parent)
QObject *parent) : QObject(parent), m_state(Inactive)
: QObject(parent),
m_connection(SshConnectionManager::instance().acquireConnection(params)),
m_state(Inactive),
m_needsRelease(true)
{
}
SshRemoteProcessRunnerPrivate::SshRemoteProcessRunnerPrivate(const SshConnection::Ptr &connection,
QObject *parent)
: QObject(parent),
m_connection(connection),
m_state(Inactive),
m_needsRelease(false)
{ {
} }
@@ -116,30 +99,32 @@ SshRemoteProcessRunnerPrivate::~SshRemoteProcessRunnerPrivate()
setState(Inactive); setState(Inactive);
} }
void SshRemoteProcessRunnerPrivate::runWithoutTerminal(const QByteArray &command) void SshRemoteProcessRunnerPrivate::runWithoutTerminal(const QByteArray &command,
const SshConnectionParameters &sshParams)
{ {
m_runInTerminal = false; m_runInTerminal = false;
run(command); run(command, sshParams);
} }
void SshRemoteProcessRunnerPrivate::runInTerminal(const QByteArray &command, void SshRemoteProcessRunnerPrivate::runInTerminal(const QByteArray &command,
const SshPseudoTerminal &terminal) const SshPseudoTerminal &terminal, const SshConnectionParameters &sshParams)
{ {
m_terminal = terminal; m_terminal = terminal;
m_runInTerminal = true; m_runInTerminal = true;
run(command); run(command, sshParams);
} }
void SshRemoteProcessRunnerPrivate::run(const QByteArray &command) void SshRemoteProcessRunnerPrivate::run(const QByteArray &command,
const SshConnectionParameters &sshParams)
{ {
ASSERT_STATE(Inactive); setState(Inactive);
setState(Connecting); setState(Connecting);
m_command = command; m_command = command;
m_connection = SshConnectionManager::instance().acquireConnection(sshParams);
connect(m_connection.data(), SIGNAL(error(Utils::SshError)), connect(m_connection.data(), SIGNAL(error(Utils::SshError)),
SLOT(handleConnectionError(Utils::SshError))); SLOT(handleConnectionError(Utils::SshError)));
connect(m_connection.data(), SIGNAL(disconnected()), connect(m_connection.data(), SIGNAL(disconnected()), SLOT(handleDisconnected()));
SLOT(handleDisconnected()));
if (m_connection->state() == SshConnection::Connected) { if (m_connection->state() == SshConnection::Connected) {
handleConnected(); handleConnected();
} else { } else {
@@ -212,9 +197,10 @@ void SshRemoteProcessRunnerPrivate::setState(State state)
if (m_state == Inactive) { if (m_state == Inactive) {
if (m_process) if (m_process)
disconnect(m_process.data(), 0, this, 0); disconnect(m_process.data(), 0, this, 0);
disconnect(m_connection.data(), 0, this, 0); if (m_connection) {
if (m_needsRelease) disconnect(m_connection.data(), 0, this, 0);
SshConnectionManager::instance().releaseConnection(m_connection); SshConnectionManager::instance().releaseConnection(m_connection);
}
} }
} }
} }
@@ -234,21 +220,8 @@ void SshRemoteProcessRunnerPrivate::assertState(State allowedState,
} // namespace Internal } // namespace Internal
SshRemoteProcessRunner::SshRemoteProcessRunner(const SshConnectionParameters &params, SshRemoteProcessRunner::SshRemoteProcessRunner(QObject *parent)
QObject *parent) : QObject(parent), d(new Internal::SshRemoteProcessRunnerPrivate(this))
: QObject(parent), d(new Internal::SshRemoteProcessRunnerPrivate(params, this))
{
init();
}
SshRemoteProcessRunner::SshRemoteProcessRunner(const SshConnection::Ptr &connection,
QObject *parent)
: QObject(parent), d(new Internal::SshRemoteProcessRunnerPrivate(connection, this))
{
init();
}
void SshRemoteProcessRunner::init()
{ {
connect(d, SIGNAL(connectionError(Utils::SshError)), connect(d, SIGNAL(connectionError(Utils::SshError)),
SIGNAL(connectionError(Utils::SshError))); SIGNAL(connectionError(Utils::SshError)));
@@ -260,15 +233,15 @@ void SshRemoteProcessRunner::init()
SIGNAL(processErrorOutputAvailable(QByteArray))); SIGNAL(processErrorOutputAvailable(QByteArray)));
} }
void SshRemoteProcessRunner::run(const QByteArray &command) void SshRemoteProcessRunner::run(const QByteArray &command, const SshConnectionParameters &params)
{ {
d->runWithoutTerminal(command); d->runWithoutTerminal(command, params);
} }
void SshRemoteProcessRunner::runInTerminal(const QByteArray &command, void SshRemoteProcessRunner::runInTerminal(const QByteArray &command,
const SshPseudoTerminal &terminal) const SshPseudoTerminal &terminal, const SshConnectionParameters &params)
{ {
d->runInTerminal(command, terminal); d->runInTerminal(command, terminal, params);
} }
QByteArray SshRemoteProcessRunner::command() const { return d->command(); } QByteArray SshRemoteProcessRunner::command() const { return d->command(); }

View File

@@ -46,12 +46,11 @@ class QTCREATOR_UTILS_EXPORT SshRemoteProcessRunner : public QObject
Q_OBJECT Q_OBJECT
public: public:
SshRemoteProcessRunner(const SshConnectionParameters &params, QObject *parent = 0); SshRemoteProcessRunner(QObject *parent = 0);
SshRemoteProcessRunner(const SshConnection::Ptr &connection, QObject *parent = 0);
void run(const QByteArray &command); void run(const QByteArray &command, const SshConnectionParameters &params);
void runInTerminal(const QByteArray &command, void runInTerminal(const QByteArray &command, const SshPseudoTerminal &terminal,
const SshPseudoTerminal &terminal); const SshConnectionParameters &params);
QByteArray command() const; QByteArray command() const;
SshConnection::Ptr connection() const; SshConnection::Ptr connection() const;
@@ -65,9 +64,8 @@ signals:
void processClosed(int exitStatus); // values are of type SshRemoteProcess::ExitStatus void processClosed(int exitStatus); // values are of type SshRemoteProcess::ExitStatus
private: private:
void init();
Internal::SshRemoteProcessRunnerPrivate *d; Internal::SshRemoteProcessRunnerPrivate * const d;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -151,11 +151,10 @@ LldbEngineHost::LldbEngineHost(const DebuggerStartParameters &startParameters)
if (startParameters.startMode == StartRemoteEngine) if (startParameters.startMode == StartRemoteEngine)
{ {
m_guestProcess = 0; m_guestProcess = 0;
Utils::SshRemoteProcessRunner * const runner = Utils::SshRemoteProcessRunner * const runner = new Utils::SshRemoteProcessRunner;
new Utils::SshRemoteProcessRunner(startParameters.connParams);
connect (runner, SIGNAL(connectionError(Utils::SshError)), connect (runner, SIGNAL(connectionError(Utils::SshError)),
this, SLOT(sshConnectionError(Utils::SshError))); this, SLOT(sshConnectionError(Utils::SshError)));
runner->run(startParameters.serverStartScript.toUtf8()); runner->run(startParameters.serverStartScript.toUtf8(), startParameters.connParams);
setGuestDevice(new SshIODevice(runner)); setGuestDevice(new SshIODevice(runner));
} else { } else {
m_guestProcess = new QProcess(this); m_guestProcess = new QProcess(this);

View File

@@ -107,8 +107,8 @@ void MaddeDeviceTester::handleGenericTestFinished(TestResult result)
return; return;
} }
delete m_processRunner; if (!m_processRunner)
m_processRunner = new SshRemoteProcessRunner(m_genericTester->connection(), this); m_processRunner = new SshRemoteProcessRunner(this);
connect(m_processRunner, SIGNAL(connectionError(Utils::SshError)), connect(m_processRunner, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError())); SLOT(handleConnectionError()));
connect(m_processRunner, SIGNAL(processOutputAvailable(QByteArray)), connect(m_processRunner, SIGNAL(processOutputAvailable(QByteArray)),
@@ -129,7 +129,7 @@ void MaddeDeviceTester::handleGenericTestFinished(TestResult result)
m_stdout.clear(); m_stdout.clear();
m_stderr.clear(); m_stderr.clear();
m_state = QtTest; m_state = QtTest;
m_processRunner->run(qtInfoCmd.toUtf8()); m_processRunner->run(qtInfoCmd.toUtf8(), m_genericTester->connection()->connectionParameters());
} }
void MaddeDeviceTester::handleConnectionError() void MaddeDeviceTester::handleConnectionError()
@@ -196,7 +196,8 @@ void MaddeDeviceTester::handleQtTestFinished(int exitStatus)
emit progressMessage(tr("Checking for connectivity support...")); emit progressMessage(tr("Checking for connectivity support..."));
m_state = MadDeveloperTest; m_state = MadDeveloperTest;
m_processRunner->run(QString(QLatin1String("test -x") + MaemoGlobal::devrootshPath()).toUtf8()); m_processRunner->run(QString(QLatin1String("test -x") + MaemoGlobal::devrootshPath()).toUtf8(),
m_genericTester->connection()->connectionParameters());
} }
void MaddeDeviceTester::handleMadDeveloperTestFinished(int exitStatus) void MaddeDeviceTester::handleMadDeveloperTestFinished(int exitStatus)
@@ -233,7 +234,8 @@ void MaddeDeviceTester::handleMadDeveloperTestFinished(int exitStatus)
emit progressMessage(tr("Checking for QML tooling support...")); emit progressMessage(tr("Checking for QML tooling support..."));
m_state = QmlToolingTest; m_state = QmlToolingTest;
m_processRunner->run(QString(QLatin1String("test -d ") m_processRunner->run(QString(QLatin1String("test -d ")
+ QLatin1String(QmlToolingDirectory)).toUtf8()); + QLatin1String(QmlToolingDirectory)).toUtf8(),
m_genericTester->connection()->connectionParameters());
} }
void MaddeDeviceTester::handleQmlToolingTestFinished(int exitStatus) void MaddeDeviceTester::handleQmlToolingTestFinished(int exitStatus)
@@ -285,8 +287,6 @@ QString MaddeDeviceTester::processedQtLibsList()
disconnect(m_genericTester, 0, this, 0); disconnect(m_genericTester, 0, this, 0);
if (m_processRunner) if (m_processRunner)
disconnect(m_processRunner, 0, this, 0); disconnect(m_processRunner, 0, this, 0);
delete m_processRunner;
m_processRunner = 0;
emit finished(m_result); emit finished(m_result);
} }

View File

@@ -385,8 +385,8 @@ void MaemoPublisherFremantleFree::runDpkgBuildPackage()
// webmaster refuses to enable SFTP "for security reasons" ... // webmaster refuses to enable SFTP "for security reasons" ...
void MaemoPublisherFremantleFree::uploadPackage() void MaemoPublisherFremantleFree::uploadPackage()
{ {
delete m_uploader; if (!m_uploader)
m_uploader = new SshRemoteProcessRunner(m_sshParams, this); m_uploader = new SshRemoteProcessRunner(this);
connect(m_uploader, SIGNAL(processStarted()), SLOT(handleScpStarted())); connect(m_uploader, SIGNAL(processStarted()), SLOT(handleScpStarted()));
connect(m_uploader, SIGNAL(connectionError(Utils::SshError)), connect(m_uploader, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError())); SLOT(handleConnectionError()));
@@ -395,7 +395,7 @@ void MaemoPublisherFremantleFree::uploadPackage()
SLOT(handleScpStdOut(QByteArray))); SLOT(handleScpStdOut(QByteArray)));
emit progressReport(tr("Starting scp ...")); emit progressReport(tr("Starting scp ..."));
setState(StartingScp); setState(StartingScp);
m_uploader->run("scp -td " + m_remoteDir.toUtf8()); m_uploader->run("scp -td " + m_remoteDir.toUtf8(), m_sshParams);
} }
void MaemoPublisherFremantleFree::handleScpStarted() void MaemoPublisherFremantleFree::handleScpStarted()
@@ -633,8 +633,6 @@ void MaemoPublisherFremantleFree::setState(State newState)
// an illegal sequence of bytes? (Probably not, if // an illegal sequence of bytes? (Probably not, if
// we are currently uploading a file.) // we are currently uploading a file.)
disconnect(m_uploader, 0, this, 0); disconnect(m_uploader, 0, this, 0);
delete m_uploader;
m_uploader = 0;
break; break;
default: default:
break; break;

View File

@@ -46,7 +46,7 @@ namespace Madde {
namespace Internal { namespace Internal {
MaemoRemoteCopyFacility::MaemoRemoteCopyFacility(QObject *parent) : MaemoRemoteCopyFacility::MaemoRemoteCopyFacility(QObject *parent) :
QObject(parent), m_copyRunner(0), m_isCopying(false) QObject(parent), m_copyRunner(0), m_killProcess(0), m_isCopying(false)
{ {
} }
@@ -63,8 +63,8 @@ void MaemoRemoteCopyFacility::copyFiles(const SshConnection::Ptr &connection,
m_deployables = deployables; m_deployables = deployables;
m_mountPoint = mountPoint; m_mountPoint = mountPoint;
delete m_copyRunner; if (!m_copyRunner)
m_copyRunner = new SshRemoteProcessRunner(connection, this); m_copyRunner = new SshRemoteProcessRunner(this);
connect(m_copyRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError())); connect(m_copyRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError()));
connect(m_copyRunner, SIGNAL(processOutputAvailable(QByteArray)), connect(m_copyRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdout(QByteArray))); SLOT(handleRemoteStdout(QByteArray)));
@@ -80,10 +80,9 @@ void MaemoRemoteCopyFacility::cancel()
{ {
Q_ASSERT(m_isCopying); Q_ASSERT(m_isCopying);
// TODO: Make member as to not waste memory. if (!m_killProcess)
SshRemoteProcessRunner * const killProcess m_killProcess = new SshRemoteProcessRunner(this);
= new SshRemoteProcessRunner(m_copyRunner->connection(), this); m_killProcess->run("pkill cp", m_devConf->sshParameters());
killProcess->run("pkill cp");
setFinished(); setFinished();
} }
@@ -140,19 +139,16 @@ void MaemoRemoteCopyFacility::copyNextFile()
#endif #endif
QString command = QString::fromLatin1("%1 mkdir -p %3 && %1 cp -a %2 %3") QString command = QString::fromLatin1("%1 mkdir -p %3 && %1 cp -a %2 %3")
.arg(MaemoGlobal::remoteSudo(m_devConf->osType(), .arg(MaemoGlobal::remoteSudo(m_devConf->osType(), m_devConf->sshParameters().userName),
m_copyRunner->connection()->connectionParameters().userName),
sourceFilePath, d.remoteDir); sourceFilePath, d.remoteDir);
emit progress(tr("Copying file '%1' to directory '%2' on the device...") emit progress(tr("Copying file '%1' to directory '%2' on the device...")
.arg(d.localFilePath, d.remoteDir)); .arg(d.localFilePath, d.remoteDir));
m_copyRunner->run(command.toUtf8()); m_copyRunner->run(command.toUtf8(), m_devConf->sshParameters());
} }
void MaemoRemoteCopyFacility::setFinished() void MaemoRemoteCopyFacility::setFinished()
{ {
disconnect(m_copyRunner, 0, this, 0); disconnect(m_copyRunner, 0, this, 0);
delete m_copyRunner;
m_copyRunner = 0;
m_deployables.clear(); m_deployables.clear();
m_isCopying = false; m_isCopying = false;
} }

View File

@@ -82,6 +82,7 @@ private:
void setFinished(); void setFinished();
Utils::SshRemoteProcessRunner *m_copyRunner; Utils::SshRemoteProcessRunner *m_copyRunner;
Utils::SshRemoteProcessRunner *m_killProcess;
QSharedPointer<const RemoteLinux::LinuxDeviceConfiguration> m_devConf; QSharedPointer<const RemoteLinux::LinuxDeviceConfiguration> m_devConf;
QList<RemoteLinux::DeployableFile> m_deployables; QList<RemoteLinux::DeployableFile> m_deployables;
QString m_mountPoint; QString m_mountPoint;

View File

@@ -31,6 +31,8 @@
**************************************************************************/ **************************************************************************/
#include "remotelinuxcustomcommanddeployservice.h" #include "remotelinuxcustomcommanddeployservice.h"
#include "linuxdeviceconfiguration.h"
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/ssh/sshremoteprocessrunner.h> #include <utils/ssh/sshremoteprocessrunner.h>
@@ -95,8 +97,8 @@ void RemoteLinuxCustomCommandDeployService::doDeploy()
{ {
QTC_ASSERT(d->state == Inactive, handleDeploymentDone()); QTC_ASSERT(d->state == Inactive, handleDeploymentDone());
delete d->runner; if (!d->runner)
d->runner = new SshRemoteProcessRunner(connection(), this); d->runner = new SshRemoteProcessRunner(this);
connect(d->runner, SIGNAL(processOutputAvailable(QByteArray)), connect(d->runner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleStdout(QByteArray))); SLOT(handleStdout(QByteArray)));
connect(d->runner, SIGNAL(processErrorOutputAvailable(QByteArray)), connect(d->runner, SIGNAL(processErrorOutputAvailable(QByteArray)),
@@ -105,7 +107,7 @@ void RemoteLinuxCustomCommandDeployService::doDeploy()
emit progressMessage(tr("Starting remote command '%1'...").arg(d->commandLine)); emit progressMessage(tr("Starting remote command '%1'...").arg(d->commandLine));
d->state = Running; d->state = Running;
d->runner->run(d->commandLine.toUtf8()); d->runner->run(d->commandLine.toUtf8(), deviceConfiguration()->sshParameters());
} }
void RemoteLinuxCustomCommandDeployService::stopDeployment() void RemoteLinuxCustomCommandDeployService::stopDeployment()
@@ -114,8 +116,6 @@ void RemoteLinuxCustomCommandDeployService::stopDeployment()
disconnect(d->runner, 0, this, 0); disconnect(d->runner, 0, this, 0);
d->runner->process()->closeChannel(); d->runner->process()->closeChannel();
delete d->runner;
d->runner = 0;
d->state = Inactive; d->state = Inactive;
handleDeploymentDone(); handleDeploymentDone();
} }

View File

@@ -59,13 +59,8 @@ void RemoteLinuxEnvironmentReader::start(const QString &environmentSetupCommand)
if (!m_devConfig) if (!m_devConfig)
return; return;
m_stop = false; m_stop = false;
if (!m_remoteProcessRunner if (!m_remoteProcessRunner)
|| m_remoteProcessRunner->connection()->state() != Utils::SshConnection::Connected m_remoteProcessRunner = new Utils::SshRemoteProcessRunner(this);
|| m_remoteProcessRunner->connection()->connectionParameters() != m_devConfig->sshParameters()) {
delete m_remoteProcessRunner;
m_remoteProcessRunner
= new Utils::SshRemoteProcessRunner(m_devConfig->sshParameters(), this);
}
connect(m_remoteProcessRunner, SIGNAL(connectionError(Utils::SshError)), connect(m_remoteProcessRunner, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionFailure())); SLOT(handleConnectionFailure()));
connect(m_remoteProcessRunner, SIGNAL(processClosed(int)), SLOT(remoteProcessFinished(int))); connect(m_remoteProcessRunner, SIGNAL(processClosed(int)), SLOT(remoteProcessFinished(int)));
@@ -76,7 +71,7 @@ void RemoteLinuxEnvironmentReader::start(const QString &environmentSetupCommand)
const QByteArray remoteCall const QByteArray remoteCall
= QString(environmentSetupCommand + QLatin1String("; env")).toUtf8(); = QString(environmentSetupCommand + QLatin1String("; env")).toUtf8();
m_remoteOutput.clear(); m_remoteOutput.clear();
m_remoteProcessRunner->run(remoteCall); m_remoteProcessRunner->run(remoteCall, m_devConfig->sshParameters());
} }
void RemoteLinuxEnvironmentReader::stop() void RemoteLinuxEnvironmentReader::stop()

View File

@@ -71,8 +71,8 @@ void AbstractRemoteLinuxPackageInstaller::installPackage(const SshConnection::Pt
&& !d->isRunning, return); && !d->isRunning, return);
prepareInstallation(); prepareInstallation();
delete d->installer; if (!d->installer)
d->installer = new SshRemoteProcessRunner(connection, this); d->installer = new SshRemoteProcessRunner(this);
connect(d->installer, SIGNAL(connectionError(Utils::SshError)), connect(d->installer, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError())); SLOT(handleConnectionError()));
connect(d->installer, SIGNAL(processOutputAvailable(QByteArray)), connect(d->installer, SIGNAL(processOutputAvailable(QByteArray)),
@@ -84,7 +84,7 @@ void AbstractRemoteLinuxPackageInstaller::installPackage(const SshConnection::Pt
QString cmdLine = installCommandLine(packageFilePath); QString cmdLine = installCommandLine(packageFilePath);
if (removePackageFile) if (removePackageFile)
cmdLine += QLatin1String(" && (rm ") + packageFilePath + QLatin1String(" || :)"); cmdLine += QLatin1String(" && (rm ") + packageFilePath + QLatin1String(" || :)");
d->installer->run(cmdLine.toUtf8()); d->installer->run(cmdLine.toUtf8(), connection->connectionParameters());
d->isRunning = true; d->isRunning = true;
} }
@@ -93,9 +93,10 @@ void AbstractRemoteLinuxPackageInstaller::cancelInstallation()
QTC_ASSERT(d->installer && d->installer->connection()->state() == SshConnection::Connected QTC_ASSERT(d->installer && d->installer->connection()->state() == SshConnection::Connected
&& d->isRunning, return); && d->isRunning, return);
delete d->killProcess; if (!d->killProcess)
d->killProcess = new SshRemoteProcessRunner(d->installer->connection(), this); d->killProcess = new SshRemoteProcessRunner(this);
d->killProcess->run(cancelInstallationCommandLine().toUtf8()); d->killProcess->run(cancelInstallationCommandLine().toUtf8(),
d->installer->connection()->connectionParameters());
setFinished(); setFinished();
} }
@@ -137,8 +138,6 @@ void AbstractRemoteLinuxPackageInstaller::handleInstallerErrorOutput(const QByte
void AbstractRemoteLinuxPackageInstaller::setFinished() void AbstractRemoteLinuxPackageInstaller::setFinished()
{ {
disconnect(d->installer, 0, this, 0); disconnect(d->installer, 0, this, 0);
delete d->installer;
d->installer = 0;
d->isRunning = false; d->isRunning = false;
} }

View File

@@ -52,15 +52,13 @@ class AbstractRemoteLinuxProcessListPrivate
public: public:
AbstractRemoteLinuxProcessListPrivate(const LinuxDeviceConfiguration::ConstPtr &devConf) AbstractRemoteLinuxProcessListPrivate(const LinuxDeviceConfiguration::ConstPtr &devConf)
: deviceConfiguration(devConf), : deviceConfiguration(devConf),
process(new SshRemoteProcessRunner(devConf->sshParameters())),
state(Inactive) state(Inactive)
{ {
} }
~AbstractRemoteLinuxProcessListPrivate() { delete process; }
const LinuxDeviceConfiguration::ConstPtr deviceConfiguration; const LinuxDeviceConfiguration::ConstPtr deviceConfiguration;
SshRemoteProcessRunner * const process; SshRemoteProcessRunner process;
QList<AbstractRemoteLinuxProcessList::RemoteProcess> remoteProcesses; QList<AbstractRemoteLinuxProcessList::RemoteProcess> remoteProcesses;
QByteArray remoteStdout; QByteArray remoteStdout;
QByteArray remoteStderr; QByteArray remoteStderr;
@@ -156,7 +154,7 @@ void AbstractRemoteLinuxProcessList::handleConnectionError()
{ {
QTC_ASSERT(d->state != Inactive, return); QTC_ASSERT(d->state != Inactive, return);
emit error(tr("Connection failure: %1").arg(d->process->connection()->errorString())); emit error(tr("Connection failure: %1").arg(d->process.connection()->errorString()));
beginResetModel(); beginResetModel();
d->remoteProcesses.clear(); d->remoteProcesses.clear();
endResetModel(); endResetModel();
@@ -170,14 +168,14 @@ void AbstractRemoteLinuxProcessList::handleRemoteProcessFinished(int exitStatus)
switch (exitStatus) { switch (exitStatus) {
case SshRemoteProcess::FailedToStart: case SshRemoteProcess::FailedToStart:
d->errorMsg = tr("Error: Remote process failed to start: %1") d->errorMsg = tr("Error: Remote process failed to start: %1")
.arg(d->process->process()->errorString()); .arg(d->process.process()->errorString());
break; break;
case SshRemoteProcess::KilledBySignal: case SshRemoteProcess::KilledBySignal:
d->errorMsg = tr("Error: Remote process crashed: %1") d->errorMsg = tr("Error: Remote process crashed: %1")
.arg(d->process->process()->errorString()); .arg(d->process.process()->errorString());
break; break;
case SshRemoteProcess::ExitedNormally: case SshRemoteProcess::ExitedNormally:
if (d->process->process()->exitCode() == 0) { if (d->process.process()->exitCode() == 0) {
if (d->state == Listing) { if (d->state == Listing) {
d->remoteProcesses = buildProcessList(QString::fromUtf8(d->remoteStdout.data(), d->remoteProcesses = buildProcessList(QString::fromUtf8(d->remoteStdout.data(),
d->remoteStdout.count())); d->remoteStdout.count()));
@@ -206,23 +204,23 @@ void AbstractRemoteLinuxProcessList::handleRemoteProcessFinished(int exitStatus)
void AbstractRemoteLinuxProcessList::startProcess(const QString &cmdLine) void AbstractRemoteLinuxProcessList::startProcess(const QString &cmdLine)
{ {
connect(d->process, SIGNAL(connectionError(Utils::SshError)), connect(&d->process, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionError())); SLOT(handleConnectionError()));
connect(d->process, SIGNAL(processOutputAvailable(QByteArray)), connect(&d->process, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdOut(QByteArray))); SLOT(handleRemoteStdOut(QByteArray)));
connect(d->process, SIGNAL(processErrorOutputAvailable(QByteArray)), connect(&d->process, SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleRemoteStdErr(QByteArray))); SLOT(handleRemoteStdErr(QByteArray)));
connect(d->process, SIGNAL(processClosed(int)), connect(&d->process, SIGNAL(processClosed(int)),
SLOT(handleRemoteProcessFinished(int))); SLOT(handleRemoteProcessFinished(int)));
d->remoteStdout.clear(); d->remoteStdout.clear();
d->remoteStderr.clear(); d->remoteStderr.clear();
d->errorMsg.clear(); d->errorMsg.clear();
d->process->run(cmdLine.toUtf8()); d->process.run(cmdLine.toUtf8(), d->deviceConfiguration->sshParameters());
} }
void AbstractRemoteLinuxProcessList::setFinished() void AbstractRemoteLinuxProcessList::setFinished()
{ {
disconnect(d->process, 0, this, 0); disconnect(&d->process, 0, this, 0);
d->state = Inactive; d->state = Inactive;
} }

View File

@@ -45,9 +45,9 @@ namespace Internal {
class RemoteLinuxUsedPortsGathererPrivate class RemoteLinuxUsedPortsGathererPrivate
{ {
public: public:
RemoteLinuxUsedPortsGathererPrivate() : procRunner(0), running(false) {} RemoteLinuxUsedPortsGathererPrivate() : running(false) {}
SshRemoteProcessRunner *procRunner; SshRemoteProcessRunner procRunner;
PortList portsToCheck; PortList portsToCheck;
QList<int> usedPorts; QList<int> usedPorts;
QByteArray remoteStdout; QByteArray remoteStdout;
@@ -78,13 +78,11 @@ void RemoteLinuxUsedPortsGatherer::start(const Utils::SshConnection::Ptr &connec
d->usedPorts.clear(); d->usedPorts.clear();
d->remoteStdout.clear(); d->remoteStdout.clear();
d->remoteStderr.clear(); d->remoteStderr.clear();
delete d->procRunner; connect(&d->procRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError()));
d->procRunner = new SshRemoteProcessRunner(connection, this); connect(&d->procRunner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
connect(d->procRunner, SIGNAL(connectionError(Utils::SshError)), SLOT(handleConnectionError())); connect(&d->procRunner, SIGNAL(processOutputAvailable(QByteArray)),
connect(d->procRunner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
connect(d->procRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdOut(QByteArray))); SLOT(handleRemoteStdOut(QByteArray)));
connect(d->procRunner, SIGNAL(processErrorOutputAvailable(QByteArray)), connect(&d->procRunner, SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleRemoteStdErr(QByteArray))); SLOT(handleRemoteStdErr(QByteArray)));
QString procFilePath; QString procFilePath;
int addressLength; int addressLength;
@@ -98,7 +96,10 @@ void RemoteLinuxUsedPortsGatherer::start(const Utils::SshConnection::Ptr &connec
const QString command = QString::fromLocal8Bit("sed " const QString command = QString::fromLocal8Bit("sed "
"'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2") "'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2")
.arg(addressLength).arg(procFilePath); .arg(addressLength).arg(procFilePath);
d->procRunner->run(command.toUtf8());
// TODO: We should not use an SshRemoteProcessRunner here, because we have to check
// for the type of the connection before we can say what the exact command line is.
d->procRunner.run(command.toUtf8(), connection->connectionParameters());
d->running = true; d->running = true;
} }
@@ -107,9 +108,7 @@ void RemoteLinuxUsedPortsGatherer::stop()
if (!d->running) if (!d->running)
return; return;
d->running = false; d->running = false;
disconnect(d->procRunner->connection().data(), 0, this, 0); disconnect(&d->procRunner, 0, this, 0);
if (d->procRunner->process())
d->procRunner->process()->closeChannel();
} }
int RemoteLinuxUsedPortsGatherer::getNextFreePort(PortList *freePorts) const int RemoteLinuxUsedPortsGatherer::getNextFreePort(PortList *freePorts) const
@@ -151,8 +150,7 @@ void RemoteLinuxUsedPortsGatherer::handleConnectionError()
{ {
if (!d->running) if (!d->running)
return; return;
emit error(tr("Connection error: %1"). emit error(tr("Connection error: %1").arg(d->procRunner.connection()->errorString()));
arg(d->procRunner->connection()->errorString()));
stop(); stop();
} }
@@ -164,18 +162,18 @@ void RemoteLinuxUsedPortsGatherer::handleProcessClosed(int exitStatus)
switch (exitStatus) { switch (exitStatus) {
case SshRemoteProcess::FailedToStart: case SshRemoteProcess::FailedToStart:
errMsg = tr("Could not start remote process: %1") errMsg = tr("Could not start remote process: %1")
.arg(d->procRunner->process()->errorString()); .arg(d->procRunner.process()->errorString());
break; break;
case SshRemoteProcess::KilledBySignal: case SshRemoteProcess::KilledBySignal:
errMsg = tr("Remote process crashed: %1") errMsg = tr("Remote process crashed: %1")
.arg(d->procRunner->process()->errorString()); .arg(d->procRunner.process()->errorString());
break; break;
case SshRemoteProcess::ExitedNormally: case SshRemoteProcess::ExitedNormally:
if (d->procRunner->process()->exitCode() == 0) { if (d->procRunner.process()->exitCode() == 0) {
setupUsedPorts(); setupUsedPorts();
} else { } else {
errMsg = tr("Remote process failed; exit code was %1.") errMsg = tr("Remote process failed; exit code was %1.")
.arg(d->procRunner->process()->exitCode()); .arg(d->procRunner.process()->exitCode());
} }
break; break;
default: default:

View File

@@ -44,8 +44,7 @@ namespace Internal {
class SshKeyDeployerPrivate class SshKeyDeployerPrivate
{ {
public: public:
SshKeyDeployerPrivate() : deployProcess(0) {} SshRemoteProcessRunner deployProcess;
SshRemoteProcessRunner *deployProcess;
}; };
} // namespace Internal } // namespace Internal
@@ -65,8 +64,6 @@ void SshKeyDeployer::deployPublicKey(const SshConnectionParameters &sshParams,
const QString &keyFilePath) const QString &keyFilePath)
{ {
cleanup(); cleanup();
delete d->deployProcess;
d->deployProcess = new SshRemoteProcessRunner(sshParams, this);
Utils::FileReader reader; Utils::FileReader reader;
if (!reader.fetch(keyFilePath)) { if (!reader.fetch(keyFilePath)) {
@@ -74,20 +71,18 @@ void SshKeyDeployer::deployPublicKey(const SshConnectionParameters &sshParams,
return; return;
} }
connect(d->deployProcess, SIGNAL(connectionError(Utils::SshError)), connect(&d->deployProcess, SIGNAL(connectionError(Utils::SshError)),
SLOT(handleConnectionFailure())); SLOT(handleConnectionFailure()));
connect(d->deployProcess, SIGNAL(processClosed(int)), SLOT(handleKeyUploadFinished(int))); connect(&d->deployProcess, SIGNAL(processClosed(int)), SLOT(handleKeyUploadFinished(int)));
const QByteArray command = "test -d .ssh " const QByteArray command = "test -d .ssh "
"|| mkdir .ssh && chmod 0700 .ssh && echo '" "|| mkdir .ssh && chmod 0700 .ssh && echo '"
+ reader.data() + "' >> .ssh/authorized_keys && chmod 0600 .ssh/authorized_keys"; + reader.data() + "' >> .ssh/authorized_keys && chmod 0600 .ssh/authorized_keys";
d->deployProcess->run(command); d->deployProcess.run(command, sshParams);
} }
void SshKeyDeployer::handleConnectionFailure() void SshKeyDeployer::handleConnectionFailure()
{ {
if (!d->deployProcess) const QString errorMsg = d->deployProcess.connection()->errorString();
return;
const QString errorMsg = d->deployProcess->connection()->errorString();
cleanup(); cleanup();
emit error(tr("Connection failed: %1").arg(errorMsg)); emit error(tr("Connection failed: %1").arg(errorMsg));
} }
@@ -98,11 +93,11 @@ void SshKeyDeployer::handleKeyUploadFinished(int exitStatus)
|| exitStatus == SshRemoteProcess::KilledBySignal || exitStatus == SshRemoteProcess::KilledBySignal
|| exitStatus == SshRemoteProcess::ExitedNormally); || exitStatus == SshRemoteProcess::ExitedNormally);
if (!d->deployProcess) if (!d->deployProcess.process())
return; return;
const int exitCode = d->deployProcess->process()->exitCode(); const int exitCode = d->deployProcess.process()->exitCode();
const QString errorMsg = d->deployProcess->process()->errorString(); const QString errorMsg = d->deployProcess.process()->errorString();
cleanup(); cleanup();
if (exitStatus == SshRemoteProcess::ExitedNormally && exitCode == 0) if (exitStatus == SshRemoteProcess::ExitedNormally && exitCode == 0)
emit finishedSuccessfully(); emit finishedSuccessfully();
@@ -117,11 +112,7 @@ void SshKeyDeployer::stopDeployment()
void SshKeyDeployer::cleanup() void SshKeyDeployer::cleanup()
{ {
if (d->deployProcess) { disconnect(&d->deployProcess, 0, this, 0);
disconnect(d->deployProcess, 0, this, 0);
delete d->deployProcess;
d->deployProcess = 0;
}
} }
} // namespace RemoteLinux } // namespace RemoteLinux

View File

@@ -53,7 +53,7 @@ namespace Internal {
class StartGdbServerDialogPrivate class StartGdbServerDialogPrivate
{ {
public: public:
StartGdbServerDialogPrivate() : processList(0), runner(0) {} StartGdbServerDialogPrivate() : processList(0) {}
LinuxDeviceConfiguration::ConstPtr currentDevice() const LinuxDeviceConfiguration::ConstPtr currentDevice() const
{ {
@@ -65,7 +65,7 @@ public:
QSortFilterProxyModel proxyModel; QSortFilterProxyModel proxyModel;
Ui::StartGdbServerDialog ui; Ui::StartGdbServerDialog ui;
RemoteLinuxUsedPortsGatherer gatherer; RemoteLinuxUsedPortsGatherer gatherer;
Utils::SshRemoteProcessRunner *runner; Utils::SshRemoteProcessRunner runner;
}; };
} // namespace Internal } // namespace Internal
@@ -203,7 +203,7 @@ void StartGdbServerDialog::startGdbServer()
void StartGdbServerDialog::handleConnectionError() void StartGdbServerDialog::handleConnectionError()
{ {
d->ui.textBrowser->append(tr("Connection error: %1") d->ui.textBrowser->append(tr("Connection error: %1")
.arg(d->runner->connection()->errorString())); .arg(d->runner.connection()->errorString()));
emit processAborted(); emit processAborted();
} }
@@ -238,20 +238,18 @@ void StartGdbServerDialog::handleProcessClosed(int status)
void StartGdbServerDialog::startGdbServerOnPort(int port, int pid) void StartGdbServerDialog::startGdbServerOnPort(int port, int pid)
{ {
LinuxDeviceConfiguration::ConstPtr device = d->currentDevice(); LinuxDeviceConfiguration::ConstPtr device = d->currentDevice();
delete d->runner; connect(&d->runner, SIGNAL(connectionError(Utils::SshError)),
d->runner = new Utils::SshRemoteProcessRunner(device->sshParameters(), this); SLOT(handleConnectionError()));
connect(d->runner, SIGNAL(connectionError(Utils::SshError)), connect(&d->runner, SIGNAL(processStarted()), SLOT(handleProcessStarted()));
SLOT(handleConnectionError())); connect(&d->runner, SIGNAL(processOutputAvailable(QByteArray)),
connect(d->runner, SIGNAL(processStarted()), SLOT(handleProcessStarted())); SLOT(handleProcessOutputAvailable(QByteArray)));
connect(d->runner, SIGNAL(processOutputAvailable(QByteArray)), connect(&d->runner, SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleProcessOutputAvailable(QByteArray))); SLOT(handleProcessErrorOutput(QByteArray)));
connect(d->runner, SIGNAL(processErrorOutputAvailable(QByteArray)), connect(&d->runner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
SLOT(handleProcessErrorOutput(QByteArray)));
connect(d->runner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
QByteArray cmd = "/usr/bin/gdbserver --attach localhost:" QByteArray cmd = "/usr/bin/gdbserver --attach localhost:"
+ QByteArray::number(port) + " " + QByteArray::number(pid); + QByteArray::number(port) + " " + QByteArray::number(pid);
d->runner->run(cmd); d->runner.run(cmd, device->sshParameters());
} }
} // namespace RemoteLinux } // namespace RemoteLinux