forked from qt-creator/qt-creator
Make ProcessInterface public
It's going to be subclassed in LinuxDevice. Change-Id: I6308d7cf75a7e16cd02de585612000a1b983fadc Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -32,7 +32,6 @@
|
|||||||
#include "launcherpackets.h"
|
#include "launcherpackets.h"
|
||||||
#include "launchersocket.h"
|
#include "launchersocket.h"
|
||||||
#include "processreaper.h"
|
#include "processreaper.h"
|
||||||
#include "qtcassert.h"
|
|
||||||
#include "stringutils.h"
|
#include "stringutils.h"
|
||||||
#include "terminalprocess_p.h"
|
#include "terminalprocess_p.h"
|
||||||
|
|
||||||
@@ -212,75 +211,6 @@ public:
|
|||||||
bool keepRawData = true;
|
bool keepRawData = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ProcessSetupData
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QtcProcess::ProcessImpl m_processImpl = QtcProcess::DefaultImpl;
|
|
||||||
ProcessMode m_processMode = ProcessMode::Reader;
|
|
||||||
QtcProcess::TerminalMode m_terminalMode = QtcProcess::TerminalOff;
|
|
||||||
|
|
||||||
QString m_nativeArguments;
|
|
||||||
QString m_standardInputFile;
|
|
||||||
QString m_initialErrorString;
|
|
||||||
bool m_belowNormalPriority = false;
|
|
||||||
bool m_lowPriority = false;
|
|
||||||
bool m_unixTerminalDisabled = false;
|
|
||||||
bool m_abortOnMetaChars = true;
|
|
||||||
QProcess::ProcessChannelMode m_procesChannelMode = QProcess::SeparateChannels;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ProcessInterface : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
ProcessInterface(QObject *parent, ProcessMode processMode)
|
|
||||||
: QObject(parent)
|
|
||||||
, m_processMode(processMode) {}
|
|
||||||
|
|
||||||
virtual QByteArray readAllStandardOutput() = 0;
|
|
||||||
virtual QByteArray readAllStandardError() = 0;
|
|
||||||
|
|
||||||
virtual void setProcessEnvironment(const QProcessEnvironment &environment) = 0;
|
|
||||||
virtual void setWorkingDirectory(const QString &dir) = 0;
|
|
||||||
virtual void start(const QString &program, const QStringList &arguments,
|
|
||||||
const QByteArray &writeData) = 0;
|
|
||||||
virtual void customStart(const CommandLine &, const FilePath &workingDirectory,
|
|
||||||
const Environment &) { Q_UNUSED(workingDirectory); QTC_CHECK(false); }
|
|
||||||
virtual bool isCustomStart() const { return false; }
|
|
||||||
virtual void terminate() = 0;
|
|
||||||
virtual void kill() = 0;
|
|
||||||
virtual void close() = 0;
|
|
||||||
virtual qint64 write(const QByteArray &data) = 0;
|
|
||||||
|
|
||||||
virtual QString program() const = 0;
|
|
||||||
virtual QProcess::ProcessError error() const = 0;
|
|
||||||
virtual QProcess::ProcessState state() const = 0;
|
|
||||||
virtual qint64 processId() const = 0;
|
|
||||||
virtual int exitCode() const = 0;
|
|
||||||
virtual QProcess::ExitStatus exitStatus() const = 0;
|
|
||||||
virtual QString errorString() const = 0;
|
|
||||||
virtual void setErrorString(const QString &str) = 0;
|
|
||||||
|
|
||||||
virtual bool waitForStarted(int msecs) = 0;
|
|
||||||
virtual bool waitForReadyRead(int msecs) = 0;
|
|
||||||
virtual bool waitForFinished(int msecs) = 0;
|
|
||||||
|
|
||||||
virtual void kickoffProcess() { QTC_CHECK(false); }
|
|
||||||
virtual void interruptProcess() { QTC_CHECK(false); }
|
|
||||||
virtual qint64 applicationMainThreadID() const { QTC_CHECK(false); return -1; }
|
|
||||||
|
|
||||||
const ProcessMode m_processMode;
|
|
||||||
ProcessSetupData *m_setup = nullptr;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void started();
|
|
||||||
void finished(int exitCode, QProcess::ExitStatus status);
|
|
||||||
void errorOccurred(QProcess::ProcessError error);
|
|
||||||
void readyReadStandardOutput();
|
|
||||||
void readyReadStandardError();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TerminalImpl : public ProcessInterface
|
class TerminalImpl : public ProcessInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -550,40 +480,42 @@ public:
|
|||||||
, q(parent)
|
, q(parent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void setupNewProcessInstance()
|
ProcessInterface *createProcessInterface()
|
||||||
{
|
{
|
||||||
const QtcProcess::ProcessImpl impl =
|
const QtcProcess::ProcessImpl impl = m_setup.m_processImpl == QtcProcess::DefaultImpl
|
||||||
m_setup.m_processImpl == QtcProcess::DefaultImpl
|
? defaultProcessImpl() : m_setup.m_processImpl;
|
||||||
? defaultProcessImpl()
|
|
||||||
: m_setup.m_processImpl;
|
|
||||||
|
|
||||||
if (m_setup.m_terminalMode != QtcProcess::TerminalOff)
|
if (m_setup.m_terminalMode != QtcProcess::TerminalOff)
|
||||||
m_process = new TerminalImpl(parent(), impl, m_setup.m_terminalMode);
|
return new TerminalImpl(parent(), impl, m_setup.m_terminalMode);
|
||||||
else if (impl == QtcProcess::QProcessImpl)
|
else if (impl == QtcProcess::QProcessImpl)
|
||||||
m_process = new QProcessImpl(parent(), m_setup.m_processMode);
|
return new QProcessImpl(parent(), m_setup.m_processMode);
|
||||||
else
|
return new ProcessLauncherImpl(parent(), m_setup.m_processMode);
|
||||||
m_process = new ProcessLauncherImpl(parent(), m_setup.m_processMode);
|
|
||||||
|
|
||||||
m_process->m_setup = &m_setup;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensureProcessInstanceExists()
|
void setProcessInterface(ProcessInterface *process)
|
||||||
|
{
|
||||||
|
m_process.reset(process);
|
||||||
|
m_process->m_setup = &m_setup;
|
||||||
|
m_process->setParent(this);
|
||||||
|
|
||||||
|
connect(m_process.get(), &ProcessInterface::started,
|
||||||
|
q, &QtcProcess::started);
|
||||||
|
connect(m_process.get(), &ProcessInterface::finished,
|
||||||
|
this, &QtcProcessPrivate::slotFinished);
|
||||||
|
connect(m_process.get(), &ProcessInterface::errorOccurred,
|
||||||
|
this, [this](QProcess::ProcessError error) { handleError(error, OtherFailure); });
|
||||||
|
connect(m_process.get(), &ProcessInterface::readyReadStandardOutput,
|
||||||
|
this, &QtcProcessPrivate::handleReadyReadStandardOutput);
|
||||||
|
connect(m_process.get(), &ProcessInterface::readyReadStandardError,
|
||||||
|
this, &QtcProcessPrivate::handleReadyReadStandardError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ensureProcessInterfaceExists()
|
||||||
{
|
{
|
||||||
if (m_process)
|
if (m_process)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
setupNewProcessInstance();
|
setProcessInterface(createProcessInterface());
|
||||||
|
|
||||||
connect(m_process, &ProcessInterface::started,
|
|
||||||
q, &QtcProcess::started);
|
|
||||||
connect(m_process, &ProcessInterface::finished,
|
|
||||||
this, &QtcProcessPrivate::slotFinished);
|
|
||||||
connect(m_process, &ProcessInterface::errorOccurred,
|
|
||||||
this, [this](QProcess::ProcessError error) { handleError(error, OtherFailure); });
|
|
||||||
connect(m_process, &ProcessInterface::readyReadStandardOutput,
|
|
||||||
this, &QtcProcessPrivate::handleReadyReadStandardOutput);
|
|
||||||
connect(m_process, &ProcessInterface::readyReadStandardError,
|
|
||||||
this, &QtcProcessPrivate::handleReadyReadStandardError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleReadyReadStandardOutput()
|
void handleReadyReadStandardOutput()
|
||||||
@@ -619,7 +551,6 @@ public:
|
|||||||
qCDebug(processLog) << "STARTING PROCESS: " << ++n << " " << commandLine.toUserOutput();
|
qCDebug(processLog) << "STARTING PROCESS: " << ++n << " " << commandLine.toUserOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
ensureProcessInstanceExists();
|
|
||||||
m_process->setProcessEnvironment(environment.toProcessEnvironment());
|
m_process->setProcessEnvironment(environment.toProcessEnvironment());
|
||||||
m_process->setWorkingDirectory(workingDirectory.path());
|
m_process->setWorkingDirectory(workingDirectory.path());
|
||||||
|
|
||||||
@@ -657,7 +588,6 @@ public:
|
|||||||
void start(const QString &program, const QStringList &arguments,
|
void start(const QString &program, const QStringList &arguments,
|
||||||
const FilePath &workingDirectory, const QByteArray &writeData)
|
const FilePath &workingDirectory, const QByteArray &writeData)
|
||||||
{
|
{
|
||||||
ensureProcessInstanceExists();
|
|
||||||
const FilePath programFilePath = resolve(workingDirectory, FilePath::fromString(program));
|
const FilePath programFilePath = resolve(workingDirectory, FilePath::fromString(program));
|
||||||
if (programFilePath.exists() && programFilePath.isExecutableFile()) {
|
if (programFilePath.exists() && programFilePath.isExecutableFile()) {
|
||||||
s_start.measureAndRun(&ProcessInterface::start, m_process, program, arguments, writeData);
|
s_start.measureAndRun(&ProcessInterface::start, m_process, program, arguments, writeData);
|
||||||
@@ -696,7 +626,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
QtcProcess *q;
|
QtcProcess *q;
|
||||||
ProcessInterface *m_process = nullptr;
|
std::unique_ptr<ProcessInterface> m_process;
|
||||||
CommandLine m_commandLine;
|
CommandLine m_commandLine;
|
||||||
FilePath m_workingDirectory;
|
FilePath m_workingDirectory;
|
||||||
Environment m_environment;
|
Environment m_environment;
|
||||||
@@ -772,6 +702,11 @@ QtcProcess::~QtcProcess()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtcProcess::setProcessInterface(ProcessInterface *interface)
|
||||||
|
{
|
||||||
|
d->setProcessInterface(interface);
|
||||||
|
}
|
||||||
|
|
||||||
void QtcProcess::setProcessImpl(ProcessImpl processImpl)
|
void QtcProcess::setProcessImpl(ProcessImpl processImpl)
|
||||||
{
|
{
|
||||||
d->m_setup.m_processImpl = processImpl;
|
d->m_setup.m_processImpl = processImpl;
|
||||||
@@ -859,12 +794,12 @@ void QtcProcess::setUseCtrlCStub(bool enabled)
|
|||||||
|
|
||||||
void QtcProcess::start()
|
void QtcProcess::start()
|
||||||
{
|
{
|
||||||
d->ensureProcessInstanceExists();
|
|
||||||
if (d->m_commandLine.executable().needsDevice()) {
|
if (d->m_commandLine.executable().needsDevice()) {
|
||||||
QTC_ASSERT(s_deviceHooks.startProcessHook, return);
|
QTC_ASSERT(s_deviceHooks.startProcessHook, return);
|
||||||
s_deviceHooks.startProcessHook(*this);
|
s_deviceHooks.startProcessHook(*this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
d->ensureProcessInterfaceExists();
|
||||||
d->clearForRun();
|
d->clearForRun();
|
||||||
const CommandLine cmd = d->fullCommandLine();
|
const CommandLine cmd = d->fullCommandLine();
|
||||||
const Environment env = d->fullEnvironment();
|
const Environment env = d->fullEnvironment();
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "environment.h"
|
#include "environment.h"
|
||||||
#include "commandline.h"
|
#include "commandline.h"
|
||||||
#include "processutils.h"
|
#include "processutils.h"
|
||||||
|
#include "qtcassert.h"
|
||||||
|
|
||||||
#include <QProcess>
|
#include <QProcess>
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ namespace Utils {
|
|||||||
|
|
||||||
class CommandLine;
|
class CommandLine;
|
||||||
class Environment;
|
class Environment;
|
||||||
|
class ProcessInterface;
|
||||||
class QtcProcess;
|
class QtcProcess;
|
||||||
|
|
||||||
namespace Internal { class QtcProcessPrivate; }
|
namespace Internal { class QtcProcessPrivate; }
|
||||||
@@ -94,6 +96,8 @@ public:
|
|||||||
Hang
|
Hang
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void setProcessInterface(ProcessInterface *interface);
|
||||||
|
|
||||||
void setProcessImpl(ProcessImpl processImpl);
|
void setProcessImpl(ProcessImpl processImpl);
|
||||||
|
|
||||||
void setTerminalMode(TerminalMode mode);
|
void setTerminalMode(TerminalMode mode);
|
||||||
@@ -236,6 +240,76 @@ private:
|
|||||||
void endFeed();
|
void endFeed();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT ProcessSetupData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QtcProcess::ProcessImpl m_processImpl = QtcProcess::DefaultImpl;
|
||||||
|
ProcessMode m_processMode = ProcessMode::Reader;
|
||||||
|
QtcProcess::TerminalMode m_terminalMode = QtcProcess::TerminalOff;
|
||||||
|
|
||||||
|
QString m_nativeArguments;
|
||||||
|
QString m_standardInputFile;
|
||||||
|
QString m_initialErrorString;
|
||||||
|
bool m_belowNormalPriority = false;
|
||||||
|
bool m_lowPriority = false;
|
||||||
|
bool m_unixTerminalDisabled = false;
|
||||||
|
bool m_abortOnMetaChars = true;
|
||||||
|
QProcess::ProcessChannelMode m_procesChannelMode = QProcess::SeparateChannels;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProcessInterface(QObject *parent, ProcessMode processMode)
|
||||||
|
: QObject(parent)
|
||||||
|
, m_processMode(processMode) {}
|
||||||
|
|
||||||
|
virtual QByteArray readAllStandardOutput() = 0;
|
||||||
|
virtual QByteArray readAllStandardError() = 0;
|
||||||
|
|
||||||
|
virtual void setProcessEnvironment(const QProcessEnvironment &environment) = 0;
|
||||||
|
virtual void setWorkingDirectory(const QString &dir) = 0;
|
||||||
|
virtual void start(const QString &program, const QStringList &arguments,
|
||||||
|
const QByteArray &writeData) = 0;
|
||||||
|
virtual void customStart(const CommandLine &, const FilePath &,
|
||||||
|
const Environment &) { QTC_CHECK(false); }
|
||||||
|
virtual bool isCustomStart() const { return false; }
|
||||||
|
virtual void terminate() = 0;
|
||||||
|
virtual void kill() = 0;
|
||||||
|
virtual void close() = 0;
|
||||||
|
virtual qint64 write(const QByteArray &data) = 0;
|
||||||
|
|
||||||
|
virtual QString program() const = 0;
|
||||||
|
virtual QProcess::ProcessError error() const = 0;
|
||||||
|
virtual QProcess::ProcessState state() const = 0;
|
||||||
|
virtual qint64 processId() const = 0;
|
||||||
|
virtual int exitCode() const = 0;
|
||||||
|
virtual QProcess::ExitStatus exitStatus() const = 0;
|
||||||
|
virtual QString errorString() const = 0;
|
||||||
|
virtual void setErrorString(const QString &str) = 0;
|
||||||
|
|
||||||
|
virtual bool waitForStarted(int msecs) = 0;
|
||||||
|
virtual bool waitForReadyRead(int msecs) = 0;
|
||||||
|
virtual bool waitForFinished(int msecs) = 0;
|
||||||
|
|
||||||
|
virtual void kickoffProcess() { QTC_CHECK(false); }
|
||||||
|
virtual void interruptProcess() { QTC_CHECK(false); }
|
||||||
|
virtual qint64 applicationMainThreadID() const { QTC_CHECK(false); return -1; }
|
||||||
|
|
||||||
|
const ProcessMode m_processMode;
|
||||||
|
ProcessSetupData *m_setup = nullptr;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void started();
|
||||||
|
void finished(int exitCode, QProcess::ExitStatus status);
|
||||||
|
void errorOccurred(QProcess::ProcessError error);
|
||||||
|
void readyReadStandardOutput();
|
||||||
|
void readyReadStandardError();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
using ExitCodeInterpreter = std::function<QtcProcess::Result(int /*exitCode*/)>;
|
using ExitCodeInterpreter = std::function<QtcProcess::Result(int /*exitCode*/)>;
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
Reference in New Issue
Block a user