forked from qt-creator/qt-creator
Ssh: Re-base SshProcess on top of QtcProcess
Change-Id: I266820e0e2ea12d6e4a5a83a679a7279fab9cd83 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -58,7 +58,7 @@ struct Command
|
||||
|
||||
struct SftpSession::SftpSessionPrivate
|
||||
{
|
||||
SshProcess sftpProc;
|
||||
SshProcess sftpProc = {ProcessMode::Writer};
|
||||
QStringList connectionArgs;
|
||||
QByteArray output;
|
||||
QQueue<Command> pendingCommands;
|
||||
@@ -112,17 +112,17 @@ static QByteArray prompt() { return "sftp> "; }
|
||||
SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionPrivate)
|
||||
{
|
||||
d->connectionArgs = connectionArgs;
|
||||
connect(&d->sftpProc, &QProcess::started, [this] {
|
||||
connect(&d->sftpProc, &QtcProcess::started, [this] {
|
||||
qCDebug(sshLog) << "sftp process started";
|
||||
d->sftpProc.write("\n"); // Force initial prompt.
|
||||
});
|
||||
connect(&d->sftpProc, &QProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
connect(&d->sftpProc, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
if (error == QProcess::FailedToStart) {
|
||||
d->state = State::Inactive;
|
||||
emit done(tr("sftp failed to start: %1").arg(d->sftpProc.errorString()));
|
||||
}
|
||||
});
|
||||
connect(&d->sftpProc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this] {
|
||||
connect(&d->sftpProc, &QtcProcess::finished, [this] {
|
||||
qCDebug(sshLog) << "sftp process finished";
|
||||
|
||||
d->state = State::Inactive;
|
||||
@@ -136,7 +136,7 @@ SftpSession::SftpSession(const QStringList &connectionArgs) : d(new SftpSessionP
|
||||
}
|
||||
emit done(QString());
|
||||
});
|
||||
connect(&d->sftpProc, &QProcess::readyReadStandardOutput, this, &SftpSession::handleStdout);
|
||||
connect(&d->sftpProc, &QtcProcess::readyReadStandardOutput, this, &SftpSession::handleStdout);
|
||||
}
|
||||
|
||||
void SftpSession::doStart()
|
||||
@@ -153,7 +153,8 @@ void SftpSession::doStart()
|
||||
d->activeCommand = Command();
|
||||
const QStringList args = QStringList{"-q"} << d->connectionArgs;
|
||||
qCDebug(sshLog) << "starting sftp session:" << sftpBinary.toUserOutput() << args;
|
||||
d->sftpProc.start(sftpBinary.toString(), args);
|
||||
d->sftpProc.setCommand(CommandLine(sftpBinary, args));
|
||||
d->sftpProc.start();
|
||||
}
|
||||
|
||||
void SftpSession::handleStdout()
|
||||
|
||||
@@ -113,11 +113,11 @@ SftpTransfer::SftpTransfer(const FilesToTransfer &files, Internal::FileTransferT
|
||||
d->transferType = type;
|
||||
d->errorHandlingMode = errorHandlingMode;
|
||||
d->connectionArgs = connectionArgs;
|
||||
connect(&d->sftpProc, &QProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
connect(&d->sftpProc, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
if (error == QProcess::FailedToStart)
|
||||
emitError(tr("sftp failed to start: %1").arg(d->sftpProc.errorString()));
|
||||
});
|
||||
connect(&d->sftpProc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this] {
|
||||
connect(&d->sftpProc, &QtcProcess::finished, [this] {
|
||||
if (d->sftpProc.exitStatus() != QProcess::NormalExit) {
|
||||
emitError(tr("sftp crashed."));
|
||||
return;
|
||||
@@ -128,7 +128,7 @@ SftpTransfer::SftpTransfer(const FilesToTransfer &files, Internal::FileTransferT
|
||||
}
|
||||
emit done(QString());
|
||||
});
|
||||
connect(&d->sftpProc, &QProcess::readyReadStandardOutput, [this] {
|
||||
connect(&d->sftpProc, &QtcProcess::readyReadStandardOutput, [this] {
|
||||
emit progress(QString::fromLocal8Bit(d->sftpProc.readAllStandardOutput()));
|
||||
});
|
||||
}
|
||||
@@ -179,7 +179,8 @@ void SftpTransfer::doStart()
|
||||
+ ProcessArgs::quoteArgUnix(f.targetFile).toLocal8Bit() + '\n');
|
||||
}
|
||||
d->sftpProc.setStandardInputFile(batchFile.fileName());
|
||||
d->sftpProc.start(sftpBinary.toString(), d->connectionArgs);
|
||||
d->sftpProc.setCommand(CommandLine(sftpBinary, d->connectionArgs));
|
||||
d->sftpProc.start();
|
||||
emit started();
|
||||
}
|
||||
|
||||
|
||||
@@ -167,7 +167,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject
|
||||
qRegisterMetaType<QSsh::SftpFileInfo>("QSsh::SftpFileInfo");
|
||||
qRegisterMetaType<QList <QSsh::SftpFileInfo> >("QList<QSsh::SftpFileInfo>");
|
||||
d->connParams = serverInfo;
|
||||
connect(&d->masterProcess, &QProcess::started, [this] {
|
||||
connect(&d->masterProcess, &QtcProcess::started, [this] {
|
||||
QFileInfo socketInfo(d->socketFilePath());
|
||||
if (socketInfo.exists()) {
|
||||
emitConnected();
|
||||
@@ -194,7 +194,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject
|
||||
socketWatcherTimer->start();
|
||||
}
|
||||
});
|
||||
connect(&d->masterProcess, &QProcess::errorOccurred, [this] (QProcess::ProcessError error) {
|
||||
connect(&d->masterProcess, &QtcProcess::errorOccurred, [this] (QProcess::ProcessError error) {
|
||||
switch (error) {
|
||||
case QProcess::FailedToStart:
|
||||
emitError(tr("Cannot establish SSH connection: Control process failed to start: %1")
|
||||
@@ -208,7 +208,7 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject
|
||||
break; // Cannot happen.
|
||||
}
|
||||
});
|
||||
connect(&d->masterProcess, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [this] {
|
||||
connect(&d->masterProcess, &QtcProcess::finished, [this] {
|
||||
if (d->state == Disconnecting) {
|
||||
emitDisconnected();
|
||||
return;
|
||||
@@ -220,9 +220,9 @@ SshConnection::SshConnection(const SshConnectionParameters &serverInfo, QObject
|
||||
emitError(errorMsg);
|
||||
});
|
||||
if (!d->connParams.x11DisplayName.isEmpty()) {
|
||||
QProcessEnvironment env = d->masterProcess.processEnvironment();
|
||||
env.insert("DISPLAY", d->connParams.x11DisplayName);
|
||||
d->masterProcess.setProcessEnvironment(env);
|
||||
Environment env = d->masterProcess.environment();
|
||||
env.set("DISPLAY", d->connParams.x11DisplayName);
|
||||
d->masterProcess.setEnvironment(env);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,16 +316,17 @@ SshConnection::~SshConnection()
|
||||
delete d;
|
||||
}
|
||||
|
||||
SshRemoteProcessPtr SshConnection::createRemoteProcess(const QString &command)
|
||||
SshRemoteProcessPtr SshConnection::createRemoteProcess(const QString &command, ProcessMode processMode)
|
||||
{
|
||||
QTC_ASSERT(state() == Connected, return SshRemoteProcessPtr());
|
||||
return SshRemoteProcessPtr(new SshRemoteProcess(command,
|
||||
d->connectionArgs(SshSettings::sshFilePath())));
|
||||
d->connectionArgs(SshSettings::sshFilePath()),
|
||||
processMode));
|
||||
}
|
||||
|
||||
SshRemoteProcessPtr SshConnection::createRemoteShell()
|
||||
SshRemoteProcessPtr SshConnection::createRemoteShell(ProcessMode processMode)
|
||||
{
|
||||
return createRemoteProcess({});
|
||||
return createRemoteProcess({}, processMode);
|
||||
}
|
||||
|
||||
SftpTransferPtr SshConnection::createUpload(const FilesToTransfer &files,
|
||||
@@ -372,7 +373,8 @@ void SshConnection::doConnectToHost()
|
||||
if (!d->connParams.x11DisplayName.isEmpty())
|
||||
args.prepend("-X");
|
||||
qCDebug(sshLog) << "establishing connection:" << sshBinary.toUserOutput() << args;
|
||||
d->masterProcess.start(sshBinary.toString(), args);
|
||||
d->masterProcess.setCommand(CommandLine(sshBinary, args));
|
||||
d->masterProcess.start();
|
||||
}
|
||||
|
||||
void SshConnection::emitError(const QString &reason)
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "sftpdefs.h"
|
||||
#include "ssh_global.h"
|
||||
|
||||
#include <utils/processutils.h>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QFlags>
|
||||
#include <QMetaType>
|
||||
@@ -113,8 +115,10 @@ public:
|
||||
bool sharingEnabled() const;
|
||||
~SshConnection();
|
||||
|
||||
SshRemoteProcessPtr createRemoteProcess(const QString &command);
|
||||
SshRemoteProcessPtr createRemoteShell();
|
||||
SshRemoteProcessPtr createRemoteProcess(const QString &command, Utils::ProcessMode processMode
|
||||
= Utils::ProcessMode::Reader);
|
||||
SshRemoteProcessPtr createRemoteShell(Utils::ProcessMode processMode
|
||||
= Utils::ProcessMode::Reader);
|
||||
SftpTransferPtr createUpload(const FilesToTransfer &files,
|
||||
FileTransferErrorHandling errorHandlingMode);
|
||||
SftpTransferPtr createDownload(const FilesToTransfer &files,
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
|
||||
namespace QSsh {
|
||||
|
||||
SshProcess::SshProcess()
|
||||
SshProcess::SshProcess(Utils::ProcessMode processMode)
|
||||
: Utils::QtcProcess(processMode)
|
||||
{
|
||||
Utils::Environment env = Utils::Environment::systemEnvironment();
|
||||
if (SshSettings::askpassFilePath().exists()) {
|
||||
@@ -46,37 +47,10 @@ SshProcess::SshProcess()
|
||||
if (!env.hasKey("DISPLAY"))
|
||||
env.set("DISPLAY", ":0");
|
||||
}
|
||||
setProcessEnvironment(env.toProcessEnvironment());
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX)
|
||||
setChildProcessModifier([this] { setupChildProcess_impl(); });
|
||||
#endif
|
||||
}
|
||||
setEnvironment(env);
|
||||
|
||||
SshProcess::~SshProcess()
|
||||
{
|
||||
if (state() == QProcess::NotRunning)
|
||||
return;
|
||||
disconnect();
|
||||
terminate();
|
||||
waitForFinished(1000);
|
||||
if (state() == QProcess::NotRunning)
|
||||
return;
|
||||
kill();
|
||||
waitForFinished(1000);
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
void SshProcess::setupChildProcess()
|
||||
{
|
||||
setupChildProcess_impl();
|
||||
}
|
||||
#endif
|
||||
|
||||
void SshProcess::setupChildProcess_impl()
|
||||
{
|
||||
#ifdef Q_OS_UNIX
|
||||
setsid(); // Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly.
|
||||
#endif
|
||||
// Otherwise, ssh will ignore SSH_ASKPASS and read from /dev/tty directly.
|
||||
setDisableUnixTerminal();
|
||||
}
|
||||
|
||||
} // namespace QSsh
|
||||
|
||||
@@ -27,22 +27,14 @@
|
||||
|
||||
#include "ssh_global.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
namespace QSsh {
|
||||
|
||||
class QSSH_EXPORT SshProcess : public QProcess
|
||||
class QSSH_EXPORT SshProcess : public Utils::QtcProcess
|
||||
{
|
||||
public:
|
||||
SshProcess();
|
||||
~SshProcess() override;
|
||||
|
||||
private:
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
void setupChildProcess() override;
|
||||
#endif
|
||||
|
||||
void setupChildProcess_impl();
|
||||
SshProcess(Utils::ProcessMode processMode = Utils::ProcessMode::Reader);
|
||||
};
|
||||
|
||||
} // namespace QSsh
|
||||
|
||||
@@ -60,13 +60,15 @@ struct SshRemoteProcess::SshRemoteProcessPrivate
|
||||
bool useTerminal = false;
|
||||
};
|
||||
|
||||
SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &connectionArgs)
|
||||
: d(new SshRemoteProcessPrivate)
|
||||
SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &connectionArgs,
|
||||
Utils::ProcessMode processMode)
|
||||
: SshProcess(processMode)
|
||||
, d(new SshRemoteProcessPrivate)
|
||||
{
|
||||
d->remoteCommand = command;
|
||||
d->connectionArgs = connectionArgs;
|
||||
|
||||
connect(this, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, [this] {
|
||||
connect(this, &QtcProcess::finished, this, [this] {
|
||||
QString error;
|
||||
if (exitStatus() == QProcess::CrashExit)
|
||||
error = tr("The ssh process crashed: %1").arg(errorString());
|
||||
@@ -74,7 +76,7 @@ SshRemoteProcess::SshRemoteProcess(const QString &command, const QStringList &co
|
||||
error = tr("Remote process crashed.");
|
||||
emit done(error);
|
||||
});
|
||||
connect(this, &QProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
connect(this, &QtcProcess::errorOccurred, [this](QProcess::ProcessError error) {
|
||||
if (error == QProcess::FailedToStart)
|
||||
emit done(errorString());
|
||||
});
|
||||
@@ -85,12 +87,13 @@ void SshRemoteProcess::doStart()
|
||||
QTC_ASSERT(!isRunning(), return);
|
||||
const Utils::CommandLine cmd = fullLocalCommandLine();
|
||||
if (!d->displayName.isEmpty()) {
|
||||
QProcessEnvironment env = processEnvironment();
|
||||
env.insert("DISPLAY", d->displayName);
|
||||
setProcessEnvironment(env);
|
||||
Utils::Environment env = environment();
|
||||
env.set("DISPLAY", d->displayName);
|
||||
setEnvironment(env);
|
||||
}
|
||||
qCDebug(sshLog) << "starting remote process:" << cmd.toUserOutput();
|
||||
QProcess::start(cmd.executable().toString(), cmd.splitArguments());
|
||||
setCommand(cmd);
|
||||
QtcProcess::start();
|
||||
}
|
||||
|
||||
SshRemoteProcess::~SshRemoteProcess()
|
||||
@@ -110,7 +113,7 @@ void SshRemoteProcess::requestX11Forwarding(const QString &displayName)
|
||||
|
||||
void SshRemoteProcess::start()
|
||||
{
|
||||
QTimer::singleShot(0, this, &SshRemoteProcess::doStart);
|
||||
doStart();
|
||||
}
|
||||
|
||||
bool SshRemoteProcess::isRunning() const
|
||||
|
||||
@@ -54,7 +54,8 @@ signals:
|
||||
void done(const QString &error);
|
||||
|
||||
private:
|
||||
SshRemoteProcess(const QString &command, const QStringList &connectionArgs);
|
||||
SshRemoteProcess(const QString &command, const QStringList &connectionArgs,
|
||||
Utils::ProcessMode processMode = Utils::ProcessMode::Reader);
|
||||
void doStart();
|
||||
|
||||
struct SshRemoteProcessPrivate;
|
||||
|
||||
@@ -186,7 +186,7 @@ void SshRemoteProcessRunner::setState(int newState)
|
||||
if (d->m_process) {
|
||||
disconnect(d->m_process.get(), nullptr, this, nullptr);
|
||||
d->m_process->terminate();
|
||||
d->m_process.release()->deleteLater();
|
||||
d->m_process.reset();
|
||||
}
|
||||
if (d->m_connection) {
|
||||
disconnect(d->m_connection, nullptr, this, nullptr);
|
||||
@@ -206,7 +206,7 @@ bool SshRemoteProcessRunner::isProcessRunning() const
|
||||
return d->m_process && d->m_process->isRunning();
|
||||
}
|
||||
|
||||
SshRemoteProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const
|
||||
QProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const
|
||||
{
|
||||
QTC_CHECK(!isProcessRunning());
|
||||
return d->m_exitStatus;
|
||||
@@ -214,7 +214,7 @@ SshRemoteProcess::ExitStatus SshRemoteProcessRunner::processExitStatus() const
|
||||
|
||||
int SshRemoteProcessRunner::processExitCode() const
|
||||
{
|
||||
QTC_CHECK(processExitStatus() == SshRemoteProcess::NormalExit);
|
||||
QTC_CHECK(processExitStatus() == QProcess::NormalExit);
|
||||
return d->m_exitCode;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
bool isProcessRunning() const;
|
||||
void writeDataToProcess(const QByteArray &data);
|
||||
void cancel();
|
||||
SshRemoteProcess::ExitStatus processExitStatus() const;
|
||||
QProcess::ExitStatus processExitStatus() const;
|
||||
int processExitCode() const;
|
||||
QString processErrorString() const;
|
||||
QByteArray readAllStandardOutput();
|
||||
|
||||
Reference in New Issue
Block a user