diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/utils/ssh/sftpchannel.cpp | 4 | ||||
-rw-r--r-- | src/libs/utils/ssh/sftpchannel_p.h | 2 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshchannel.cpp | 7 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshchannel_p.h | 6 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.cpp | 103 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.h | 20 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess_p.h | 7 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/remotegdbprocess.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/lldb/lldbenginehost.cpp | 4 | ||||
-rw-r--r-- | src/plugins/madde/maddedevicetester.cpp | 2 | ||||
-rw-r--r-- | src/plugins/madde/maemopublisherfremantlefree.cpp | 6 | ||||
-rw-r--r-- | src/plugins/madde/maemoremotemounter.cpp | 4 | ||||
-rw-r--r-- | src/plugins/remotelinux/linuxdevicetester.cpp | 2 | ||||
-rw-r--r-- | src/plugins/remotelinux/remotelinuxcustomcommanddeployservice.cpp | 2 |
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(); } |