forked from qt-creator/qt-creator
SSH: Implement pseudo terminal support.
Untested yet, because SSH tests are currently broken. (They are fixed in 2.2 and will be merged back soon.)
This commit is contained in:
@@ -154,6 +154,23 @@ void SshOutgoingPacket::generateEnvPacket(quint32 remoteChannel,
|
|||||||
.appendBool(false).appendString(var).appendString(value).finalize();
|
.appendBool(false).appendString(var).appendString(value).finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SshOutgoingPacket::generatePtyRequestPacket(quint32 remoteChannel,
|
||||||
|
const SshPseudoTerminal &terminal)
|
||||||
|
{
|
||||||
|
init(SSH_MSG_CHANNEL_REQUEST).appendInt(remoteChannel)
|
||||||
|
.appendString("pty-req").appendBool(false)
|
||||||
|
.appendString(terminal.termType).appendInt(terminal.columnCount)
|
||||||
|
.appendInt(terminal.rowCount);
|
||||||
|
QByteArray modeString;
|
||||||
|
for (SshPseudoTerminal::ModeMap::ConstIterator it = terminal.modes.constBegin();
|
||||||
|
it != terminal.modes.constEnd(); ++it) {
|
||||||
|
modeString += encodeInt(static_cast<quint8>(it.key()));
|
||||||
|
modeString += encodeInt(it.value());
|
||||||
|
}
|
||||||
|
modeString += encodeInt(static_cast<quint8>(0)); // TTY_OP_END
|
||||||
|
appendString(modeString).finalize();
|
||||||
|
}
|
||||||
|
|
||||||
void SshOutgoingPacket::generateExecPacket(quint32 remoteChannel,
|
void SshOutgoingPacket::generateExecPacket(quint32 remoteChannel,
|
||||||
const QByteArray &command)
|
const QByteArray &command)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,8 @@
|
|||||||
|
|
||||||
#include "sshpacket_p.h"
|
#include "sshpacket_p.h"
|
||||||
|
|
||||||
|
#include "sshpseudoterminal.h"
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -65,6 +67,8 @@ public:
|
|||||||
quint32 maxPacketSize);
|
quint32 maxPacketSize);
|
||||||
void generateEnvPacket(quint32 remoteChannel, const QByteArray &var,
|
void generateEnvPacket(quint32 remoteChannel, const QByteArray &var,
|
||||||
const QByteArray &value);
|
const QByteArray &value);
|
||||||
|
void generatePtyRequestPacket(quint32 remoteChannel,
|
||||||
|
const SshPseudoTerminal &terminal);
|
||||||
void generateExecPacket(quint32 remoteChannel, const QByteArray &command);
|
void generateExecPacket(quint32 remoteChannel, const QByteArray &command);
|
||||||
void generateSftpPacket(quint32 remoteChannel);
|
void generateSftpPacket(quint32 remoteChannel);
|
||||||
void generateWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd);
|
void generateWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd);
|
||||||
|
|||||||
@@ -39,6 +39,8 @@
|
|||||||
|
|
||||||
#include <botan/exceptn.h>
|
#include <botan/exceptn.h>
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -57,8 +59,8 @@
|
|||||||
|
|
||||||
Therefore, the only sensible use case for calling closeChannel() is to
|
Therefore, the only sensible use case for calling closeChannel() is to
|
||||||
get rid of an SshRemoteProces object before the process is actually started.
|
get rid of an SshRemoteProces object before the process is actually started.
|
||||||
Note that the process does not have a terminal, so you can't use it
|
If the process needs a pseudo terminal, you can request one
|
||||||
for applications that require one.
|
via requestTerminal() before calling start().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -105,6 +107,13 @@ void SshRemoteProcess::addToEnvironment(const QByteArray &var, const QByteArray
|
|||||||
d->m_env << qMakePair(var, value); // Cached locally and sent on start()
|
d->m_env << qMakePair(var, value); // Cached locally and sent on start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SshRemoteProcess::requestTerminal(const SshPseudoTerminal &terminal)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(d->channelState() == Internal::SshRemoteProcessPrivate::Inactive, return);
|
||||||
|
d->m_useTerminal = true;
|
||||||
|
d->m_terminal = terminal;
|
||||||
|
}
|
||||||
|
|
||||||
void SshRemoteProcess::start()
|
void SshRemoteProcess::start()
|
||||||
{
|
{
|
||||||
if (d->channelState() == Internal::SshRemoteProcessPrivate::Inactive) {
|
if (d->channelState() == Internal::SshRemoteProcessPrivate::Inactive) {
|
||||||
@@ -154,7 +163,8 @@ namespace Internal {
|
|||||||
SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command,
|
SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command,
|
||||||
quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc)
|
quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc)
|
||||||
: AbstractSshChannel(channelId, sendFacility), m_procState(NotYetStarted),
|
: AbstractSshChannel(channelId, sendFacility), m_procState(NotYetStarted),
|
||||||
m_wasRunning(false), m_exitCode(0), m_command(command), m_proc(proc)
|
m_wasRunning(false), m_exitCode(0), m_command(command),
|
||||||
|
m_useTerminal(false), m_proc(proc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,6 +199,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal()
|
|||||||
envVar.second);
|
envVar.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_useTerminal) {
|
||||||
|
// TODO: Encode m_terminal
|
||||||
|
}
|
||||||
|
|
||||||
m_sendFacility.sendExecPacket(remoteChannel(), m_command);
|
m_sendFacility.sendExecPacket(remoteChannel(), m_command);
|
||||||
setProcState(ExecRequested);
|
setProcState(ExecRequested);
|
||||||
m_timeoutTimer->start(ReplyTimeout);
|
m_timeoutTimer->start(ReplyTimeout);
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ class QByteArray;
|
|||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
class SshPseudoTerminal;
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
class SshChannelManager;
|
class SshChannelManager;
|
||||||
class SshRemoteProcessPrivate;
|
class SshRemoteProcessPrivate;
|
||||||
@@ -84,6 +85,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void addToEnvironment(const QByteArray &var, const QByteArray &value);
|
void addToEnvironment(const QByteArray &var, const QByteArray &value);
|
||||||
|
|
||||||
|
void requestTerminal(const SshPseudoTerminal &terminal);
|
||||||
void start();
|
void start();
|
||||||
void closeChannel();
|
void closeChannel();
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
#ifndef SSHREMOTEPROCESS_P_H
|
#ifndef SSHREMOTEPROCESS_P_H
|
||||||
#define SSHREMOTEPROCESS_P_H
|
#define SSHREMOTEPROCESS_P_H
|
||||||
|
|
||||||
|
#include "sshpseudoterminal.h"
|
||||||
|
|
||||||
#include "sshchannel_p.h"
|
#include "sshchannel_p.h"
|
||||||
|
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
@@ -88,6 +90,8 @@ private:
|
|||||||
|
|
||||||
typedef QPair<QByteArray, QByteArray> EnvVar;
|
typedef QPair<QByteArray, QByteArray> EnvVar;
|
||||||
QList<EnvVar> m_env;
|
QList<EnvVar> m_env;
|
||||||
|
bool m_useTerminal;
|
||||||
|
SshPseudoTerminal m_terminal;
|
||||||
|
|
||||||
SshRemoteProcess *m_proc;
|
SshRemoteProcess *m_proc;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ HEADERS += $$PWD/environment.h \
|
|||||||
$$PWD/ssh/sftpchannel_p.h \
|
$$PWD/ssh/sftpchannel_p.h \
|
||||||
$$PWD/ssh/sshremoteprocessrunner.h \
|
$$PWD/ssh/sshremoteprocessrunner.h \
|
||||||
$$PWD/ssh/sshconnectionmanager.h \
|
$$PWD/ssh/sshconnectionmanager.h \
|
||||||
|
$$PWD/ssh/sshpseudoterminal.h \
|
||||||
$$PWD/statuslabel.h
|
$$PWD/statuslabel.h
|
||||||
|
|
||||||
FORMS += $$PWD/filewizardpage.ui \
|
FORMS += $$PWD/filewizardpage.ui \
|
||||||
|
|||||||
Reference in New Issue
Block a user