forked from qt-creator/qt-creator
SSH: Make interface more Qt-ish.
This commit is contained in:
@@ -151,6 +151,9 @@ struct InteractiveSshConnectionPrivate
|
|||||||
|
|
||||||
GenericSshConnection conn;
|
GenericSshConnection conn;
|
||||||
ConnectionOutputReader *outputReader;
|
ConnectionOutputReader *outputReader;
|
||||||
|
QByteArray remoteOutput;
|
||||||
|
QMutex mutex;
|
||||||
|
QWaitCondition waitCond;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NonInteractiveSshConnectionPrivate
|
struct NonInteractiveSshConnectionPrivate
|
||||||
@@ -208,8 +211,12 @@ private:
|
|||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
QScopedPointer<char, QScopedPointerArrayDeleter<char> >
|
QScopedPointer<char, QScopedPointerArrayDeleter<char> >
|
||||||
output(m_conn->d->conn.ssh->readAndReset(channel, alloc));
|
output(m_conn->d->conn.ssh->readAndReset(channel, alloc));
|
||||||
if (output)
|
if (output) {
|
||||||
emit m_conn->remoteOutput(QByteArray(output.data()));
|
m_conn->d->mutex.lock();
|
||||||
|
m_conn->d->remoteOutput += output.data();
|
||||||
|
emit m_conn->remoteOutputAvailable();
|
||||||
|
m_conn->d->mutex.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,10 +273,25 @@ bool InteractiveSshConnection::sendInput(const QByteArray &input)
|
|||||||
|
|
||||||
void InteractiveSshConnection::quit()
|
void InteractiveSshConnection::quit()
|
||||||
{
|
{
|
||||||
|
d->mutex.lock();
|
||||||
|
d->waitCond.wakeOne();
|
||||||
|
d->mutex.unlock();
|
||||||
d->outputReader->stop();
|
d->outputReader->stop();
|
||||||
d->conn.quit();
|
d->conn.quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QByteArray InteractiveSshConnection::waitForRemoteOutput(int msecs)
|
||||||
|
{
|
||||||
|
d->mutex.lock();
|
||||||
|
if (d->remoteOutput.isEmpty())
|
||||||
|
d->waitCond.wait(&d->mutex, msecs == -1 ? ULONG_MAX : msecs);
|
||||||
|
const QByteArray remoteOutput = d->remoteOutput;
|
||||||
|
d->remoteOutput.clear();
|
||||||
|
d->mutex.unlock();
|
||||||
|
return remoteOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
InteractiveSshConnection::Ptr InteractiveSshConnection::create(const SshServerInfo &server)
|
InteractiveSshConnection::Ptr InteractiveSshConnection::create(const SshServerInfo &server)
|
||||||
{
|
{
|
||||||
return Ptr(new InteractiveSshConnection(server));
|
return Ptr(new InteractiveSshConnection(server));
|
||||||
|
|||||||
@@ -82,12 +82,13 @@ public:
|
|||||||
bool start();
|
bool start();
|
||||||
void quit();
|
void quit();
|
||||||
bool sendInput(const QByteArray &input); // Should normally end in newline.
|
bool sendInput(const QByteArray &input); // Should normally end in newline.
|
||||||
|
QByteArray waitForRemoteOutput(int msecs = -1);
|
||||||
bool hasError() const;
|
bool hasError() const;
|
||||||
QString error() const;
|
QString error() const;
|
||||||
~InteractiveSshConnection();
|
~InteractiveSshConnection();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void remoteOutput(const QByteArray &output);
|
void remoteOutputAvailable();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
InteractiveSshConnection(const SshServerInfo &server);
|
InteractiveSshConnection(const SshServerInfo &server);
|
||||||
|
|||||||
@@ -71,12 +71,12 @@ void RemoteGdbProcess::start(const QString &cmd, const QStringList &args)
|
|||||||
return;
|
return;
|
||||||
m_command = cmd;
|
m_command = cmd;
|
||||||
m_cmdArgs = args;
|
m_cmdArgs = args;
|
||||||
connect(m_gdbConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
connect(m_gdbConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleGdbOutput(QByteArray)));
|
this, SLOT(handleGdbOutput()));
|
||||||
connect(m_appOutputConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
connect(m_appOutputConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleAppOutput(QByteArray)));
|
this, SLOT(handleAppOutput()));
|
||||||
connect(m_errOutputConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
connect(m_errOutputConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleErrOutput(QByteArray)));
|
this, SLOT(handleErrOutput()));
|
||||||
m_gdbConn->start();
|
m_gdbConn->start();
|
||||||
m_errOutputConn->start();
|
m_errOutputConn->start();
|
||||||
m_appOutputConn->start();
|
m_appOutputConn->start();
|
||||||
@@ -130,7 +130,7 @@ QString RemoteGdbProcess::errorString() const
|
|||||||
return m_gdbConn ? m_gdbConn->error() : QString();
|
return m_gdbConn ? m_gdbConn->error() : QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteGdbProcess::handleGdbOutput(const QByteArray &output)
|
void RemoteGdbProcess::handleGdbOutput()
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
qDebug("%s: output is '%s'", Q_FUNC_INFO, output.data());
|
qDebug("%s: output is '%s'", Q_FUNC_INFO, output.data());
|
||||||
@@ -139,7 +139,8 @@ void RemoteGdbProcess::handleGdbOutput(const QByteArray &output)
|
|||||||
if (m_gdbState == CmdNotYetSent)
|
if (m_gdbState == CmdNotYetSent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_currentGdbOutput += removeCarriageReturn(output);
|
m_currentGdbOutput
|
||||||
|
+= removeCarriageReturn(m_gdbConn->waitForRemoteOutput(0));
|
||||||
if (!m_currentGdbOutput.endsWith('\n'))
|
if (!m_currentGdbOutput.endsWith('\n'))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -217,15 +218,17 @@ qint64 RemoteGdbProcess::sendInput(const QByteArray &data)
|
|||||||
return m_gdbConn->sendInput(data) ? data.size() : 0;
|
return m_gdbConn->sendInput(data) ? data.size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteGdbProcess::handleAppOutput(const QByteArray &output)
|
void RemoteGdbProcess::handleAppOutput()
|
||||||
{
|
{
|
||||||
|
const QByteArray output = m_appOutputConn->waitForRemoteOutput(0);
|
||||||
if (!handleAppOrErrOutput(m_appOutputConn, m_appOutputReaderState,
|
if (!handleAppOrErrOutput(m_appOutputConn, m_appOutputReaderState,
|
||||||
m_initialAppOutput, AppOutputFile, output))
|
m_initialAppOutput, AppOutputFile, output))
|
||||||
m_adapter->handleApplicationOutput(output);
|
m_adapter->handleApplicationOutput(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemoteGdbProcess::handleErrOutput(const QByteArray &output)
|
void RemoteGdbProcess::handleErrOutput()
|
||||||
{
|
{
|
||||||
|
const QByteArray output = m_errOutputConn->waitForRemoteOutput(0);
|
||||||
if (!handleAppOrErrOutput(m_errOutputConn, m_errOutputReaderState,
|
if (!handleAppOrErrOutput(m_errOutputConn, m_errOutputReaderState,
|
||||||
m_initialErrOutput, ErrOutputFile, output)) {
|
m_initialErrOutput, ErrOutputFile, output)) {
|
||||||
m_errorOutput += output;
|
m_errorOutput += output;
|
||||||
@@ -277,14 +280,14 @@ void RemoteGdbProcess::startGdb()
|
|||||||
void RemoteGdbProcess::stopReaders()
|
void RemoteGdbProcess::stopReaders()
|
||||||
{
|
{
|
||||||
if (m_appOutputConn) {
|
if (m_appOutputConn) {
|
||||||
disconnect(m_appOutputConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
disconnect(m_appOutputConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleAppOutput(QByteArray)));
|
this, SLOT(handleAppOutput()));
|
||||||
m_appOutputConn->sendInput(CtrlC);
|
m_appOutputConn->sendInput(CtrlC);
|
||||||
m_appOutputConn->quit();
|
m_appOutputConn->quit();
|
||||||
}
|
}
|
||||||
if (m_errOutputConn) {
|
if (m_errOutputConn) {
|
||||||
disconnect(m_errOutputConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
disconnect(m_errOutputConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleErrOutput(QByteArray)));
|
this, SLOT(handleErrOutput()));
|
||||||
m_errOutputConn->sendInput(CtrlC);
|
m_errOutputConn->sendInput(CtrlC);
|
||||||
m_errOutputConn->quit();
|
m_errOutputConn->quit();
|
||||||
}
|
}
|
||||||
@@ -316,8 +319,8 @@ void RemoteGdbProcess::checkForGdbExit(QByteArray &output)
|
|||||||
const QByteArray exitString("^exit");
|
const QByteArray exitString("^exit");
|
||||||
const int exitPos = output.indexOf(exitString);
|
const int exitPos = output.indexOf(exitString);
|
||||||
if (exitPos != -1) {
|
if (exitPos != -1) {
|
||||||
disconnect(m_gdbConn.data(), SIGNAL(remoteOutput(QByteArray)),
|
disconnect(m_gdbConn.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleGdbOutput(QByteArray)));
|
this, SLOT(handleGdbOutput()));
|
||||||
output.remove(exitPos + exitString.size(), output.size());
|
output.remove(exitPos + exitString.size(), output.size());
|
||||||
stopReaders();
|
stopReaders();
|
||||||
emit finished(0, QProcess::NormalExit);
|
emit finished(0, QProcess::NormalExit);
|
||||||
|
|||||||
@@ -68,9 +68,9 @@ public:
|
|||||||
static const QByteArray CtrlC;
|
static const QByteArray CtrlC;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleGdbOutput(const QByteArray &output);
|
void handleGdbOutput();
|
||||||
void handleAppOutput(const QByteArray &output);
|
void handleAppOutput();
|
||||||
void handleErrOutput(const QByteArray &output);
|
void handleErrOutput();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum CmdState { CmdNotYetSent, CmdSent, CmdReceived };
|
enum CmdState { CmdNotYetSent, CmdSent, CmdReceived };
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ MaemoSshRunner::MaemoSshRunner(const Core::SshServerInfo &server,
|
|||||||
bool MaemoSshRunner::runInternal()
|
bool MaemoSshRunner::runInternal()
|
||||||
{
|
{
|
||||||
createConnection();
|
createConnection();
|
||||||
connect(m_connection.data(), SIGNAL(remoteOutput(QByteArray)),
|
connect(m_connection.data(), SIGNAL(remoteOutputAvailable()),
|
||||||
this, SLOT(handleRemoteOutput(QByteArray)));
|
this, SLOT(handleRemoteOutput()));
|
||||||
m_endMarkerCount = 0;
|
m_endMarkerCount = 0;
|
||||||
m_promptEncountered = false;
|
m_promptEncountered = false;
|
||||||
if (!m_connection->start())
|
if (!m_connection->start())
|
||||||
@@ -115,8 +115,10 @@ bool MaemoSshRunner::runInternal()
|
|||||||
return !m_connection->hasError();
|
return !m_connection->hasError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaemoSshRunner::handleRemoteOutput(const QByteArray &output)
|
void MaemoSshRunner::handleRemoteOutput()
|
||||||
{
|
{
|
||||||
|
const QByteArray output = m_connection->waitForRemoteOutput(0);
|
||||||
|
|
||||||
// Wait for a prompt before sending the command.
|
// Wait for a prompt before sending the command.
|
||||||
if (!m_promptEncountered) {
|
if (!m_promptEncountered) {
|
||||||
if (output.indexOf(m_prompt) != -1) {
|
if (output.indexOf(m_prompt) != -1) {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ signals:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool runInternal();
|
virtual bool runInternal();
|
||||||
Q_SLOT void handleRemoteOutput(const QByteArray &output);
|
Q_SLOT void handleRemoteOutput();
|
||||||
|
|
||||||
static const QByteArray EndMarker;
|
static const QByteArray EndMarker;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user