summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/utils/ssh/sftpchannel.cpp4
-rw-r--r--src/libs/utils/ssh/sftpchannel_p.h2
-rw-r--r--src/libs/utils/ssh/sshchannel.cpp7
-rw-r--r--src/libs/utils/ssh/sshchannel_p.h6
-rw-r--r--src/libs/utils/ssh/sshremoteprocess.cpp103
-rw-r--r--src/libs/utils/ssh/sshremoteprocess.h20
-rw-r--r--src/libs/utils/ssh/sshremoteprocess_p.h7
-rw-r--r--src/plugins/debugger/gdb/remotegdbprocess.cpp2
-rw-r--r--src/plugins/debugger/lldb/lldbenginehost.cpp4
-rw-r--r--src/plugins/madde/maddedevicetester.cpp2
-rw-r--r--src/plugins/madde/maemopublisherfremantlefree.cpp6
-rw-r--r--src/plugins/madde/maemoremotemounter.cpp4
-rw-r--r--src/plugins/remotelinux/linuxdevicetester.cpp2
-rw-r--r--src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp2
14 files changed, 94 insertions, 77 deletions
diff --git a/src/libs/utils/ssh/sftpchannel.cpp b/src/libs/utils/ssh/sftpchannel.cpp
index c17ce21d19..79e1f3f2ef 100644
--- a/src/libs/utils/ssh/sftpchannel.cpp
+++ b/src/libs/utils/ssh/sftpchannel.cpp
@@ -821,13 +821,13 @@ void SftpChannelPrivate::handleOpenSuccessInternal()
m_sftpState = SubsystemRequested;
}
-void SftpChannelPrivate::handleOpenFailureInternal()
+void SftpChannelPrivate::handleOpenFailureInternal(const QString &reason)
{
if (channelState() != SessionRequested) {
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
}
- emit initializationFailed(tr("Server could not start session."));
+ emit initializationFailed(tr("Server could not start session: %1").arg(reason));
}
void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
diff --git a/src/libs/utils/ssh/sftpchannel_p.h b/src/libs/utils/ssh/sftpchannel_p.h
index 241cbb77a7..e2efd89afd 100644
--- a/src/libs/utils/ssh/sftpchannel_p.h
+++ b/src/libs/utils/ssh/sftpchannel_p.h
@@ -74,7 +74,7 @@ private:
SftpJobId createJob(const AbstractSftpOperation::Ptr &job);
virtual void handleOpenSuccessInternal();
- virtual void handleOpenFailureInternal();
+ virtual void handleOpenFailureInternal(const QString &reason);
virtual void handleChannelDataInternal(const QByteArray &data);
virtual void handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data);
diff --git a/src/libs/utils/ssh/sshchannel.cpp b/src/libs/utils/ssh/sshchannel.cpp
index b6965da5b1..4fa68dc89e 100644
--- a/src/libs/utils/ssh/sshchannel.cpp
+++ b/src/libs/utils/ssh/sshchannel.cpp
@@ -84,7 +84,7 @@ void AbstractSshChannel::requestSessionStart()
setChannelState(SessionRequested);
m_timeoutTimer->start(ReplyTimeout);
} catch (Botan::Exception &e) {
- m_errorString = QString::fromAscii(e.what());
+ qDebug("Botan error: %s", e.what());
closeChannel();
}
}
@@ -95,7 +95,7 @@ void AbstractSshChannel::sendData(const QByteArray &data)
m_sendBuffer += data;
flushSendBuffer();
} catch (Botan::Exception &e) {
- m_errorString = QString::fromAscii(e.what());
+ qDebug("Botan error: %s", e.what());
closeChannel();
}
}
@@ -163,8 +163,7 @@ void AbstractSshChannel::handleOpenFailure(const QString &reason)
#ifdef CREATOR_SSH_DEBUG
qDebug("Channel open request failed for channel %u", m_localChannel);
#endif
- m_errorString = reason;
- handleOpenFailureInternal();
+ handleOpenFailureInternal(reason);
}
void AbstractSshChannel::handleChannelEof()
diff --git a/src/libs/utils/ssh/sshchannel_p.h b/src/libs/utils/ssh/sshchannel_p.h
index 201b77b970..c6c81f5abf 100644
--- a/src/libs/utils/ssh/sshchannel_p.h
+++ b/src/libs/utils/ssh/sshchannel_p.h
@@ -58,9 +58,6 @@ public:
ChannelState channelState() const { return m_state; }
void setChannelState(ChannelState state);
- void setError(const QString &error) { m_errorString = error; }
- QString errorString() const { return m_errorString; }
-
quint32 localChannelId() const { return m_localChannel; }
quint32 remoteChannel() const { return m_remoteChannel; }
@@ -101,7 +98,7 @@ protected:
private:
virtual void handleOpenSuccessInternal() = 0;
- virtual void handleOpenFailureInternal() = 0;
+ virtual void handleOpenFailureInternal(const QString &reason) = 0;
virtual void handleChannelDataInternal(const QByteArray &data) = 0;
virtual void handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data) = 0;
@@ -119,7 +116,6 @@ private:
quint32 m_remoteMaxPacketSize;
ChannelState m_state;
QByteArray m_sendBuffer;
- QString m_errorString;
};
} // namespace Internal
diff --git a/src/libs/utils/ssh/sshremoteprocess.cpp b/src/libs/utils/ssh/sshremoteprocess.cpp
index 90ab74735f..52068ba869 100644
--- a/src/libs/utils/ssh/sshremoteprocess.cpp
+++ b/src/libs/utils/ssh/sshremoteprocess.cpp
@@ -42,6 +42,8 @@
#include <QtCore/QTimer>
+#include <cstring>
+
/*!
\class Utils::SshRemoteProcess
@@ -49,17 +51,10 @@
Objects are created via SshConnection::createRemoteProcess.
The process is started via the start() member function.
- A closeChannel() function is provided, but rarely useful, because
-
- \list
- \i a) when the process ends, the channel is closed automatically, and
- \i b) closing a channel will not necessarily kill the remote process.
- \endlist
-
- Therefore, the only sensible use case for calling closeChannel() is to
- get rid of an SshRemoteProces object before the process is actually started.
If the process needs a pseudo terminal, you can request one
via requestTerminal() before calling start().
+ Note that this class does not support QIODevice's waitFor*() functions, i.e. it has
+ no synchronous mode.
*/
namespace Utils {
@@ -99,12 +94,63 @@ SshRemoteProcess::~SshRemoteProcess()
delete d;
}
+bool SshRemoteProcess::atEnd() const
+{
+ return QIODevice::atEnd() && d->m_stdout.isEmpty();
+}
+
+qint64 SshRemoteProcess::bytesAvailable() const
+{
+ return QIODevice::bytesAvailable() + d->m_stdout.count();
+}
+
+bool SshRemoteProcess::canReadLine() const
+{
+ return QIODevice::canReadLine() || d->m_stdout.contains('\n'); // TODO: Not cross-platform?
+}
+
+QByteArray SshRemoteProcess::readAllStandardOutput()
+{
+ return readAll();
+}
+
+QByteArray SshRemoteProcess::readAllStandardError()
+{
+ const QByteArray data = d->m_stderr;
+ d->m_stderr.clear();
+ return data;
+}
+
+void SshRemoteProcess::close()
+{
+ d->closeChannel();
+ QIODevice::close();
+}
+
+qint64 SshRemoteProcess::readData(char *data, qint64 maxlen)
+{
+ const qint64 bytesRead = qMin(qint64(d->m_stdout.count()), maxlen);
+ memcpy(data, d->m_stdout.constData(), bytesRead);
+ d->m_stdout.remove(0, bytesRead);
+ return bytesRead;
+}
+
+qint64 SshRemoteProcess::writeData(const char *data, qint64 len)
+{
+ if (isRunning()) {
+ d->sendData(QByteArray(data, len));
+ return len;
+ }
+ return 0;
+}
+
void SshRemoteProcess::init()
{
connect(d, SIGNAL(started()), this, SIGNAL(started()),
Qt::QueuedConnection);
connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyReadStandardOutput()),
Qt::QueuedConnection);
+ connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
connect(d, SIGNAL(readyReadStandardError()), this,
SIGNAL(readyReadStandardError()), Qt::QueuedConnection);
connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), Qt::QueuedConnection);
@@ -129,6 +175,7 @@ void SshRemoteProcess::start()
#ifdef CREATOR_SSH_DEBUG
qDebug("process start requested, channel id = %u", d->localChannelId());
#endif
+ QIODevice::open(QIODevice::ReadWrite);
d->requestSessionStart();
}
}
@@ -140,36 +187,19 @@ void SshRemoteProcess::sendSignal(const QByteArray &signal)
d->m_sendFacility.sendChannelSignalPacket(d->remoteChannel(),
signal);
} catch (Botan::Exception &e) {
- d->setError(QString::fromAscii(e.what()));
+ setErrorString(QString::fromAscii(e.what()));
d->closeChannel();
}
}
-void SshRemoteProcess::closeChannel()
-{
- d->closeChannel();
-}
-
-void SshRemoteProcess::sendInput(const QByteArray &data)
-{
- if (isRunning())
- d->sendData(data);
-}
-
bool SshRemoteProcess::isRunning() const
{
return d->m_procState == Internal::SshRemoteProcessPrivate::Running;
}
-QString SshRemoteProcess::errorString() const { return d->errorString(); }
-
int SshRemoteProcess::exitCode() const { return d->m_exitCode; }
-
QByteArray SshRemoteProcess::exitSignal() const { return d->m_signal; }
-QByteArray SshRemoteProcess::readAllStandardOutput() { return d->readAllStandardOutput(); }
-QByteArray SshRemoteProcess::readAllStandardError() { return d->readAllStandardError(); }
-
namespace Internal {
SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command,
@@ -214,20 +244,6 @@ void SshRemoteProcessPrivate::setProcState(ProcessState newState)
}
}
-QByteArray SshRemoteProcessPrivate::readAllStandardOutput()
-{
- const QByteArray data = m_stdout;
- m_stdout.clear();
- return data;
-}
-
-QByteArray SshRemoteProcessPrivate::readAllStandardError()
-{
- const QByteArray data = m_stderr;
- m_stderr.clear();
- return data;
-}
-
void SshRemoteProcessPrivate::closeHook()
{
if (m_wasRunning) {
@@ -256,9 +272,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal()
m_timeoutTimer->start(ReplyTimeout);
}
-void SshRemoteProcessPrivate::handleOpenFailureInternal()
+void SshRemoteProcessPrivate::handleOpenFailureInternal(const QString &reason)
{
setProcState(StartFailed);
+ m_proc->setErrorString(reason);
}
void SshRemoteProcessPrivate::handleChannelSuccess()
@@ -313,9 +330,9 @@ void SshRemoteProcessPrivate::handleExitSignal(const SshChannelExitSignal &signa
#ifdef CREATOR_SSH_DEBUG
qDebug("Exit due to signal %s", signal.signal.data());
#endif
- setError(signal.error);
m_signal = signal.signal;
m_procState = Exited;
+ m_proc->setErrorString(tr("Process killed by signal"));
}
} // namespace Internal
diff --git a/src/libs/utils/ssh/sshremoteprocess.h b/src/libs/utils/ssh/sshremoteprocess.h
index 59f61385c2..fcd3f0edd5 100644
--- a/src/libs/utils/ssh/sshremoteprocess.h
+++ b/src/libs/utils/ssh/sshremoteprocess.h
@@ -35,7 +35,7 @@
#include <utils/utils_global.h>
-#include <QtCore/QObject>
+#include <QtCore/QProcess>
#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -50,7 +50,8 @@ class SshRemoteProcessPrivate;
class SshSendFacility;
} // namespace Internal
-class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QObject
+// TODO: ProcessChannel
+class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QIODevice
{
Q_OBJECT
@@ -77,6 +78,13 @@ public:
~SshRemoteProcess();
+ // QIODevice stuff
+ bool atEnd() const;
+ qint64 bytesAvailable() const;
+ bool canReadLine() const;
+ void close();
+ bool isSequential() const { return true; }
+
/*
* Note that this is of limited value in practice, because servers are
* usually configured to ignore such requests for security reasons.
@@ -85,10 +93,8 @@ public:
void requestTerminal(const SshPseudoTerminal &terminal);
void start();
- void closeChannel();
bool isRunning() const;
- QString errorString() const;
int exitCode() const;
QByteArray exitSignal() const;
@@ -99,8 +105,6 @@ public:
void sendSignal(const QByteArray &signal);
void kill() { sendSignal(KillSignal); }
- void sendInput(const QByteArray &data); // Should usually have a trailing newline.
-
signals:
void started();
@@ -118,6 +122,10 @@ private:
Internal::SshSendFacility &sendFacility);
SshRemoteProcess(quint32 channelId, Internal::SshSendFacility &sendFacility);
+ // QIODevice stuff
+ qint64 readData(char *data, qint64 maxlen);
+ qint64 writeData(const char *data, qint64 len);
+
void init();
Internal::SshRemoteProcessPrivate *d;
diff --git a/src/libs/utils/ssh/sshremoteprocess_p.h b/src/libs/utils/ssh/sshremoteprocess_p.h
index da47927f3a..32564ef9cb 100644
--- a/src/libs/utils/ssh/sshremoteprocess_p.h
+++ b/src/libs/utils/ssh/sshremoteprocess_p.h
@@ -52,7 +52,7 @@ class SshRemoteProcessPrivate : public AbstractSshChannel
friend class Utils::SshRemoteProcess;
public:
enum ProcessState {
- NotYetStarted, ExecRequested, StartFailed,Running, Exited
+ NotYetStarted, ExecRequested, StartFailed, Running, Exited
};
virtual void handleChannelSuccess();
@@ -60,9 +60,6 @@ public:
virtual void closeHook();
- QByteArray readAllStandardOutput();
- QByteArray readAllStandardError();
-
signals:
void started();
void readyReadStandardOutput();
@@ -76,7 +73,7 @@ private:
SshRemoteProcess *proc);
virtual void handleOpenSuccessInternal();
- virtual void handleOpenFailureInternal();
+ virtual void handleOpenFailureInternal(const QString &reason);
virtual void handleChannelDataInternal(const QByteArray &data);
virtual void handleChannelExtendedDataInternal(quint32 type,
const QByteArray &data);
diff --git a/src/plugins/debugger/gdb/remotegdbprocess.cpp b/src/plugins/debugger/gdb/remotegdbprocess.cpp
index 80a1dd5837..e9bb37aefe 100644
--- a/src/plugins/debugger/gdb/remotegdbprocess.cpp
+++ b/src/plugins/debugger/gdb/remotegdbprocess.cpp
@@ -341,7 +341,7 @@ void RemoteGdbProcess::sendInput(const QByteArray &data)
if (!isdigit(data.at(pos)))
break;
m_lastSeqNr = data.left(pos);
- m_gdbProc->sendInput(data);
+ m_gdbProc->write(data);
}
void RemoteGdbProcess::handleAppOutput()
diff --git a/src/plugins/debugger/lldb/lldbenginehost.cpp b/src/plugins/debugger/lldb/lldbenginehost.cpp
index 70189a5139..d5115bbd6a 100644
--- a/src/plugins/debugger/lldb/lldbenginehost.cpp
+++ b/src/plugins/debugger/lldb/lldbenginehost.cpp
@@ -95,7 +95,7 @@ qint64 SshIODevice::writeData (const char * data, qint64 maxSize)
startupbuffer += QByteArray::fromRawData(data, maxSize);
return maxSize;
}
- proc->sendInput(QByteArray::fromRawData(data, maxSize));
+ proc->write(data, maxSize);
return maxSize;
}
qint64 SshIODevice::readData (char * data, qint64 maxSize)
@@ -128,7 +128,7 @@ qint64 SshIODevice::readData (char * data, qint64 maxSize)
void SshIODevice::processStarted()
{
proc = runner->process();
- proc->sendInput(startupbuffer);
+ proc->write(startupbuffer);
}
void SshIODevice::outputAvailable(const QByteArray &output)
diff --git a/src/plugins/madde/maddedevicetester.cpp b/src/plugins/madde/maddedevicetester.cpp
index a275971f4e..80090f07d6 100644
--- a/src/plugins/madde/maddedevicetester.cpp
+++ b/src/plugins/madde/maddedevicetester.cpp
@@ -89,7 +89,7 @@ void MaddeDeviceTester::stopTest()
case QtTest:
case MadDeveloperTest:
case QmlToolingTest:
- m_processRunner->process()->closeChannel();
+ m_processRunner->process()->close();
break;
}
diff --git a/src/plugins/madde/maemopublisherfremantlefree.cpp b/src/plugins/madde/maemopublisherfremantlefree.cpp
index aa85f8138b..e0cf2f7043 100644
--- a/src/plugins/madde/maemopublisherfremantlefree.cpp
+++ b/src/plugins/madde/maemopublisherfremantlefree.cpp
@@ -447,7 +447,7 @@ void MaemoPublisherFremantleFree::prepareToSendFile()
emit progressReport(tr("Uploading file %1 ...")
.arg(QDir::toNativeSeparators(nextFilePath)));
QFileInfo info(nextFilePath);
- m_uploader->process()->sendInput("C0644 " + QByteArray::number(info.size())
+ m_uploader->process()->write("C0644 " + QByteArray::number(info.size())
+ ' ' + info.fileName().toUtf8() + '\n');
}
@@ -473,13 +473,13 @@ void MaemoPublisherFremantleFree::sendFile()
tr("Upload failed."));
return;
}
- m_uploader->process()->sendInput(data);
+ m_uploader->process()->write(data);
bytesToSend -= data.size();
QCoreApplication::processEvents();
if (m_state == Inactive)
return;
}
- m_uploader->process()->sendInput(QByteArray(1, '\0'));
+ m_uploader->process()->write(QByteArray(1, '\0'));
}
void MaemoPublisherFremantleFree::handleScpStdOut(const QByteArray &output)
diff --git a/src/plugins/madde/maemoremotemounter.cpp b/src/plugins/madde/maemoremotemounter.cpp
index a151feaf3d..6144036243 100644
--- a/src/plugins/madde/maemoremotemounter.cpp
+++ b/src/plugins/madde/maemoremotemounter.cpp
@@ -380,11 +380,11 @@ void MaemoRemoteMounter::setState(State newState)
m_utfsServerTimer->stop();
if (m_mountProcess) {
disconnect(m_mountProcess.data(), 0, this, 0);
- m_mountProcess->closeChannel();
+ m_mountProcess->close();
}
if (m_unmountProcess) {
disconnect(m_unmountProcess.data(), 0, this, 0);
- m_unmountProcess->closeChannel();
+ m_unmountProcess->close();
}
}
m_state = newState;
diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp
index 8c9e1cd2b9..cd9c465174 100644
--- a/src/plugins/remotelinux/linuxdevicetester.cpp
+++ b/src/plugins/remotelinux/linuxdevicetester.cpp
@@ -106,7 +106,7 @@ void GenericLinuxDeviceTester::stopTest()
d->portsGatherer.stop();
break;
case RunningUname:
- d->process->closeChannel();
+ d->process->close();
break;
case Inactive:
break;
diff --git a/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp b/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp
index 9f393b8924..d489d55030 100644
--- a/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp
+++ b/src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp
@@ -115,7 +115,7 @@ void RemoteLinuxCustomCommandDeployService::stopDeployment()
QTC_ASSERT(d->state == Running, return);
disconnect(d->runner, 0, this, 0);
- d->runner->process()->closeChannel();
+ d->runner->process()->close();
d->state = Inactive;
handleDeploymentDone();
}