diff options
author | Christian Kandeler <christian.kandeler@nokia.com> | 2011-07-26 18:13:11 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@nokia.com> | 2011-07-26 18:17:11 +0200 |
commit | d59a64c7dfbd6d21218520bdee23c324acf00eba (patch) | |
tree | bd42c8c57b44ddc1c4877e33e18cb30ad7a59db0 | |
parent | a3e517415d3a84570fedc8fb2fb216e65e471d15 (diff) | |
download | qt-creator-d59a64c7dfbd6d21218520bdee23c324acf00eba.tar.gz |
SSH: Implement remote shell support.
Change-Id: Ifcddd930bbf027f4828f8ba01544aca5dea1eeed
Reviewed-on: http://codereview.qt.nokia.com/2220
Reviewed-by: Christian Kandeler <christian.kandeler@nokia.com>
-rw-r--r-- | src/libs/utils/ssh/sshchannelmanager.cpp | 7 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshchannelmanager_p.h | 1 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshconnection.cpp | 11 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshconnection.h | 1 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshconnection_p.h | 1 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshoutgoingpacket.cpp | 6 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshoutgoingpacket_p.h | 1 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.cpp | 60 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess.h | 3 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshremoteprocess_p.h | 4 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshsendfacility.cpp | 6 | ||||
-rw-r--r-- | src/libs/utils/ssh/sshsendfacility_p.h | 1 | ||||
-rw-r--r-- | tests/manual/ssh/shell/main.cpp | 57 | ||||
-rw-r--r-- | tests/manual/ssh/shell/shell.cpp | 121 | ||||
-rw-r--r-- | tests/manual/ssh/shell/shell.h | 70 | ||||
-rw-r--r-- | tests/manual/ssh/shell/shell.pro | 6 | ||||
-rw-r--r-- | tests/manual/ssh/ssh.pro | 2 |
17 files changed, 344 insertions, 14 deletions
diff --git a/src/libs/utils/ssh/sshchannelmanager.cpp b/src/libs/utils/ssh/sshchannelmanager.cpp index 3110d33d18..65c805e572 100644 --- a/src/libs/utils/ssh/sshchannelmanager.cpp +++ b/src/libs/utils/ssh/sshchannelmanager.cpp @@ -156,6 +156,13 @@ Utils::SshRemoteProcess::Ptr SshChannelManager::createRemoteProcess(const QByteA return proc; } +Utils::SshRemoteProcess::Ptr SshChannelManager::createRemoteShell() +{ + SshRemoteProcess::Ptr proc(new SshRemoteProcess(m_nextLocalChannelId++, m_sendFacility)); + insertChannel(proc->d, proc); + return proc; +} + Utils::SftpChannel::Ptr SshChannelManager::createSftpChannel() { SftpChannel::Ptr sftp(new SftpChannel(m_nextLocalChannelId++, m_sendFacility)); diff --git a/src/libs/utils/ssh/sshchannelmanager_p.h b/src/libs/utils/ssh/sshchannelmanager_p.h index e3ff542187..8cf35502c0 100644 --- a/src/libs/utils/ssh/sshchannelmanager_p.h +++ b/src/libs/utils/ssh/sshchannelmanager_p.h @@ -55,6 +55,7 @@ public: SshChannelManager(SshSendFacility &sendFacility, QObject *parent); QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); + QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); void closeAllChannels(); diff --git a/src/libs/utils/ssh/sshconnection.cpp b/src/libs/utils/ssh/sshconnection.cpp index 5ff083e6d2..7e458e28f7 100644 --- a/src/libs/utils/ssh/sshconnection.cpp +++ b/src/libs/utils/ssh/sshconnection.cpp @@ -178,6 +178,12 @@ QSharedPointer<SshRemoteProcess> SshConnection::createRemoteProcess(const QByteA return d->createRemoteProcess(command); } +QSharedPointer<SshRemoteProcess> SshConnection::createRemoteShell() +{ + QTC_ASSERT(state() == Connected, return QSharedPointer<SshRemoteProcess>()); + return d->createRemoteShell(); +} + QSharedPointer<SftpChannel> SshConnection::createSftpChannel() { QTC_ASSERT(state() == Connected, return QSharedPointer<SftpChannel>()); @@ -678,6 +684,11 @@ QSharedPointer<SshRemoteProcess> SshConnectionPrivate::createRemoteProcess(const return m_channelManager->createRemoteProcess(command); } +QSharedPointer<SshRemoteProcess> SshConnectionPrivate::createRemoteShell() +{ + return m_channelManager->createRemoteShell(); +} + QSharedPointer<SftpChannel> SshConnectionPrivate::createSftpChannel() { return m_channelManager->createSftpChannel(); diff --git a/src/libs/utils/ssh/sshconnection.h b/src/libs/utils/ssh/sshconnection.h index 2791ab1b78..83493db53c 100644 --- a/src/libs/utils/ssh/sshconnection.h +++ b/src/libs/utils/ssh/sshconnection.h @@ -89,6 +89,7 @@ public: ~SshConnection(); QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); + QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); signals: diff --git a/src/libs/utils/ssh/sshconnection_p.h b/src/libs/utils/ssh/sshconnection_p.h index a3b728b73e..6eef908e5f 100644 --- a/src/libs/utils/ssh/sshconnection_p.h +++ b/src/libs/utils/ssh/sshconnection_p.h @@ -90,6 +90,7 @@ public: void closeConnection(SshErrorCode sshError, SshError userError, const QByteArray &serverErrorString, const QString &userErrorString); QSharedPointer<SshRemoteProcess> createRemoteProcess(const QByteArray &command); + QSharedPointer<SshRemoteProcess> createRemoteShell(); QSharedPointer<SftpChannel> createSftpChannel(); SshStateInternal state() const { return m_state; } SshError error() const { return m_error; } diff --git a/src/libs/utils/ssh/sshoutgoingpacket.cpp b/src/libs/utils/ssh/sshoutgoingpacket.cpp index b7ab343433..e5f84a38a6 100644 --- a/src/libs/utils/ssh/sshoutgoingpacket.cpp +++ b/src/libs/utils/ssh/sshoutgoingpacket.cpp @@ -179,6 +179,12 @@ void SshOutgoingPacket::generateExecPacket(quint32 remoteChannel, .appendBool(true).appendString(command).finalize(); } +void SshOutgoingPacket::generateShellPacket(quint32 remoteChannel) +{ + init(SSH_MSG_CHANNEL_REQUEST).appendInt(remoteChannel).appendString("shell") + .appendBool(true).finalize(); +} + void SshOutgoingPacket::generateSftpPacket(quint32 remoteChannel) { init(SSH_MSG_CHANNEL_REQUEST).appendInt(remoteChannel) diff --git a/src/libs/utils/ssh/sshoutgoingpacket_p.h b/src/libs/utils/ssh/sshoutgoingpacket_p.h index da322fabbb..fcb0f5baa8 100644 --- a/src/libs/utils/ssh/sshoutgoingpacket_p.h +++ b/src/libs/utils/ssh/sshoutgoingpacket_p.h @@ -69,6 +69,7 @@ public: void generatePtyRequestPacket(quint32 remoteChannel, const SshPseudoTerminal &terminal); void generateExecPacket(quint32 remoteChannel, const QByteArray &command); + void generateShellPacket(quint32 remoteChannel); void generateSftpPacket(quint32 remoteChannel); void generateWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd); void generateChannelDataPacket(quint32 remoteChannel, diff --git a/src/libs/utils/ssh/sshremoteprocess.cpp b/src/libs/utils/ssh/sshremoteprocess.cpp index 49cc556758..850c77c464 100644 --- a/src/libs/utils/ssh/sshremoteprocess.cpp +++ b/src/libs/utils/ssh/sshremoteprocess.cpp @@ -82,14 +82,13 @@ SshRemoteProcess::SshRemoteProcess(const QByteArray &command, quint32 channelId, Internal::SshSendFacility &sendFacility) : d(new Internal::SshRemoteProcessPrivate(command, channelId, sendFacility, this)) { - connect(d, SIGNAL(started()), this, SIGNAL(started()), - Qt::QueuedConnection); - connect(d, SIGNAL(outputAvailable(QByteArray)), this, - SIGNAL(outputAvailable(QByteArray)), Qt::QueuedConnection); - connect(d, SIGNAL(errorOutputAvailable(QByteArray)), this, - SIGNAL(errorOutputAvailable(QByteArray)), Qt::QueuedConnection); - connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), - Qt::QueuedConnection); + init(); +} + +SshRemoteProcess::SshRemoteProcess(quint32 channelId, Internal::SshSendFacility &sendFacility) + : d(new Internal::SshRemoteProcessPrivate(channelId, sendFacility, this)) +{ + init(); } SshRemoteProcess::~SshRemoteProcess() @@ -100,6 +99,18 @@ SshRemoteProcess::~SshRemoteProcess() delete d; } +void SshRemoteProcess::init() +{ + connect(d, SIGNAL(started()), this, SIGNAL(started()), + Qt::QueuedConnection); + connect(d, SIGNAL(outputAvailable(QByteArray)), this, + SIGNAL(outputAvailable(QByteArray)), Qt::QueuedConnection); + connect(d, SIGNAL(errorOutputAvailable(QByteArray)), this, + SIGNAL(errorOutputAvailable(QByteArray)), Qt::QueuedConnection); + connect(d, SIGNAL(closed(int)), this, SIGNAL(closed(int)), + Qt::QueuedConnection); +} + void SshRemoteProcess::addToEnvironment(const QByteArray &var, const QByteArray &value) { if (d->channelState() == Internal::SshRemoteProcessPrivate::Inactive) @@ -160,11 +171,31 @@ QByteArray SshRemoteProcess::exitSignal() const { return d->m_signal; } namespace Internal { SshRemoteProcessPrivate::SshRemoteProcessPrivate(const QByteArray &command, - quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc) - : AbstractSshChannel(channelId, sendFacility), m_procState(NotYetStarted), - m_wasRunning(false), m_exitCode(0), m_command(command), - m_useTerminal(false), m_proc(proc) + quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc) + : AbstractSshChannel(channelId, sendFacility), + m_command(command), + m_isShell(false), + m_useTerminal(false), + m_proc(proc) +{ + init(); +} + +SshRemoteProcessPrivate::SshRemoteProcessPrivate(quint32 channelId, SshSendFacility &sendFacility, + SshRemoteProcess *proc) + : AbstractSshChannel(channelId, sendFacility), + m_isShell(true), + m_useTerminal(true), + m_proc(proc) +{ + init(); +} + +void SshRemoteProcessPrivate::init() { + m_procState = NotYetStarted; + m_wasRunning = false; + m_exitCode = 0; } void SshRemoteProcessPrivate::setProcState(ProcessState newState) @@ -201,7 +232,10 @@ void SshRemoteProcessPrivate::handleOpenSuccessInternal() if (m_useTerminal) m_sendFacility.sendPtyRequestPacket(remoteChannel(), m_terminal); - m_sendFacility.sendExecPacket(remoteChannel(), m_command); + if (m_isShell) + m_sendFacility.sendShellPacket(remoteChannel()); + else + m_sendFacility.sendExecPacket(remoteChannel(), m_command); setProcState(ExecRequested); m_timeoutTimer->start(ReplyTimeout); } diff --git a/src/libs/utils/ssh/sshremoteprocess.h b/src/libs/utils/ssh/sshremoteprocess.h index 12c3ea1921..e31447ee21 100644 --- a/src/libs/utils/ssh/sshremoteprocess.h +++ b/src/libs/utils/ssh/sshremoteprocess.h @@ -112,6 +112,9 @@ signals: private: SshRemoteProcess(const QByteArray &command, quint32 channelId, Internal::SshSendFacility &sendFacility); + SshRemoteProcess(quint32 channelId, Internal::SshSendFacility &sendFacility); + + void init(); Internal::SshRemoteProcessPrivate *d; }; diff --git a/src/libs/utils/ssh/sshremoteprocess_p.h b/src/libs/utils/ssh/sshremoteprocess_p.h index 7617c2b920..b36e722cb9 100644 --- a/src/libs/utils/ssh/sshremoteprocess_p.h +++ b/src/libs/utils/ssh/sshremoteprocess_p.h @@ -69,6 +69,8 @@ signals: private: SshRemoteProcessPrivate(const QByteArray &command, quint32 channelId, SshSendFacility &sendFacility, SshRemoteProcess *proc); + SshRemoteProcessPrivate(quint32 channelId, SshSendFacility &sendFacility, + SshRemoteProcess *proc); virtual void handleOpenSuccessInternal(); virtual void handleOpenFailureInternal(); @@ -78,6 +80,7 @@ private: virtual void handleExitStatus(const SshChannelExitStatus &exitStatus); virtual void handleExitSignal(const SshChannelExitSignal &signal); + void init(); void setProcState(ProcessState newState); ProcessState m_procState; @@ -86,6 +89,7 @@ private: int m_exitCode; const QByteArray m_command; + const bool m_isShell; typedef QPair<QByteArray, QByteArray> EnvVar; QList<EnvVar> m_env; diff --git a/src/libs/utils/ssh/sshsendfacility.cpp b/src/libs/utils/ssh/sshsendfacility.cpp index edf03bb72b..1608f11c3e 100644 --- a/src/libs/utils/ssh/sshsendfacility.cpp +++ b/src/libs/utils/ssh/sshsendfacility.cpp @@ -173,6 +173,12 @@ void SshSendFacility::sendExecPacket(quint32 remoteChannel, sendPacket(); } +void SshSendFacility::sendShellPacket(quint32 remoteChannel) +{ + m_outgoingPacket.generateShellPacket(remoteChannel); + sendPacket(); +} + void SshSendFacility::sendSftpPacket(quint32 remoteChannel) { m_outgoingPacket.generateSftpPacket(remoteChannel); diff --git a/src/libs/utils/ssh/sshsendfacility_p.h b/src/libs/utils/ssh/sshsendfacility_p.h index 5a1928f293..7d8d36a79a 100644 --- a/src/libs/utils/ssh/sshsendfacility_p.h +++ b/src/libs/utils/ssh/sshsendfacility_p.h @@ -76,6 +76,7 @@ public: void sendEnvPacket(quint32 remoteChannel, const QByteArray &var, const QByteArray &value); void sendExecPacket(quint32 remoteChannel, const QByteArray &command); + void sendShellPacket(quint32 remoteChannel); void sendSftpPacket(quint32 remoteChannel); void sendWindowAdjustPacket(quint32 remoteChannel, quint32 bytesToAdd); void sendChannelDataPacket(quint32 remoteChannel, const QByteArray &data); diff --git a/tests/manual/ssh/shell/main.cpp b/tests/manual/ssh/shell/main.cpp new file mode 100644 index 0000000000..5c1bdfcb54 --- /dev/null +++ b/tests/manual/ssh/shell/main.cpp @@ -0,0 +1,57 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "../remoteprocess/argumentscollector.h" +#include "shell.h" + +#include <utils/ssh/sshconnection.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QObject> +#include <QtCore/QStringList> + +#include <cstdlib> +#include <iostream> + +using namespace Utils; + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + bool parseSuccess; + const Utils::SshConnectionParameters ¶meters + = ArgumentsCollector(app.arguments()).collect(parseSuccess); + if (!parseSuccess) + return EXIT_FAILURE; + Shell shell(parameters); + shell.run(); + return app.exec(); +} diff --git a/tests/manual/ssh/shell/shell.cpp b/tests/manual/ssh/shell/shell.cpp new file mode 100644 index 0000000000..344d7d53fa --- /dev/null +++ b/tests/manual/ssh/shell/shell.cpp @@ -0,0 +1,121 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include "shell.h" + +#include <utils/ssh/sshconnection.h> +#include <utils/ssh/sshremoteprocess.h> + +#include <QtCore/QCoreApplication> +#include <QtCore/QFile> +#include <QtCore/QSocketNotifier> + +#include <cstdlib> +#include <iostream> + +using namespace Utils; + +Shell::Shell(const Utils::SshConnectionParameters ¶meters, QObject *parent) + : QObject(parent), + m_connection(SshConnection::create(parameters)), + m_stdin(new QFile(this)) +{ + connect(m_connection.data(), SIGNAL(connected()), SLOT(handleConnected())); + connect(m_connection.data(), SIGNAL(dataAvailable(QString)), SLOT(handleShellMessage(QString))); + connect(m_connection.data(), SIGNAL(error(Utils::SshError)), SLOT(handleConnectionError())); +} + +Shell::~Shell() +{ +} + +void Shell::run() +{ + if (!m_stdin->open(stdin, QIODevice::ReadOnly | QIODevice::Unbuffered)) { + std::cerr << "Error: Cannot read from standard input." << std::endl; + qApp->exit(EXIT_FAILURE); + return; + } + + m_connection->connectToHost(); +} + +void Shell::handleConnectionError() +{ + std::cerr << "SSH connection error: " << qPrintable(m_connection->errorString()) << std::endl; + qApp->exit(EXIT_FAILURE); +} + +void Shell::handleShellMessage(const QString &message) +{ + std::cout << qPrintable(message); +} + +void Shell::handleConnected() +{ + m_shell = m_connection->createRemoteShell(); + connect(m_shell.data(), SIGNAL(started()), SLOT(handleShellStarted())); + connect(m_shell.data(), SIGNAL(outputAvailable(QByteArray)), + SLOT(handleRemoteStdout(QByteArray))); + connect(m_shell.data(), SIGNAL(errorOutputAvailable(QByteArray)), + SLOT(handleRemoteStderr(QByteArray))); + connect(m_shell.data(), SIGNAL(closed(int)), SLOT(handleChannelClosed(int))); + m_shell->start(); +} + +void Shell::handleShellStarted() +{ + QSocketNotifier * const notifier = new QSocketNotifier(0, QSocketNotifier::Read, this); + connect(notifier, SIGNAL(activated(int)), SLOT(handleStdin())); +} + +void Shell::handleRemoteStdout(const QByteArray &output) +{ + std::cout << output.data() << std::flush; +} + +void Shell::handleRemoteStderr(const QByteArray &output) +{ + std::cerr << output.data() << std::flush; +} + +void Shell::handleChannelClosed(int exitStatus) +{ + std::cerr << "Shell closed. Exit status was " << exitStatus << ", exit code was " + << m_shell->exitCode() << "." << std::endl; + qApp->exit(exitStatus == SshRemoteProcess::ExitedNormally && m_shell->exitCode() == 0 + ? EXIT_SUCCESS : EXIT_FAILURE); +} + +void Shell::handleStdin() +{ + m_shell->sendInput(m_stdin->readLine()); +} diff --git a/tests/manual/ssh/shell/shell.h b/tests/manual/ssh/shell/shell.h new file mode 100644 index 0000000000..633b3197cb --- /dev/null +++ b/tests/manual/ssh/shell/shell.h @@ -0,0 +1,70 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Lesser General Public License Usage +** +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this file. +** Please review the following information to ensure the GNU Lesser General +** Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** Other Usage +** +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** If you have questions regarding the use of this file, please contact +** Nokia at info@qt.nokia.com. +** +**************************************************************************/ +#include <QtCore/QObject> +#include <QtCore/QSharedPointer> + +namespace Utils { +class SshConnection; +class SshConnectionParameters; +class SshRemoteProcess; +} + +QT_BEGIN_NAMESPACE +class QByteArray; +class QFile; +class QString; +QT_END_NAMESPACE + +class Shell : public QObject +{ + Q_OBJECT +public: + Shell(const Utils::SshConnectionParameters ¶meters, QObject *parent = 0); + ~Shell(); + + void run(); + +private slots: + void handleConnected(); + void handleConnectionError(); + void handleRemoteStdout(const QByteArray &output); + void handleRemoteStderr(const QByteArray &output); + void handleShellMessage(const QString &message); + void handleChannelClosed(int exitStatus); + void handleShellStarted(); + void handleStdin(); + +private: + QSharedPointer<Utils::SshConnection> m_connection; + QSharedPointer<Utils::SshRemoteProcess> m_shell; + QFile * const m_stdin; +}; diff --git a/tests/manual/ssh/shell/shell.pro b/tests/manual/ssh/shell/shell.pro new file mode 100644 index 0000000000..ed3b0d987e --- /dev/null +++ b/tests/manual/ssh/shell/shell.pro @@ -0,0 +1,6 @@ +include(../ssh.pri) +QT += network + +TARGET=shell +SOURCES=main.cpp shell.cpp ../remoteprocess/argumentscollector.cpp +HEADERS=shell.h ../remoteprocess/argumentscollector.h diff --git a/tests/manual/ssh/ssh.pro b/tests/manual/ssh/ssh.pro index a722b3d543..04f2420ad9 100644 --- a/tests/manual/ssh/ssh.pro +++ b/tests/manual/ssh/ssh.pro @@ -5,4 +5,4 @@ #------------------------------------------------- TEMPLATE = subdirs -SUBDIRS = errorhandling sftp remoteprocess +SUBDIRS = errorhandling sftp remoteprocess shell |