SSH: Use proper signal forwarding.

This commit is contained in:
Christian Kandeler
2010-08-17 12:37:41 +02:00
parent 03b626c80c
commit 4e90f47524
9 changed files with 80 additions and 526 deletions

View File

@@ -105,8 +105,7 @@ SOURCES += mainwindow.cpp \
ssh/sftpoperation.cpp \
ssh/sftpincomingpacket.cpp \
ssh/sftpdefs.cpp \
ssh/sftpchannel.cpp \
ssh/sshdelayedsignal.cpp
ssh/sftpchannel.cpp
HEADERS += mainwindow.h \
editmode.h \
@@ -214,8 +213,7 @@ HEADERS += mainwindow.h \
ssh/sftpincomingpacket_p.h \
ssh/sftpdefs.h \
ssh/sftpchannel.h \
ssh/sftpchannel_p.h \
ssh/sshdelayedsignal_p.h
ssh/sftpchannel_p.h
FORMS += dialogs/newdialog.ui \
actionmanager/commandmappings.ui \

View File

@@ -30,13 +30,11 @@
#include "sftpchannel.h"
#include "sftpchannel_p.h"
#include "sshdelayedsignal_p.h"
#include "sshexception_p.h"
#include "sshsendfacility_p.h"
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QWeakPointer>
namespace Core {
@@ -63,6 +61,15 @@ SftpChannel::SftpChannel(quint32 channelId,
Internal::SshSendFacility &sendFacility)
: d(new Internal::SftpChannelPrivate(channelId, sendFacility, this))
{
connect(d, SIGNAL(initialized()), this, SIGNAL(initialized()),
Qt::QueuedConnection);
connect(d, SIGNAL(initializationFailed(QString)), this,
SIGNAL(initializationFailed(QString)), Qt::QueuedConnection);
connect(d, SIGNAL(dataAvailable(Core::SftpJobId,QString)), this,
SIGNAL(dataAvailable(Core::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(finished(Core::SftpJobId,QString)), this,
SIGNAL(finished(Core::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(closed()), this, SIGNAL(closed()), Qt::QueuedConnection);
}
SftpChannel::State SftpChannel::state() const
@@ -219,7 +226,7 @@ void SftpChannelPrivate::handleChannelFailure()
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_FAILURE packet.");
}
createDelayedInitFailedSignal(SSH_TR("Server could not start sftp subsystem."));
emit initializationFailed(tr("Server could not start sftp subsystem."));
closeChannel();
}
@@ -268,7 +275,7 @@ void SftpChannelPrivate::handleCurrentPacket()
default:
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected packet.",
SSH_TR("Unexpected packet of type %d.").arg(m_incomingPacket.type()));
tr("Unexpected packet of type %d.").arg(m_incomingPacket.type()));
}
}
@@ -285,12 +292,12 @@ void SftpChannelPrivate::handleServerVersion()
#endif
const quint32 serverVersion = m_incomingPacket.extractServerVersion();
if (serverVersion != ProtocolVersion) {
createDelayedInitFailedSignal(SSH_TR("Protocol version mismatch: Expected %1, got %2")
emit initializationFailed(tr("Protocol version mismatch: Expected %1, got %2")
.arg(serverVersion).arg(ProtocolVersion));
closeChannel();
} else {
m_sftpState = Initialized;
createDelayedInitializedSignal();
emit initialized();
}
}
@@ -401,8 +408,8 @@ void SftpChannelPrivate::handleStatusGeneric(const JobMap::Iterator &it,
const SftpStatusResponse &response)
{
AbstractSftpOperation::Ptr op = it.value();
const QString error = errorMessage(response, SSH_TR("Unknown error."));
createDelayedJobFinishedSignal(op->jobId, error);
const QString error = errorMessage(response, tr("Unknown error."));
emit finished(op->jobId, error);
m_jobs.erase(it);
}
@@ -424,15 +431,15 @@ void SftpChannelPrivate::handleMkdirStatus(const JobMap::Iterator &it,
Q_ASSERT(dirIt != op->parentJob->mkdirsInProgress.end());
const QString &remoteDir = dirIt.value().remoteDir;
if (response.status == SSH_FX_OK) {
createDelayedDataAvailableSignal(op->parentJob->jobId,
SSH_TR("Created remote directory '%1'.").arg(remoteDir));
emit dataAvailable(op->parentJob->jobId,
tr("Created remote directory '%1'.").arg(remoteDir));
} else if (response.status == SSH_FX_FAILURE) {
createDelayedDataAvailableSignal(op->parentJob->jobId,
SSH_TR("Remote directory '%1' already exists.").arg(remoteDir));
emit dataAvailable(op->parentJob->jobId,
tr("Remote directory '%1' already exists.").arg(remoteDir));
} else {
op->parentJob->setError();
createDelayedJobFinishedSignal(op->parentJob->jobId,
SSH_TR("Error creating directory '%1': %2")
emit finished(op->parentJob->jobId,
tr("Error creating directory '%1': %2")
.arg(remoteDir, response.errorString));
m_jobs.erase(it);
return;
@@ -455,8 +462,8 @@ void SftpChannelPrivate::handleMkdirStatus(const JobMap::Iterator &it,
QSharedPointer<QFile> localFile(new QFile(fileInfo.absoluteFilePath()));
if (!localFile->open(QIODevice::ReadOnly)) {
op->parentJob->setError();
createDelayedJobFinishedSignal(op->parentJob->jobId,
SSH_TR("Could not open local file '%1': %2")
emit finished(op->parentJob->jobId,
tr("Could not open local file '%1': %2")
.arg(fileInfo.absoluteFilePath(), localFile->error()));
m_jobs.erase(it);
return;
@@ -472,7 +479,7 @@ void SftpChannelPrivate::handleMkdirStatus(const JobMap::Iterator &it,
op->parentJob->mkdirsInProgress.erase(dirIt);
if (op->parentJob->mkdirsInProgress.isEmpty()
&& op->parentJob->uploadsInProgress.isEmpty())
createDelayedJobFinishedSignal(op->parentJob->jobId);
emit finished(op->parentJob->jobId);
m_jobs.erase(it);
}
@@ -482,14 +489,14 @@ void SftpChannelPrivate::handleLsStatus(const JobMap::Iterator &it,
SftpListDir::Ptr op = it.value().staticCast<SftpListDir>();
switch (op->state) {
case SftpListDir::OpenRequested:
createDelayedJobFinishedSignal(op->jobId, errorMessage(response.errorString,
SSH_TR("Remote directory could not be opened for reading.")));
emit finished(op->jobId, errorMessage(response.errorString,
tr("Remote directory could not be opened for reading.")));
m_jobs.erase(it);
break;
case SftpListDir::Open:
if (response.status != SSH_FX_EOF)
reportRequestError(op, errorMessage(response.errorString,
SSH_TR("Failed to list remote directory contents.")));
tr("Failed to list remote directory contents.")));
op->state = SftpListDir::CloseRequested;
sendData(m_outgoingPacket.generateCloseHandle(op->remoteHandle,
op->jobId).rawData());
@@ -497,8 +504,8 @@ void SftpChannelPrivate::handleLsStatus(const JobMap::Iterator &it,
case SftpListDir::CloseRequested:
if (!op->hasError) {
const QString error = errorMessage(response,
SSH_TR("Failed to close remote directory."));
createDelayedJobFinishedSignal(op->jobId, error);
tr("Failed to close remote directory."));
emit finished(op->jobId, error);
}
m_jobs.erase(it);
break;
@@ -514,21 +521,21 @@ void SftpChannelPrivate::handleGetStatus(const JobMap::Iterator &it,
SftpDownload::Ptr op = it.value().staticCast<SftpDownload>();
switch (op->state) {
case SftpDownload::OpenRequested:
createDelayedJobFinishedSignal(op->jobId,
emit finished(op->jobId,
errorMessage(response.errorString,
SSH_TR("Failed to open remote file for reading.")));
tr("Failed to open remote file for reading.")));
m_jobs.erase(it);
break;
case SftpDownload::Open:
if (op->statRequested) {
reportRequestError(op, errorMessage(response.errorString,
SSH_TR("Failed to stat remote file.")));
tr("Failed to stat remote file.")));
sendTransferCloseHandle(op, response.requestId);
} else {
if ((response.status != SSH_FX_EOF || response.requestId != op->eofId)
&& !op->hasError)
reportRequestError(op, errorMessage(response.errorString,
SSH_TR("Failed to read remote file.")));
tr("Failed to read remote file.")));
finishTransferRequest(it);
}
break;
@@ -536,10 +543,10 @@ void SftpChannelPrivate::handleGetStatus(const JobMap::Iterator &it,
Q_ASSERT(op->inFlightCount == 1);
if (!op->hasError) {
if (response.status == SSH_FX_OK)
createDelayedJobFinishedSignal(op->jobId);
emit finished(op->jobId);
else
reportRequestError(op, errorMessage(response.errorString,
SSH_TR("Failed to close remote file.")));
tr("Failed to close remote file.")));
}
removeTransferRequest(it);
break;
@@ -566,9 +573,9 @@ void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
}
if (emitError) {
createDelayedJobFinishedSignal(job->jobId,
emit finished(job->jobId,
errorMessage(response.errorString,
SSH_TR("Failed to open remote file for writing.")));
tr("Failed to open remote file for writing.")));
}
m_jobs.erase(it);
break;
@@ -586,7 +593,7 @@ void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
if (job->parentJob)
job->parentJob->setError();
reportRequestError(job, errorMessage(response.errorString,
SSH_TR("Failed to write remote file.")));
tr("Failed to write remote file.")));
finishTransferRequest(it);
}
break;
@@ -602,18 +609,18 @@ void SftpChannelPrivate::handlePutStatus(const JobMap::Iterator &it,
job->parentJob->uploadsInProgress.removeOne(job);
if (job->parentJob->mkdirsInProgress.isEmpty()
&& job->parentJob->uploadsInProgress.isEmpty())
createDelayedJobFinishedSignal(job->parentJob->jobId);
emit finished(job->parentJob->jobId);
} else {
createDelayedJobFinishedSignal(job->jobId);
emit finished(job->jobId);
}
} else {
const QString error = errorMessage(response.errorString,
SSH_TR("Failed to close remote file."));
tr("Failed to close remote file."));
if (job->parentJob) {
job->parentJob->setError();
createDelayedJobFinishedSignal(job->parentJob->jobId, error);
emit finished(job->parentJob->jobId, error);
} else {
createDelayedJobFinishedSignal(job->jobId, error);
emit finished(job->jobId, error);
}
}
m_jobs.erase(it);
@@ -638,7 +645,7 @@ void SftpChannelPrivate::handleName()
for (int i = 0; i < response.files.count(); ++i) {
const SftpFile &file = response.files.at(i);
createDelayedDataAvailableSignal(op->jobId, file.fileName);
emit dataAvailable(op->jobId, file.fileName);
}
sendData(m_outgoingPacket.generateReadDir(op->remoteHandle,
op->jobId).rawData());
@@ -721,7 +728,7 @@ void SftpChannelPrivate::handleAttrs()
} else {
if (op->parentJob)
op->parentJob->setError();
reportRequestError(op, SSH_TR("Cannot append to remote file: "
reportRequestError(op, tr("Cannot append to remote file: "
"Server does not support file size attribute."));
sendTransferCloseHandle(op, op->jobId);
}
@@ -740,7 +747,7 @@ SftpChannelPrivate::JobMap::Iterator SftpChannelPrivate::lookupJob(SftpJobId id)
void SftpChannelPrivate::closeHook()
{
createClosedSignal();
emit closed();
}
void SftpChannelPrivate::handleOpenSuccessInternal()
@@ -758,7 +765,7 @@ void SftpChannelPrivate::handleOpenFailureInternal()
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
createDelayedInitFailedSignal(SSH_TR("Server could not start session."));
emit initializationFailed(tr("Server could not start session."));
}
void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
@@ -776,7 +783,7 @@ void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
void SftpChannelPrivate::reportRequestError(const AbstractSftpOperationWithHandle::Ptr &job,
const QString &error)
{
createDelayedJobFinishedSignal(job->jobId, error);
emit finished(job->jobId, error);
job->hasError = true;
}
@@ -810,7 +817,7 @@ void SftpChannelPrivate::sendWriteRequest(const JobMap::Iterator &it)
if (job->localFile->error() != QFile::NoError) {
if (job->parentJob)
job->parentJob->setError();
reportRequestError(job, SSH_TR("Error reading local file: %1")
reportRequestError(job, tr("Error reading local file: %1")
.arg(job->localFile->errorString()));
finishTransferRequest(it);
} else if (data.isEmpty()) {
@@ -842,58 +849,5 @@ void SftpChannelPrivate::spawnReadRequests(const SftpDownload::Ptr &job)
}
}
void SftpChannelPrivate::createDelayedInitFailedSignal(const QString &reason)
{
new SftpInitializationFailedSignal(this, QWeakPointer<SftpChannel>(m_sftp),
reason);
}
void SftpChannelPrivate::emitInitializationFailedSignal(const QString &reason)
{
emit m_sftp->initializationFailed(reason);
}
void SftpChannelPrivate::createDelayedInitializedSignal()
{
new SftpInitializedSignal(this, QWeakPointer<SftpChannel>(m_sftp));
}
void SftpChannelPrivate::emitInitialized()
{
emit m_sftp->initialized();
}
void SftpChannelPrivate::createDelayedJobFinishedSignal(SftpJobId jobId,
const QString &error)
{
new SftpJobFinishedSignal(this, QWeakPointer<SftpChannel>(m_sftp), jobId, error);
}
void SftpChannelPrivate::emitJobFinished(SftpJobId jobId, const QString &error)
{
emit m_sftp->finished(jobId, error);
}
void SftpChannelPrivate::createDelayedDataAvailableSignal(SftpJobId jobId,
const QString &data)
{
new SftpDataAvailableSignal(this, QWeakPointer<SftpChannel>(m_sftp), jobId, data);
}
void SftpChannelPrivate::emitDataAvailable(SftpJobId jobId, const QString &data)
{
emit m_sftp->dataAvailable(jobId, data);
}
void SftpChannelPrivate::createClosedSignal()
{
new SftpClosedSignal(this, QWeakPointer<SftpChannel>(m_sftp));
}
void SftpChannelPrivate::emitClosed()
{
emit m_sftp->closed();
}
} // namespace Internal
} // namespace Core

View File

@@ -45,6 +45,7 @@ namespace Internal {
class SftpChannelPrivate : public AbstractSshChannel
{
Q_OBJECT
friend class Core::SftpChannel;
public:
@@ -55,11 +56,12 @@ public:
virtual void closeHook();
void emitInitializationFailedSignal(const QString &reason);
void emitInitialized();
void emitJobFinished(SftpJobId jobId, const QString &error);
void emitDataAvailable(SftpJobId jobId, const QString &data);
void emitClosed();
signals:
void initialized();
void initializationFailed(const QString &reason);
void closed();
void finished(Core::SftpJobId job, const QString &error = QString());
void dataAvailable(SftpJobId job, const QString &data);
private:
typedef QMap<SftpJobId, AbstractSftpOperation::Ptr> JobMap;
@@ -109,13 +111,6 @@ private:
void sendTransferCloseHandle(const AbstractSftpTransfer::Ptr &job,
quint32 requestId);
void createDelayedInitFailedSignal(const QString &reason);
void createDelayedInitializedSignal();
void createDelayedJobFinishedSignal(SftpJobId jobId,
const QString &error = QString());
void createDelayedDataAvailableSignal(SftpJobId jobId, const QString &data);
void createClosedSignal();
JobMap::Iterator lookupJob(SftpJobId id);
JobMap m_jobs;
SftpOutgoingPacket m_outgoingPacket;

View File

@@ -134,7 +134,7 @@ SshChannelManager::ChannelIterator SshChannelManager::lookupChannelAsIterator(qu
if (it == m_channels.end() && !allowNotFound) {
throw SshServerException(SSH_DISCONNECT_PROTOCOL_ERROR,
"Invalid channel id.",
SSH_TR("Invalid channel id %1").arg(channelId));
tr("Invalid channel id %1").arg(channelId));
}
return it;
}

View File

@@ -59,6 +59,7 @@ namespace {
if (!staticInitializationsDone) {
Botan::LibraryInitializer::initialize("thread_safe=true");
qRegisterMetaType<SshError>("SshError");
qRegisterMetaType<Core::SftpJobId>("Core::SftpJobId");
staticInitializationsDone = true;
}
staticInitMutex.unlock();

View File

@@ -1,165 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "sshdelayedsignal_p.h"
#include "sftpchannel_p.h"
#include "sshremoteprocess_p.h"
#include <QtCore/QTimer>
namespace Core {
namespace Internal {
SshDelayedSignal::SshDelayedSignal(const QWeakPointer<QObject> &checkObject)
: m_checkObject(checkObject)
{
QTimer::singleShot(0, this, SLOT(handleTimeout()));
}
void SshDelayedSignal::handleTimeout()
{
if (!m_checkObject.isNull())
emitSignal();
deleteLater();
}
SftpDelayedSignal::SftpDelayedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject)
: SshDelayedSignal(checkObject), m_privChannel(privChannel) {}
SftpInitializationFailedSignal::SftpInitializationFailedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QString &reason)
: SftpDelayedSignal(privChannel, checkObject), m_reason(reason) {}
void SftpInitializationFailedSignal::emitSignal()
{
m_privChannel->emitInitializationFailedSignal(m_reason);
}
SftpInitializedSignal::SftpInitializedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject)
: SftpDelayedSignal(privChannel, checkObject) {}
void SftpInitializedSignal::emitSignal()
{
m_privChannel->emitInitialized();
}
SftpJobFinishedSignal::SftpJobFinishedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, SftpJobId jobId,
const QString &error)
: SftpDelayedSignal(privChannel, checkObject), m_jobId(jobId), m_error(error)
{
}
void SftpJobFinishedSignal::emitSignal()
{
m_privChannel->emitJobFinished(m_jobId, m_error);
}
SftpDataAvailableSignal::SftpDataAvailableSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, SftpJobId jobId,
const QString &data)
: SftpDelayedSignal(privChannel, checkObject), m_jobId(jobId), m_data(data) {}
void SftpDataAvailableSignal::emitSignal()
{
m_privChannel->emitDataAvailable(m_jobId, m_data);
}
SftpClosedSignal::SftpClosedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject)
: SftpDelayedSignal(privChannel, checkObject) {}
void SftpClosedSignal::emitSignal()
{
m_privChannel->emitClosed();
}
SshRemoteProcessDelayedSignal::SshRemoteProcessDelayedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject)
: SshDelayedSignal(checkObject), m_privChannel(privChannel) {}
SshRemoteProcessStartedSignal::SshRemoteProcessStartedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject)
: SshRemoteProcessDelayedSignal(privChannel, checkObject) {}
void SshRemoteProcessStartedSignal::emitSignal()
{
m_privChannel->emitStartedSignal();
}
SshRemoteProcessOutputAvailableSignal::SshRemoteProcessOutputAvailableSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QByteArray &output)
: SshRemoteProcessDelayedSignal(privChannel, checkObject), m_output(output)
{
}
void SshRemoteProcessOutputAvailableSignal::emitSignal()
{
m_privChannel->emitOutputAvailableSignal(m_output);
}
SshRemoteProcessErrorOutputAvailableSignal::SshRemoteProcessErrorOutputAvailableSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QByteArray &output)
: SshRemoteProcessDelayedSignal(privChannel, checkObject), m_output(output)
{
}
void SshRemoteProcessErrorOutputAvailableSignal::emitSignal()
{
m_privChannel->emitErrorOutputAvailableSignal(m_output);
}
SshRemoteProcessClosedSignal::SshRemoteProcessClosedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, int exitStatus)
: SshRemoteProcessDelayedSignal(privChannel, checkObject),
m_exitStatus(exitStatus)
{
}
void SshRemoteProcessClosedSignal::emitSignal()
{
m_privChannel->emitClosedSignal(m_exitStatus);
}
} // namespace Internal
} // namespace Core

View File

@@ -1,190 +0,0 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#ifndef SSHDELAYEDSIGNAL_P_H
#define SSHDELAYEDSIGNAL_P_H
#include "sftpdefs.h"
#include <QtCore/QObject>
#include <QtCore/QString>
#include <QtCore/QWeakPointer>
namespace Core {
namespace Internal {
class SftpChannelPrivate;
class SshRemoteProcessPrivate;
class SshDelayedSignal : public QObject
{
Q_OBJECT
public:
SshDelayedSignal(const QWeakPointer<QObject> &checkObject);
private:
Q_SLOT void handleTimeout();
virtual void emitSignal()=0;
const QWeakPointer<QObject> m_checkObject;
};
class SftpDelayedSignal : public SshDelayedSignal
{
public:
SftpDelayedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject);
protected:
SftpChannelPrivate * const m_privChannel;
};
class SftpInitializationFailedSignal : public SftpDelayedSignal
{
public:
SftpInitializationFailedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QString &reason);
private:
virtual void emitSignal();
const QString m_reason;
};
class SftpInitializedSignal : public SftpDelayedSignal
{
public:
SftpInitializedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject);
private:
virtual void emitSignal();
};
class SftpJobFinishedSignal : public SftpDelayedSignal
{
public:
SftpJobFinishedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, SftpJobId jobId,
const QString &error);
private:
virtual void emitSignal();
const SftpJobId m_jobId;
const QString m_error;
};
class SftpDataAvailableSignal : public SftpDelayedSignal
{
public:
SftpDataAvailableSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, SftpJobId jobId,
const QString &data);
private:
virtual void emitSignal();
const SftpJobId m_jobId;
const QString m_data;
};
class SftpClosedSignal : public SftpDelayedSignal
{
public:
SftpClosedSignal(SftpChannelPrivate *privChannel,
const QWeakPointer<QObject> &checkObject);
private:
virtual void emitSignal();
};
class SshRemoteProcessDelayedSignal : public SshDelayedSignal
{
public:
SshRemoteProcessDelayedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject);
protected:
SshRemoteProcessPrivate * const m_privChannel;
};
class SshRemoteProcessStartedSignal : public SshRemoteProcessDelayedSignal
{
public:
SshRemoteProcessStartedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject);
private:
virtual void emitSignal();
};
class SshRemoteProcessOutputAvailableSignal
: public SshRemoteProcessDelayedSignal
{
public:
SshRemoteProcessOutputAvailableSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QByteArray &output);
private:
virtual void emitSignal();
const QByteArray m_output;
};
class SshRemoteProcessErrorOutputAvailableSignal
: public SshRemoteProcessDelayedSignal
{
public:
SshRemoteProcessErrorOutputAvailableSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, const QByteArray &output);
private:
virtual void emitSignal();
const QByteArray m_output;
};
class SshRemoteProcessClosedSignal : public SshRemoteProcessDelayedSignal
{
public:
SshRemoteProcessClosedSignal(SshRemoteProcessPrivate *privChannel,
const QWeakPointer<QObject> &checkObject, int exitStatus);
private:
virtual void emitSignal();
const int m_exitStatus;
};
} // namespace Internal
} // namespace Core
#endif // SSHDELAYEDSIGNAL_P_H

View File

@@ -30,7 +30,6 @@
#include "sshremoteprocess.h"
#include "sshremoteprocess_p.h"
#include "sshdelayedsignal_p.h"
#include "sshincomingpacket_p.h"
#include "sshsendfacility_p.h"
@@ -58,6 +57,14 @@ SshRemoteProcess::SshRemoteProcess(const QByteArray &command, quint32 channelId,
Internal::SshSendFacility &sendFacility)
: d(new Internal::SshRemoteProcessPrivate(command, channelId, sendFacility, this))
{
connect(d, SIGNAL(started()), this, SIGNAL(started()),
Qt::QueuedConnection);
connect(d, SIGNAL(outputAvailable(QByteArray)), this,
SIGNAL(outputAvailable(QByteArray)), Qt::QueuedConnection);
connect(d, SIGNAL(errorOutputAvailable(QByteArray)), this,
SIGNAL(errorOutputAvailable(QByteArray)), Qt::QueuedConnection);
connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)),
Qt::QueuedConnection);
}
SshRemoteProcess::~SshRemoteProcess()
@@ -134,10 +141,10 @@ void SshRemoteProcessPrivate::setProcState(ProcessState newState)
#endif
m_procState = newState;
if (newState == StartFailed) {
createClosedSignal(SshRemoteProcess::FailedToStart);
emit closed(SshRemoteProcess::FailedToStart);
} else if (newState == Running) {
m_wasRunning = true;
createStartedSignal();
emit started();
}
}
@@ -145,9 +152,9 @@ void SshRemoteProcessPrivate::closeHook()
{
if (m_wasRunning) {
if (!m_signal.isEmpty())
createClosedSignal(SshRemoteProcess::KilledBySignal);
emit closed(SshRemoteProcess::KilledBySignal);
else
createClosedSignal(SshRemoteProcess::ExitedNormally);
emit closed(SshRemoteProcess::ExitedNormally);
}
}
@@ -191,7 +198,7 @@ void SshRemoteProcessPrivate::handleChannelFailure()
void SshRemoteProcessPrivate::handleChannelDataInternal(const QByteArray &data)
{
createOutputAvailableSignal(data);
emit outputAvailable(data);
}
void SshRemoteProcessPrivate::handleChannelExtendedDataInternal(quint32 type,
@@ -200,7 +207,7 @@ void SshRemoteProcessPrivate::handleChannelExtendedDataInternal(quint32 type,
if (type != SSH_EXTENDED_DATA_STDERR)
qWarning("Unknown extended data type %u", type);
else
createErrorOutputAvailableSignal(data);
emit errorOutputAvailable(data);
}
void SshRemoteProcessPrivate::handleChannelRequest(const SshIncomingPacket &packet)
@@ -227,48 +234,5 @@ void SshRemoteProcessPrivate::handleChannelRequest(const SshIncomingPacket &pack
}
}
void SshRemoteProcessPrivate::createStartedSignal()
{
new SshRemoteProcessStartedSignal(this, QWeakPointer<SshRemoteProcess>(m_proc));
}
void SshRemoteProcessPrivate::emitStartedSignal()
{
emit m_proc->started();
}
void SshRemoteProcessPrivate::createOutputAvailableSignal(const QByteArray &output)
{
new SshRemoteProcessOutputAvailableSignal(this,
QWeakPointer<SshRemoteProcess>(m_proc), output);
}
void SshRemoteProcessPrivate::emitOutputAvailableSignal(const QByteArray &output)
{
emit m_proc->outputAvailable(output);
}
void SshRemoteProcessPrivate::createErrorOutputAvailableSignal(const QByteArray &output)
{
new SshRemoteProcessErrorOutputAvailableSignal(this,
QWeakPointer<SshRemoteProcess>(m_proc), output);
}
void SshRemoteProcessPrivate::emitErrorOutputAvailableSignal(const QByteArray &output)
{
emit m_proc->errorOutputAvailable(output);
}
void SshRemoteProcessPrivate::createClosedSignal(int exitStatus)
{
new SshRemoteProcessClosedSignal(this,
QWeakPointer<SshRemoteProcess>(m_proc), exitStatus);
}
void SshRemoteProcessPrivate::emitClosedSignal(int exitStatus)
{
emit m_proc->closed(exitStatus);
}
} // namespace Internal
} // namespace Core

View File

@@ -43,6 +43,7 @@ class SshSendFacility;
class SshRemoteProcessPrivate : public AbstractSshChannel
{
Q_OBJECT
friend class Core::SshRemoteProcess;
public:
enum ProcessState {
@@ -54,10 +55,11 @@ public:
virtual void closeHook();
void emitStartedSignal();
void emitOutputAvailableSignal(const QByteArray &output);
void emitErrorOutputAvailableSignal(const QByteArray &output);
void emitClosedSignal(int exitStatus);
signals:
void started();
void outputAvailable(const QByteArray &output);
void errorOutputAvailable(const QByteArray &output);
void closed(int exitStatus);
private:
SshRemoteProcessPrivate(const QByteArray &command, quint32 channelId,
@@ -72,11 +74,6 @@ private:
void setProcState(ProcessState newState);
void createStartedSignal();
void createOutputAvailableSignal(const QByteArray &output);
void createErrorOutputAvailableSignal(const QByteArray &output);
void createClosedSignal(int exitStatus);
ProcessState m_procState;
bool m_wasRunning;
QByteArray m_signal;