summaryrefslogtreecommitdiff
path: root/src/libs/utils/ssh/sshremoteprocess.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/utils/ssh/sshremoteprocess.cpp')
-rw-r--r--src/libs/utils/ssh/sshremoteprocess.cpp103
1 files changed, 60 insertions, 43 deletions
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