forked from qt-creator/qt-creator
SSH: Derive SshRemoteProcess from QIODevice.
Now it looks even more like QProcess. Things like process channels are still missing. Change-Id: I3f30cd00ed4a054d02e83add9a6f4162b48f8345 Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
This commit is contained in:
@@ -821,13 +821,13 @@ void SftpChannelPrivate::handleOpenSuccessInternal()
|
|||||||
m_sftpState = SubsystemRequested;
|
m_sftpState = SubsystemRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SftpChannelPrivate::handleOpenFailureInternal()
|
void SftpChannelPrivate::handleOpenFailureInternal(const QString &reason)
|
||||||
{
|
{
|
||||||
if (channelState() != SessionRequested) {
|
if (channelState() != SessionRequested) {
|
||||||
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
|
throw SSH_SERVER_EXCEPTION(SSH_DISCONNECT_PROTOCOL_ERROR,
|
||||||
"Unexpected SSH_MSG_CHANNEL_OPEN_FAILURE packet.");
|
"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,
|
void SftpChannelPrivate::sendReadRequest(const SftpDownload::Ptr &job,
|
||||||
|
@@ -74,7 +74,7 @@ private:
|
|||||||
SftpJobId createJob(const AbstractSftpOperation::Ptr &job);
|
SftpJobId createJob(const AbstractSftpOperation::Ptr &job);
|
||||||
|
|
||||||
virtual void handleOpenSuccessInternal();
|
virtual void handleOpenSuccessInternal();
|
||||||
virtual void handleOpenFailureInternal();
|
virtual void handleOpenFailureInternal(const QString &reason);
|
||||||
virtual void handleChannelDataInternal(const QByteArray &data);
|
virtual void handleChannelDataInternal(const QByteArray &data);
|
||||||
virtual void handleChannelExtendedDataInternal(quint32 type,
|
virtual void handleChannelExtendedDataInternal(quint32 type,
|
||||||
const QByteArray &data);
|
const QByteArray &data);
|
||||||
|
@@ -84,7 +84,7 @@ void AbstractSshChannel::requestSessionStart()
|
|||||||
setChannelState(SessionRequested);
|
setChannelState(SessionRequested);
|
||||||
m_timeoutTimer->start(ReplyTimeout);
|
m_timeoutTimer->start(ReplyTimeout);
|
||||||
} catch (Botan::Exception &e) {
|
} catch (Botan::Exception &e) {
|
||||||
m_errorString = QString::fromAscii(e.what());
|
qDebug("Botan error: %s", e.what());
|
||||||
closeChannel();
|
closeChannel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ void AbstractSshChannel::sendData(const QByteArray &data)
|
|||||||
m_sendBuffer += data;
|
m_sendBuffer += data;
|
||||||
flushSendBuffer();
|
flushSendBuffer();
|
||||||
} catch (Botan::Exception &e) {
|
} catch (Botan::Exception &e) {
|
||||||
m_errorString = QString::fromAscii(e.what());
|
qDebug("Botan error: %s", e.what());
|
||||||
closeChannel();
|
closeChannel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,8 +163,7 @@ void AbstractSshChannel::handleOpenFailure(const QString &reason)
|
|||||||
#ifdef CREATOR_SSH_DEBUG
|
#ifdef CREATOR_SSH_DEBUG
|
||||||
qDebug("Channel open request failed for channel %u", m_localChannel);
|
qDebug("Channel open request failed for channel %u", m_localChannel);
|
||||||
#endif
|
#endif
|
||||||
m_errorString = reason;
|
handleOpenFailureInternal(reason);
|
||||||
handleOpenFailureInternal();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractSshChannel::handleChannelEof()
|
void AbstractSshChannel::handleChannelEof()
|
||||||
|
@@ -58,9 +58,6 @@ public:
|
|||||||
ChannelState channelState() const { return m_state; }
|
ChannelState channelState() const { return m_state; }
|
||||||
void setChannelState(ChannelState 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 localChannelId() const { return m_localChannel; }
|
||||||
quint32 remoteChannel() const { return m_remoteChannel; }
|
quint32 remoteChannel() const { return m_remoteChannel; }
|
||||||
|
|
||||||
@@ -101,7 +98,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void handleOpenSuccessInternal() = 0;
|
virtual void handleOpenSuccessInternal() = 0;
|
||||||
virtual void handleOpenFailureInternal() = 0;
|
virtual void handleOpenFailureInternal(const QString &reason) = 0;
|
||||||
virtual void handleChannelDataInternal(const QByteArray &data) = 0;
|
virtual void handleChannelDataInternal(const QByteArray &data) = 0;
|
||||||
virtual void handleChannelExtendedDataInternal(quint32 type,
|
virtual void handleChannelExtendedDataInternal(quint32 type,
|
||||||
const QByteArray &data) = 0;
|
const QByteArray &data) = 0;
|
||||||
@@ -119,7 +116,6 @@ private:
|
|||||||
quint32 m_remoteMaxPacketSize;
|
quint32 m_remoteMaxPacketSize;
|
||||||
ChannelState m_state;
|
ChannelState m_state;
|
||||||
QByteArray m_sendBuffer;
|
QByteArray m_sendBuffer;
|
||||||
QString m_errorString;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Utils::SshRemoteProcess
|
\class Utils::SshRemoteProcess
|
||||||
|
|
||||||
@@ -49,17 +51,10 @@
|
|||||||
|
|
||||||
Objects are created via SshConnection::createRemoteProcess.
|
Objects are created via SshConnection::createRemoteProcess.
|
||||||
The process is started via the start() member function.
|
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
|
If the process needs a pseudo terminal, you can request one
|
||||||
via requestTerminal() before calling start().
|
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 {
|
namespace Utils {
|
||||||
@@ -99,12 +94,63 @@ SshRemoteProcess::~SshRemoteProcess()
|
|||||||
delete d;
|
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()
|
void SshRemoteProcess::init()
|
||||||
{
|
{
|
||||||
connect(d, SIGNAL(started()), this, SIGNAL(started()),
|
connect(d, SIGNAL(started()), this, SIGNAL(started()),
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyReadStandardOutput()),
|
connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyReadStandardOutput()),
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
|
connect(d, SIGNAL(readyReadStandardOutput()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
|
||||||
connect(d, SIGNAL(readyReadStandardError()), this,
|
connect(d, SIGNAL(readyReadStandardError()), this,
|
||||||
SIGNAL(readyReadStandardError()), Qt::QueuedConnection);
|
SIGNAL(readyReadStandardError()), Qt::QueuedConnection);
|
||||||
connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), Qt::QueuedConnection);
|
connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), Qt::QueuedConnection);
|
||||||
@@ -129,6 +175,7 @@ void SshRemoteProcess::start()
|
|||||||
#ifdef CREATOR_SSH_DEBUG
|
#ifdef CREATOR_SSH_DEBUG
|
||||||
qDebug("process start requested, channel id = %u", d->localChannelId());
|
qDebug("process start requested, channel id = %u", d->localChannelId());
|
||||||
#endif
|
#endif
|
||||||
|
QIODevice::open(QIODevice::ReadWrite);
|
||||||
d->requestSessionStart();
|
d->requestSessionStart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -140,36 +187,19 @@ void SshRemoteProcess::sendSignal(const QByteArray &signal)
|
|||||||
d->m_sendFacility.sendChannelSignalPacket(d->remoteChannel(),
|
d->m_sendFacility.sendChannelSignalPacket(d->remoteChannel(),
|
||||||
signal);
|
signal);
|
||||||
} catch (Botan::Exception &e) {
|
} catch (Botan::Exception &e) {
|
||||||
d->setError(QString::fromAscii(e.what()));
|
setErrorString(QString::fromAscii(e.what()));
|
||||||
d->closeChannel();
|
d->closeChannel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshRemoteProcess::closeChannel()
|
|
||||||
{
|
|
||||||
d->closeChannel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SshRemoteProcess::sendInput(const QByteArray &data)
|
|
||||||
{
|
|
||||||
if (isRunning())
|
|
||||||
d->sendData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SshRemoteProcess::isRunning() const
|
bool SshRemoteProcess::isRunning() const
|
||||||
{
|
{
|
||||||
return d->m_procState == Internal::SshRemoteProcessPrivate::Running;
|
return d->m_procState == Internal::SshRemoteProcessPrivate::Running;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SshRemoteProcess::errorString() const { return d->errorString(); }
|
|
||||||
|
|
||||||
int SshRemoteProcess::exitCode() const { return d->m_exitCode; }
|
int SshRemoteProcess::exitCode() const { return d->m_exitCode; }
|
||||||
|
|
||||||
QByteArray SshRemoteProcess::exitSignal() const { return d->m_signal; }
|
QByteArray SshRemoteProcess::exitSignal() const { return d->m_signal; }
|
||||||
|
|
||||||
QByteArray SshRemoteProcess::readAllStandardOutput() { return d->readAllStandardOutput(); }
|
|
||||||
QByteArray SshRemoteProcess::readAllStandardError() { return d->readAllStandardError(); }
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command,
|
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()
|
void SshRemoteProcessPrivate::closeHook()
|
||||||
{
|
{
|
||||||
if (m_wasRunning) {
|
if (m_wasRunning) {
|
||||||
@@ -256,9 +272,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal()
|
|||||||
m_timeoutTimer->start(ReplyTimeout);
|
m_timeoutTimer->start(ReplyTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshRemoteProcessPrivate::handleOpenFailureInternal()
|
void SshRemoteProcessPrivate::handleOpenFailureInternal(const QString &reason)
|
||||||
{
|
{
|
||||||
setProcState(StartFailed);
|
setProcState(StartFailed);
|
||||||
|
m_proc->setErrorString(reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshRemoteProcessPrivate::handleChannelSuccess()
|
void SshRemoteProcessPrivate::handleChannelSuccess()
|
||||||
@@ -313,9 +330,9 @@ void SshRemoteProcessPrivate::handleExitSignal(const SshChannelExitSignal &signa
|
|||||||
#ifdef CREATOR_SSH_DEBUG
|
#ifdef CREATOR_SSH_DEBUG
|
||||||
qDebug("Exit due to signal %s", signal.signal.data());
|
qDebug("Exit due to signal %s", signal.signal.data());
|
||||||
#endif
|
#endif
|
||||||
setError(signal.error);
|
|
||||||
m_signal = signal.signal;
|
m_signal = signal.signal;
|
||||||
m_procState = Exited;
|
m_procState = Exited;
|
||||||
|
m_proc->setErrorString(tr("Process killed by signal"));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
#include <utils/utils_global.h>
|
#include <utils/utils_global.h>
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QProcess>
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
@@ -50,7 +50,8 @@ class SshRemoteProcessPrivate;
|
|||||||
class SshSendFacility;
|
class SshSendFacility;
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QObject
|
// TODO: ProcessChannel
|
||||||
|
class QTCREATOR_UTILS_EXPORT SshRemoteProcess : public QIODevice
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
@@ -77,6 +78,13 @@ public:
|
|||||||
|
|
||||||
~SshRemoteProcess();
|
~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
|
* Note that this is of limited value in practice, because servers are
|
||||||
* usually configured to ignore such requests for security reasons.
|
* usually configured to ignore such requests for security reasons.
|
||||||
@@ -85,10 +93,8 @@ public:
|
|||||||
|
|
||||||
void requestTerminal(const SshPseudoTerminal &terminal);
|
void requestTerminal(const SshPseudoTerminal &terminal);
|
||||||
void start();
|
void start();
|
||||||
void closeChannel();
|
|
||||||
|
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
QString errorString() const;
|
|
||||||
int exitCode() const;
|
int exitCode() const;
|
||||||
QByteArray exitSignal() const;
|
QByteArray exitSignal() const;
|
||||||
|
|
||||||
@@ -99,8 +105,6 @@ public:
|
|||||||
void sendSignal(const QByteArray &signal);
|
void sendSignal(const QByteArray &signal);
|
||||||
void kill() { sendSignal(KillSignal); }
|
void kill() { sendSignal(KillSignal); }
|
||||||
|
|
||||||
void sendInput(const QByteArray &data); // Should usually have a trailing newline.
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
|
|
||||||
@@ -118,6 +122,10 @@ private:
|
|||||||
Internal::SshSendFacility &sendFacility);
|
Internal::SshSendFacility &sendFacility);
|
||||||
SshRemoteProcess(quint32 channelId, 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();
|
void init();
|
||||||
|
|
||||||
Internal::SshRemoteProcessPrivate *d;
|
Internal::SshRemoteProcessPrivate *d;
|
||||||
|
@@ -60,9 +60,6 @@ public:
|
|||||||
|
|
||||||
virtual void closeHook();
|
virtual void closeHook();
|
||||||
|
|
||||||
QByteArray readAllStandardOutput();
|
|
||||||
QByteArray readAllStandardError();
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
void readyReadStandardOutput();
|
void readyReadStandardOutput();
|
||||||
@@ -76,7 +73,7 @@ private:
|
|||||||
SshRemoteProcess *proc);
|
SshRemoteProcess *proc);
|
||||||
|
|
||||||
virtual void handleOpenSuccessInternal();
|
virtual void handleOpenSuccessInternal();
|
||||||
virtual void handleOpenFailureInternal();
|
virtual void handleOpenFailureInternal(const QString &reason);
|
||||||
virtual void handleChannelDataInternal(const QByteArray &data);
|
virtual void handleChannelDataInternal(const QByteArray &data);
|
||||||
virtual void handleChannelExtendedDataInternal(quint32 type,
|
virtual void handleChannelExtendedDataInternal(quint32 type,
|
||||||
const QByteArray &data);
|
const QByteArray &data);
|
||||||
|
@@ -341,7 +341,7 @@ void RemoteGdbProcess::sendInput(const QByteArray &data)
|
|||||||
if (!isdigit(data.at(pos)))
|
if (!isdigit(data.at(pos)))
|
||||||
break;
|
break;
|
||||||
m_lastSeqNr = data.left(pos);
|
m_lastSeqNr = data.left(pos);
|
||||||
m_gdbProc->sendInput(data);
|
m_gdbProc->write(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteGdbProcess::handleAppOutput()
|
void RemoteGdbProcess::handleAppOutput()
|
||||||
|
@@ -95,7 +95,7 @@ qint64 SshIODevice::writeData (const char * data, qint64 maxSize)
|
|||||||
startupbuffer += QByteArray::fromRawData(data, maxSize);
|
startupbuffer += QByteArray::fromRawData(data, maxSize);
|
||||||
return maxSize;
|
return maxSize;
|
||||||
}
|
}
|
||||||
proc->sendInput(QByteArray::fromRawData(data, maxSize));
|
proc->write(data, maxSize);
|
||||||
return maxSize;
|
return maxSize;
|
||||||
}
|
}
|
||||||
qint64 SshIODevice::readData (char * data, qint64 maxSize)
|
qint64 SshIODevice::readData (char * data, qint64 maxSize)
|
||||||
@@ -128,7 +128,7 @@ qint64 SshIODevice::readData (char * data, qint64 maxSize)
|
|||||||
void SshIODevice::processStarted()
|
void SshIODevice::processStarted()
|
||||||
{
|
{
|
||||||
proc = runner->process();
|
proc = runner->process();
|
||||||
proc->sendInput(startupbuffer);
|
proc->write(startupbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SshIODevice::outputAvailable(const QByteArray &output)
|
void SshIODevice::outputAvailable(const QByteArray &output)
|
||||||
|
@@ -89,7 +89,7 @@ void MaddeDeviceTester::stopTest()
|
|||||||
case QtTest:
|
case QtTest:
|
||||||
case MadDeveloperTest:
|
case MadDeveloperTest:
|
||||||
case QmlToolingTest:
|
case QmlToolingTest:
|
||||||
m_processRunner->process()->closeChannel();
|
m_processRunner->process()->close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -447,7 +447,7 @@ void MaemoPublisherFremantleFree::prepareToSendFile()
|
|||||||
emit progressReport(tr("Uploading file %1 ...")
|
emit progressReport(tr("Uploading file %1 ...")
|
||||||
.arg(QDir::toNativeSeparators(nextFilePath)));
|
.arg(QDir::toNativeSeparators(nextFilePath)));
|
||||||
QFileInfo info(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');
|
+ ' ' + info.fileName().toUtf8() + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -473,13 +473,13 @@ void MaemoPublisherFremantleFree::sendFile()
|
|||||||
tr("Upload failed."));
|
tr("Upload failed."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_uploader->process()->sendInput(data);
|
m_uploader->process()->write(data);
|
||||||
bytesToSend -= data.size();
|
bytesToSend -= data.size();
|
||||||
QCoreApplication::processEvents();
|
QCoreApplication::processEvents();
|
||||||
if (m_state == Inactive)
|
if (m_state == Inactive)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_uploader->process()->sendInput(QByteArray(1, '\0'));
|
m_uploader->process()->write(QByteArray(1, '\0'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoPublisherFremantleFree::handleScpStdOut(const QByteArray &output)
|
void MaemoPublisherFremantleFree::handleScpStdOut(const QByteArray &output)
|
||||||
|
@@ -380,11 +380,11 @@ void MaemoRemoteMounter::setState(State newState)
|
|||||||
m_utfsServerTimer->stop();
|
m_utfsServerTimer->stop();
|
||||||
if (m_mountProcess) {
|
if (m_mountProcess) {
|
||||||
disconnect(m_mountProcess.data(), 0, this, 0);
|
disconnect(m_mountProcess.data(), 0, this, 0);
|
||||||
m_mountProcess->closeChannel();
|
m_mountProcess->close();
|
||||||
}
|
}
|
||||||
if (m_unmountProcess) {
|
if (m_unmountProcess) {
|
||||||
disconnect(m_unmountProcess.data(), 0, this, 0);
|
disconnect(m_unmountProcess.data(), 0, this, 0);
|
||||||
m_unmountProcess->closeChannel();
|
m_unmountProcess->close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_state = newState;
|
m_state = newState;
|
||||||
|
@@ -106,7 +106,7 @@ void GenericLinuxDeviceTester::stopTest()
|
|||||||
d->portsGatherer.stop();
|
d->portsGatherer.stop();
|
||||||
break;
|
break;
|
||||||
case RunningUname:
|
case RunningUname:
|
||||||
d->process->closeChannel();
|
d->process->close();
|
||||||
break;
|
break;
|
||||||
case Inactive:
|
case Inactive:
|
||||||
break;
|
break;
|
||||||
|
@@ -115,7 +115,7 @@ void RemoteLinuxCustomCommandDeployService::stopDeployment()
|
|||||||
QTC_ASSERT(d->state == Running, return);
|
QTC_ASSERT(d->state == Running, return);
|
||||||
|
|
||||||
disconnect(d->runner, 0, this, 0);
|
disconnect(d->runner, 0, this, 0);
|
||||||
d->runner->process()->closeChannel();
|
d->runner->process()->close();
|
||||||
d->state = Inactive;
|
d->state = Inactive;
|
||||||
handleDeploymentDone();
|
handleDeploymentDone();
|
||||||
}
|
}
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include <utils/ssh/sshpseudoterminal.h>
|
#include <utils/ssh/sshpseudoterminal.h>
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -75,9 +76,10 @@ void RemoteProcessTest::run()
|
|||||||
|
|
||||||
void RemoteProcessTest::handleConnectionError()
|
void RemoteProcessTest::handleConnectionError()
|
||||||
{
|
{
|
||||||
std::cerr << "Error: Connection failure ("
|
const QString error = m_state == TestingIoDevice
|
||||||
<< qPrintable(m_remoteRunner->lastConnectionErrorString()) << ")."
|
? m_sshConnection->errorString() : m_remoteRunner->lastConnectionErrorString();
|
||||||
<< std::endl;
|
|
||||||
|
std::cerr << "Error: Connection failure (" << qPrintable(error) << ")." << std::endl;
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +94,11 @@ void RemoteProcessTest::handleProcessStarted()
|
|||||||
Utils::SshRemoteProcessRunner * const killer
|
Utils::SshRemoteProcessRunner * const killer
|
||||||
= new Utils::SshRemoteProcessRunner(this);
|
= new Utils::SshRemoteProcessRunner(this);
|
||||||
killer->run("pkill -9 sleep", m_sshParams);
|
killer->run("pkill -9 sleep", m_sshParams);
|
||||||
|
} else if (m_state == TestingIoDevice) {
|
||||||
|
connect(m_catProcess.data(), SIGNAL(readyRead()), SLOT(handleReadyRead()));
|
||||||
|
m_textStream = new QTextStream(m_catProcess.data());
|
||||||
|
*m_textStream << testString();
|
||||||
|
m_textStream->flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,10 +205,16 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus)
|
|||||||
qApp->quit();
|
qApp->quit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::cout << "Ok.\nAll tests succeeded." << std::endl;
|
std::cout << "Ok.\nTesting I/O device functionality... " << std::flush;
|
||||||
qApp->quit();
|
m_state = TestingIoDevice;
|
||||||
|
m_sshConnection = Utils::SshConnection::create(m_sshParams);
|
||||||
|
connect(m_sshConnection.data(), SIGNAL(connected()), SLOT(handleConnected()));
|
||||||
|
connect(m_sshConnection.data(), SIGNAL(error(Utils::SshError)),
|
||||||
|
SLOT(handleConnectionError()));
|
||||||
|
m_sshConnection->connectToHost();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case TestingIoDevice:
|
||||||
case Inactive:
|
case Inactive:
|
||||||
Q_ASSERT(false);
|
Q_ASSERT(false);
|
||||||
}
|
}
|
||||||
@@ -216,16 +229,23 @@ void RemoteProcessTest::handleProcessClosed(int exitStatus)
|
|||||||
qApp->quit();
|
qApp->quit();
|
||||||
break;
|
break;
|
||||||
case SshRemoteProcess::KilledBySignal:
|
case SshRemoteProcess::KilledBySignal:
|
||||||
if (m_state != TestingCrash) {
|
switch (m_state) {
|
||||||
std::cerr << "Error: Unexpected crash." << std::endl;
|
case TestingCrash:
|
||||||
qApp->quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::cout << "Ok.\nTesting remote process with terminal... " << std::flush;
|
std::cout << "Ok.\nTesting remote process with terminal... " << std::flush;
|
||||||
m_state = TestingTerminal;
|
m_state = TestingTerminal;
|
||||||
m_started = false;
|
m_started = false;
|
||||||
m_timeoutTimer->start();
|
m_timeoutTimer->start();
|
||||||
m_remoteRunner->runInTerminal("top -n 1", SshPseudoTerminal(), m_sshParams);
|
m_remoteRunner->runInTerminal("top -n 1", SshPseudoTerminal(), m_sshParams);
|
||||||
|
break;
|
||||||
|
case TestingIoDevice:
|
||||||
|
std::cout << "Ok.\nAll tests succeeded." << std::endl;
|
||||||
|
qApp->quit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
std::cerr << "Error: Unexpected crash." << std::endl;
|
||||||
|
qApp->quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,3 +254,35 @@ void RemoteProcessTest::handleTimeout()
|
|||||||
std::cerr << "Error: Timeout waiting for progress." << std::endl;
|
std::cerr << "Error: Timeout waiting for progress." << std::endl;
|
||||||
qApp->quit();
|
qApp->quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoteProcessTest::handleConnected()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_state == TestingIoDevice);
|
||||||
|
|
||||||
|
m_catProcess = m_sshConnection->createRemoteProcess(QString::fromLocal8Bit("cat").toUtf8());
|
||||||
|
connect(m_catProcess.data(), SIGNAL(started()), SLOT(handleProcessStarted()));
|
||||||
|
connect(m_catProcess.data(), SIGNAL(closed(int)), SLOT(handleProcessClosed(int)));
|
||||||
|
m_started = false;
|
||||||
|
m_timeoutTimer->start();
|
||||||
|
m_catProcess->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString RemoteProcessTest::testString() const
|
||||||
|
{
|
||||||
|
return QLatin1String("x");
|
||||||
|
}
|
||||||
|
|
||||||
|
void RemoteProcessTest::handleReadyRead()
|
||||||
|
{
|
||||||
|
Q_ASSERT(m_state == TestingIoDevice);
|
||||||
|
|
||||||
|
const QString &data = QString::fromUtf8(m_catProcess->readAll());
|
||||||
|
if (data != testString()) {
|
||||||
|
std::cerr << "Testing of QIODevice functionality failed: Expected '"
|
||||||
|
<< qPrintable(testString()) << "', got '" << qPrintable(data) << "'." << std::endl;
|
||||||
|
qApp->exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Utils::SshRemoteProcessRunner * const killer = new Utils::SshRemoteProcessRunner(this);
|
||||||
|
killer->run("pkill -9 cat", m_sshParams);
|
||||||
|
}
|
||||||
|
@@ -35,9 +35,11 @@
|
|||||||
|
|
||||||
#include <utils/ssh/sshremoteprocessrunner.h>
|
#include <utils/ssh/sshremoteprocessrunner.h>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QTimer);
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QTextStream)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QTimer)
|
||||||
|
|
||||||
class RemoteProcessTest : public QObject
|
class RemoteProcessTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -53,13 +55,22 @@ private slots:
|
|||||||
void handleProcessStderr(const QByteArray &output);
|
void handleProcessStderr(const QByteArray &output);
|
||||||
void handleProcessClosed(int exitStatus);
|
void handleProcessClosed(int exitStatus);
|
||||||
void handleTimeout();
|
void handleTimeout();
|
||||||
|
void handleReadyRead();
|
||||||
|
void handleConnected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum State { Inactive, TestingSuccess, TestingFailure, TestingCrash, TestingTerminal };
|
enum State {
|
||||||
|
Inactive, TestingSuccess, TestingFailure, TestingCrash, TestingTerminal, TestingIoDevice
|
||||||
|
};
|
||||||
|
|
||||||
|
QString testString() const;
|
||||||
|
|
||||||
const Utils::SshConnectionParameters m_sshParams;
|
const Utils::SshConnectionParameters m_sshParams;
|
||||||
QTimer * const m_timeoutTimer;
|
QTimer * const m_timeoutTimer;
|
||||||
|
QTextStream *m_textStream;
|
||||||
Utils::SshRemoteProcessRunner * const m_remoteRunner;
|
Utils::SshRemoteProcessRunner * const m_remoteRunner;
|
||||||
|
Utils::SshRemoteProcess::Ptr m_catProcess;
|
||||||
|
Utils::SshConnection::Ptr m_sshConnection;
|
||||||
QByteArray m_remoteStdout;
|
QByteArray m_remoteStdout;
|
||||||
QByteArray m_remoteStderr;
|
QByteArray m_remoteStderr;
|
||||||
State m_state;
|
State m_state;
|
||||||
|
@@ -115,5 +115,5 @@ void Shell::handleChannelClosed(int exitStatus)
|
|||||||
|
|
||||||
void Shell::handleStdin()
|
void Shell::handleStdin()
|
||||||
{
|
{
|
||||||
m_shell->sendInput(m_stdin->readLine());
|
m_shell->write(m_stdin->readLine());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user