aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorChristian Kandeler <[email protected]>2014-01-15 18:23:08 +0100
committerChristian Kandeler <[email protected]>2014-01-20 10:45:06 +0100
commit6434a697be57e12ad12542d4d75ba99efef687e2 (patch)
tree86c66c1264f8b9cbd765498b75db17eef87cbde9 /src/libs
parent8b99e5532fcf51249ecfe44b19ca24642240caa2 (diff)
SSH: Act on failing SFTP server.
So far we ignored crashes and unexpected exits of the remote SFTP service under the assumption that the SSH server would catch these itself and act accordingly. This is not the case, however: OpenSSH, for instance, does not even realize if its sftp-server binary is not present at all. As a result, Qt Creator waits indefinitely for an SFTP operation to finish. Now we emit an error and close the offending channel. Task-number: QTCREATORBUG-10339 Change-Id: I132ed4a0098434a4cfce6056b964bd6363951fd7 Reviewed-by: Volker Vogelhuber <[email protected]> Reviewed-by: Christian Kandeler <[email protected]>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/ssh/sftpchannel.cpp26
-rw-r--r--src/libs/ssh/sftpchannel.h2
-rw-r--r--src/libs/ssh/sftpchannel_p.h2
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.cpp6
-rw-r--r--src/libs/ssh/sftpfilesystemmodel.h2
5 files changed, 21 insertions, 17 deletions
diff --git a/src/libs/ssh/sftpchannel.cpp b/src/libs/ssh/sftpchannel.cpp
index 39ba41bb668..b5e68b6e329 100644
--- a/src/libs/ssh/sftpchannel.cpp
+++ b/src/libs/ssh/sftpchannel.cpp
@@ -88,8 +88,8 @@ SftpChannel::SftpChannel(quint32 channelId,
{
connect(d, SIGNAL(initialized()), this, SIGNAL(initialized()),
Qt::QueuedConnection);
- connect(d, SIGNAL(initializationFailed(QString)), this,
- SIGNAL(initializationFailed(QString)), Qt::QueuedConnection);
+ connect(d, SIGNAL(channelError(QString)), this,
+ SIGNAL(channelError(QString)), Qt::QueuedConnection);
connect(d, SIGNAL(dataAvailable(QSsh::SftpJobId,QString)), this,
SIGNAL(dataAvailable(QSsh::SftpJobId,QString)), Qt::QueuedConnection);
connect(d, SIGNAL(fileInfoAvailable(QSsh::SftpJobId,QList<QSsh::SftpFileInfo>)), this,
@@ -271,7 +271,7 @@ void SftpChannelPrivate::handleChannelFailure()
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_FAILURE packet.");
}
- emit initializationFailed(tr("Server could not start SFTP subsystem."));
+ emit channelError(tr("Server could not start SFTP subsystem."));
closeChannel();
}
@@ -298,18 +298,22 @@ void SftpChannelPrivate::handleChannelExtendedDataInternal(quint32 type,
void SftpChannelPrivate::handleExitStatus(const SshChannelExitStatus &exitStatus)
{
- const char * const message = "Remote SFTP service exited with exit code %d";
#ifdef CREATOR_SSH_DEBUG
- qDebug(message, exitStatus.exitStatus);
-#else
- if (exitStatus.exitStatus != 0)
- qWarning(message, exitStatus.exitStatus);
+ qDebug("Remote SFTP service exited with exit code %d", exitStatus.exitStatus);
#endif
+
+ emit channelError(tr("The SFTP server finished unexpectedly with exit code %1.")
+ .arg(exitStatus.exitStatus));
+
+ // Note: According to the specs, the server must close the channel after this happens,
+ // but OpenSSH doesn't do that, so we need to initiate the closing procedure ourselves.
+ closeChannel();
}
void SftpChannelPrivate::handleExitSignal(const SshChannelExitSignal &signal)
{
- qWarning("Remote SFTP service killed; signal was %s", signal.signal.data());
+ emit channelError(tr("The SFTP server crashed: %1.").arg(signal.error));
+ closeChannel(); // See above.
}
void SftpChannelPrivate::handleCurrentPacket()
@@ -356,7 +360,7 @@ void SftpChannelPrivate::handleServerVersion()
#endif
const quint32 serverVersion = m_incomingPacket.extractServerVersion();
if (serverVersion != ProtocolVersion) {
- emit initializationFailed(tr("Protocol version mismatch: Expected %1, got %2")
+ emit channelError(tr("Protocol version mismatch: Expected %1, got %2")
.arg(serverVersion).arg(ProtocolVersion));
closeChannel();
} else {
@@ -854,7 +858,7 @@ void SftpChannelPrivate::handleOpenFailureInternal(const QString &reason)
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
- emit initializationFailed(tr("Server could not start session: %1").arg(reason));
+ emit channelError(tr("Server could not start session: %1").arg(reason));
}
void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
diff --git a/src/libs/ssh/sftpchannel.h b/src/libs/ssh/sftpchannel.h
index 5d698427f51..55464fc382c 100644
--- a/src/libs/ssh/sftpchannel.h
+++ b/src/libs/ssh/sftpchannel.h
@@ -83,7 +83,7 @@ public:
signals:
void initialized();
- void initializationFailed(const QString &reason);
+ void channelError(const QString &reason);
void closed();
// error.isEmpty <=> finished successfully
diff --git a/src/libs/ssh/sftpchannel_p.h b/src/libs/ssh/sftpchannel_p.h
index 5422358c0d3..3787d192396 100644
--- a/src/libs/ssh/sftpchannel_p.h
+++ b/src/libs/ssh/sftpchannel_p.h
@@ -52,7 +52,7 @@ public:
signals:
void initialized();
- void initializationFailed(const QString &reason);
+ void channelError(const QString &reason);
void closed();
void finished(QSsh::SftpJobId job, const QString &error = QString());
void dataAvailable(QSsh::SftpJobId job, const QString &data);
diff --git a/src/libs/ssh/sftpfilesystemmodel.cpp b/src/libs/ssh/sftpfilesystemmodel.cpp
index 3452a9186ff..ca5bea30ba6 100644
--- a/src/libs/ssh/sftpfilesystemmodel.cpp
+++ b/src/libs/ssh/sftpfilesystemmodel.cpp
@@ -296,12 +296,12 @@ void SftpFileSystemModel::handleSshConnectionEstablished()
{
d->sftpChannel = d->sshConnection->createSftpChannel();
connect(d->sftpChannel.data(), SIGNAL(initialized()), SLOT(handleSftpChannelInitialized()));
- connect(d->sftpChannel.data(), SIGNAL(initializationFailed(QString)),
- SLOT(handleSftpChannelInitializationFailed(QString)));
+ connect(d->sftpChannel.data(), SIGNAL(channelError(QString)),
+ SLOT(handleSftpChannelError(QString)));
d->sftpChannel->initialize();
}
-void SftpFileSystemModel::handleSftpChannelInitializationFailed(const QString &reason)
+void SftpFileSystemModel::handleSftpChannelError(const QString &reason)
{
emit connectionError(reason);
beginResetModel();
diff --git a/src/libs/ssh/sftpfilesystemmodel.h b/src/libs/ssh/sftpfilesystemmodel.h
index 0de34b74c81..4c7054c26e2 100644
--- a/src/libs/ssh/sftpfilesystemmodel.h
+++ b/src/libs/ssh/sftpfilesystemmodel.h
@@ -84,7 +84,7 @@ private slots:
void handleSshConnectionEstablished();
void handleSshConnectionFailure();
void handleSftpChannelInitialized();
- void handleSftpChannelInitializationFailed(const QString &reason);
+ void handleSftpChannelError(const QString &reason);
void handleFileInfo(QSsh::SftpJobId jobId, const QList<QSsh::SftpFileInfo> &fileInfoList);
void handleSftpJobFinished(QSsh::SftpJobId jobId, const QString &errorMessage);