RemoteLinux: Fix ports gatherer API.

The ports gatherer used to take an SshConnection for historical reasons
(connection sharing in the absence of a connection manager). This is no
longer required, since all the information needed for creating or
re-using a connection is available from the device.
In addition, the old code assumes the connection is already established,
which some newer callers did not adhere to, so this patch also fixes a
bug.

Change-Id: I3fd7fec7de9b64126358749f727a403bfa1e0a94
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@nokia.com>
This commit is contained in:
Christian Kandeler
2012-04-03 10:23:59 +02:00
parent 23a420eb3f
commit 1348e92971
6 changed files with 62 additions and 57 deletions

View File

@@ -142,7 +142,7 @@ void MaemoDeploymentMounter::handleUnmounted()
break;
case UnmountingCurrentDirs:
setState(GatheringPorts);
m_portsGatherer->start(m_connection, m_devConf);
m_portsGatherer->start(m_devConf);
break;
case UnmountingCurrentMounts:
setState(Inactive);

View File

@@ -159,7 +159,7 @@ void GenericLinuxDeviceTester::handleProcessFinished(int exitStatus)
emit progressMessage(tr("Checking if specified ports are available..."));
d->state = TestingPorts;
d->portsGatherer.start(d->connection, d->deviceConfiguration);
d->portsGatherer.start(d->deviceConfiguration);
}
void GenericLinuxDeviceTester::handlePortsGatheringError(const QString &message)

View File

@@ -422,7 +422,7 @@ void AbstractRemoteLinuxApplicationRunner::handleInitialCleanupDone(bool success
}
d->state = GatheringPorts;
d->portsGatherer.start(d->connection, d->devConfig);
d->portsGatherer.start(d->devConfig);
}
void AbstractRemoteLinuxApplicationRunner::handleInitializationsDone(bool success)

View File

@@ -33,7 +33,10 @@
#include "linuxdeviceconfiguration.h"
#include <utils/portlist.h>
#include <utils/ssh/sshremoteprocessrunner.h>
#include <utils/qtcassert.h>
#include <utils/ssh/sshconnection.h>
#include <utils/ssh/sshconnectionmanager.h>
#include <utils/ssh/sshremoteprocess.h>
#include <QString>
@@ -45,14 +48,12 @@ namespace Internal {
class RemoteLinuxUsedPortsGathererPrivate
{
public:
RemoteLinuxUsedPortsGathererPrivate() : running(false) {}
SshRemoteProcessRunner procRunner;
SshConnection::Ptr connection;
SshRemoteProcess::Ptr process;
PortList portsToCheck;
QList<int> usedPorts;
QByteArray remoteStdout;
QByteArray remoteStderr;
bool running; // TODO: Redundant due to being in sync with procRunner?
};
} // namespace Internal
@@ -69,24 +70,26 @@ RemoteLinuxUsedPortsGatherer::~RemoteLinuxUsedPortsGatherer()
delete d;
}
void RemoteLinuxUsedPortsGatherer::start(const Utils::SshConnection::Ptr &connection,
const LinuxDeviceConfiguration::ConstPtr &devConf)
void RemoteLinuxUsedPortsGatherer::start(const LinuxDeviceConfiguration::ConstPtr &devConf)
{
if (d->running)
qWarning("Unexpected call of %s in running state", Q_FUNC_INFO);
QTC_ASSERT(!d->connection, return);
d->portsToCheck = devConf->freePorts();
d->usedPorts.clear();
d->remoteStdout.clear();
d->remoteStderr.clear();
connect(&d->procRunner, SIGNAL(connectionError()), SLOT(handleConnectionError()));
connect(&d->procRunner, SIGNAL(processClosed(int)), SLOT(handleProcessClosed(int)));
connect(&d->procRunner, SIGNAL(processOutputAvailable(QByteArray)),
SLOT(handleRemoteStdOut(QByteArray)));
connect(&d->procRunner, SIGNAL(processErrorOutputAvailable(QByteArray)),
SLOT(handleRemoteStdErr(QByteArray)));
d->connection = SshConnectionManager::instance().acquireConnection(devConf->sshParameters());
connect(d->connection.data(), SIGNAL(error(Utils::SshError)), SLOT(handleConnectionError()));
if (d->connection->state() == SshConnection::Connected) {
handleConnectionEstablished();
return;
}
connect(d->connection.data(), SIGNAL(connected()), SLOT(handleConnectionEstablished()));
if (d->connection->state() == SshConnection::Unconnected)
d->connection->connectToHost();
}
void RemoteLinuxUsedPortsGatherer::handleConnectionEstablished()
{
QString procFilePath;
int addressLength;
if (connection->connectionInfo().localAddress.protocol() == QAbstractSocket::IPv4Protocol) {
if (d->connection->connectionInfo().localAddress.protocol() == QAbstractSocket::IPv4Protocol) {
procFilePath = QLatin1String("/proc/net/tcp");
addressLength = 8;
} else {
@@ -96,19 +99,28 @@ void RemoteLinuxUsedPortsGatherer::start(const Utils::SshConnection::Ptr &connec
const QString command = QString::fromLatin1("sed "
"'s/.*: [[:xdigit:]]\\{%1\\}:\\([[:xdigit:]]\\{4\\}\\).*/\\1/g' %2")
.arg(addressLength).arg(procFilePath);
d->process = d->connection->createRemoteProcess(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;
connect(d->process.data(), SIGNAL(closed(int)), SLOT(handleProcessClosed(int)));
connect(d->process.data(), SIGNAL(readyReadStandardOutput()), SLOT(handleRemoteStdOut()));
connect(d->process.data(), SIGNAL(readyReadStandardError()), SLOT(handleRemoteStdErr()));
d->process->start();
}
void RemoteLinuxUsedPortsGatherer::stop()
{
if (!d->running)
if (!d->connection)
return;
d->running = false;
disconnect(&d->procRunner, 0, this, 0);
d->usedPorts.clear();
d->remoteStdout.clear();
d->remoteStderr.clear();
if (d->process)
disconnect(d->process.data(), 0, this, 0);
d->process.clear();
disconnect(d->connection.data(), 0, this, 0);
SshConnectionManager::instance().releaseConnection(d->connection);
d->connection.clear();
}
int RemoteLinuxUsedPortsGatherer::getNextFreePort(PortList *freePorts) const
@@ -148,33 +160,29 @@ void RemoteLinuxUsedPortsGatherer::setupUsedPorts()
void RemoteLinuxUsedPortsGatherer::handleConnectionError()
{
if (!d->running)
if (!d->connection)
return;
emit error(tr("Connection error: %1").arg(d->procRunner.lastConnectionErrorString()));
emit error(tr("Connection error: %1").arg(d->connection->errorString()));
stop();
}
void RemoteLinuxUsedPortsGatherer::handleProcessClosed(int exitStatus)
{
if (!d->running)
if (!d->connection)
return;
QString errMsg;
switch (exitStatus) {
case SshRemoteProcess::FailedToStart:
errMsg = tr("Could not start remote process: %1")
.arg(d->procRunner.processErrorString());
errMsg = tr("Could not start remote process: %1").arg(d->process->errorString());
break;
case SshRemoteProcess::KilledBySignal:
errMsg = tr("Remote process crashed: %1")
.arg(d->procRunner.processErrorString());
errMsg = tr("Remote process crashed: %1").arg(d->process->errorString());
break;
case SshRemoteProcess::ExitedNormally:
if (d->procRunner.processExitCode() == 0) {
if (d->process->exitCode() == 0)
setupUsedPorts();
} else {
errMsg = tr("Remote process failed; exit code was %1.")
.arg(d->procRunner.processExitCode());
}
else
errMsg = tr("Remote process failed; exit code was %1.").arg(d->process->exitCode());
break;
default:
Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid exit status");
@@ -190,14 +198,16 @@ void RemoteLinuxUsedPortsGatherer::handleProcessClosed(int exitStatus)
stop();
}
void RemoteLinuxUsedPortsGatherer::handleRemoteStdOut(const QByteArray &output)
void RemoteLinuxUsedPortsGatherer::handleRemoteStdOut()
{
d->remoteStdout += output;
if (d->process)
d->remoteStdout += d->process->readAllStandardOutput();
}
void RemoteLinuxUsedPortsGatherer::handleRemoteStdErr(const QByteArray &output)
void RemoteLinuxUsedPortsGatherer::handleRemoteStdErr()
{
d->remoteStderr += output;
if (d->process)
d->remoteStderr += d->process->readAllStandardError();
}
} // namespace RemoteLinux

View File

@@ -39,10 +39,7 @@
QT_FORWARD_DECLARE_CLASS(QString)
namespace Utils {
class PortList;
class SshConnection;
} // namespace Utils
namespace Utils { class PortList; }
namespace RemoteLinux {
class LinuxDeviceConfiguration;
@@ -58,8 +55,7 @@ class REMOTELINUX_EXPORT RemoteLinuxUsedPortsGatherer : public QObject
public:
explicit RemoteLinuxUsedPortsGatherer(QObject *parent = 0);
~RemoteLinuxUsedPortsGatherer();
void start(const QSharedPointer<Utils::SshConnection> &connection,
const QSharedPointer<const LinuxDeviceConfiguration> &devConf);
void start(const QSharedPointer<const LinuxDeviceConfiguration> &devConf);
void stop();
int getNextFreePort(Utils::PortList *freePorts) const; // returns -1 if no more are left
QList<int> usedPorts() const;
@@ -69,10 +65,11 @@ signals:
void portListReady();
private slots:
void handleConnectionEstablished();
void handleConnectionError();
void handleProcessClosed(int exitStatus);
void handleRemoteStdOut(const QByteArray &output);
void handleRemoteStdErr(const QByteArray &output);
void handleRemoteStdOut();
void handleRemoteStdErr();
private:
void setupUsedPorts();

View File

@@ -325,8 +325,7 @@ void StartGdbServerDialog::startGdbServer()
d->startServerOnly = true;
if (exec() == QDialog::Rejected)
return;
LinuxDeviceConfiguration::ConstPtr device = d->currentDevice();
d->gatherer.start(SshConnection::create(device->sshParameters()), device);
d->gatherer.start(d->currentDevice());
}
void StartGdbServerDialog::attachToRemoteProcess()
@@ -334,8 +333,7 @@ void StartGdbServerDialog::attachToRemoteProcess()
d->startServerOnly = false;
if (exec() == QDialog::Rejected)
return;
LinuxDeviceConfiguration::ConstPtr device = d->currentDevice();
d->gatherer.start(SshConnection::create(device->sshParameters()), device);
d->gatherer.start(d->currentDevice());
}
void StartGdbServerDialog::handleConnectionError()