diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 78e82b668cc..d5aec30fe8a 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -447,9 +447,10 @@ public: OtherFailure }; - explicit QtcProcessPrivate(QtcProcess *parent) + explicit QtcProcessPrivate(QtcProcess *parent, ProcessSetupData &setup) : QObject(parent) , q(parent) + , m_setup(setup) {} ProcessInterface *createProcessInterface() @@ -525,7 +526,7 @@ public: QtcProcess *q; std::unique_ptr m_process; - ProcessSetupData m_setup; + ProcessSetupData &m_setup; void slotTimeout(); void slotFinished(); @@ -670,8 +671,8 @@ bool ProcessInterface::ensureProgramExists(const QString &program) */ QtcProcess::QtcProcess(QObject *parent) - : QObject(parent), - d(new QtcProcessPrivate(this)) + : ProcessInterface(parent), + d(new QtcProcessPrivate(this, m_setup)) { static int qProcessExitStatusMeta = qRegisterMetaType(); static int qProcessProcessErrorMeta = qRegisterMetaType(); diff --git a/src/libs/utils/qtcprocess.h b/src/libs/utils/qtcprocess.h index 081e43e6e32..7df9ed29997 100644 --- a/src/libs/utils/qtcprocess.h +++ b/src/libs/utils/qtcprocess.h @@ -43,19 +43,91 @@ class tst_QtcProcess; namespace Utils { -class ProcessInterface; -class QtcProcess; - namespace Internal { class QtcProcessPrivate; } -class DeviceProcessHooks +class QTCREATOR_UTILS_EXPORT ProcessSetupData { public: - std::function startProcessHook; - std::function systemEnvironmentForBinary; + ProcessImpl m_processImpl = ProcessImpl::Default; + ProcessMode m_processMode = ProcessMode::Reader; + TerminalMode m_terminalMode = TerminalMode::Off; + + CommandLine m_commandLine; + FilePath m_workingDirectory; + Environment m_environment; + QByteArray m_writeData; + QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels; + QVariantHash m_extraData; + QString m_standardInputFile; + QString m_errorString; // partial internal + QString m_nativeArguments; // internal, dependent on specific code path + + // TODO: Make below bools a one common flag enum? + bool m_abortOnMetaChars = true; + bool m_runAsRoot = false; + bool m_haveEnv = false; + bool m_lowPriority = false; + bool m_unixTerminalDisabled = false; + bool m_useCtrlCStub = false; // debug only + bool m_belowNormalPriority = false; // internal, dependent on other fields and specific code path }; -class QTCREATOR_UTILS_EXPORT QtcProcess : public QObject +class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject +{ + Q_OBJECT + +public: + ProcessInterface(QObject *parent) : QObject(parent) {} + + virtual void start() { defaultStart(); } + virtual void terminate() = 0; + virtual void kill() = 0; + virtual void close() = 0; + + virtual QByteArray readAllStandardOutput() = 0; + virtual QByteArray readAllStandardError() = 0; + virtual qint64 write(const QByteArray &data) = 0; + + virtual qint64 processId() const = 0; + virtual QProcess::ProcessState state() const = 0; + virtual int exitCode() const = 0; + virtual QProcess::ExitStatus exitStatus() const = 0; + + virtual QProcess::ProcessError error() 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; } + +signals: + void started(); + void finished(); + void errorOccurred(QProcess::ProcessError error); + void readyReadStandardOutput(); + void readyReadStandardError(); + +protected: + void defaultStart(); + + ProcessSetupData m_setup; + +private: + virtual void doDefaultStart(const QString &program, const QStringList &arguments) + { Q_UNUSED(program) Q_UNUSED(arguments) QTC_CHECK(false); } + bool dissolveCommand(QString *program, QStringList *arguments); + bool ensureProgramExists(const QString &program); + friend class QtcProcess; +}; + +class DeviceProcessHooks; + +class QTCREATOR_UTILS_EXPORT QtcProcess : public ProcessInterface { Q_OBJECT @@ -67,31 +139,31 @@ public: // ProcessInterface related - virtual void start(); - virtual void terminate(); - virtual void kill(); - void close(); + void start() override; + void terminate() override; + void kill() override; + void close() final; - virtual QByteArray readAllStandardOutput(); - virtual QByteArray readAllStandardError(); - virtual qint64 write(const QByteArray &input); + QByteArray readAllStandardOutput() override; + QByteArray readAllStandardError() override; + qint64 write(const QByteArray &input) override; - virtual qint64 processId() const; - virtual QProcess::ProcessState state() const; - virtual int exitCode() const; - virtual QProcess::ExitStatus exitStatus() const; + qint64 processId() const override; + QProcess::ProcessState state() const override; + int exitCode() const override; + QProcess::ExitStatus exitStatus() const override; - QProcess::ProcessError error() const; - virtual QString errorString() const; - void setErrorString(const QString &str); + QProcess::ProcessError error() const final; + QString errorString() const override; + void setErrorString(const QString &str) final; - bool waitForStarted(int msecs = 30000); - bool waitForReadyRead(int msecs = 30000); - bool waitForFinished(int msecs = 30000); + bool waitForStarted(int msecs = 30000) final; + bool waitForReadyRead(int msecs = 30000) final; + bool waitForFinished(int msecs = 30000) final; - void kickoffProcess(); - void interruptProcess(); - qint64 applicationMainThreadID() const; + void kickoffProcess() final; + void interruptProcess() final; + qint64 applicationMainThreadID() const final; // ProcessSetupData related @@ -218,16 +290,10 @@ public: QString toStandaloneCommandLine() const; -signals: - void started(); - void finished(); - void errorOccurred(QProcess::ProcessError error); - void readyReadStandardOutput(); - void readyReadStandardError(); - private: friend QTCREATOR_UTILS_EXPORT QDebug operator<<(QDebug str, const QtcProcess &r); + friend class Internal::QtcProcessPrivate; Internal::QtcProcessPrivate *d = nullptr; friend tst_QtcProcess; @@ -236,87 +302,13 @@ private: void endFeed(); }; -class QTCREATOR_UTILS_EXPORT ProcessSetupData +class DeviceProcessHooks { public: - ProcessImpl m_processImpl = ProcessImpl::Default; - ProcessMode m_processMode = ProcessMode::Reader; - TerminalMode m_terminalMode = TerminalMode::Off; - - CommandLine m_commandLine; - FilePath m_workingDirectory; - Environment m_environment; - QByteArray m_writeData; - QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels; - QVariantHash m_extraData; - QString m_standardInputFile; - QString m_errorString; // partial internal - QString m_nativeArguments; // internal, dependent on specific code path - - // TODO: Make below bools a one common flag enum? - bool m_abortOnMetaChars = true; - bool m_runAsRoot = false; - bool m_haveEnv = false; - bool m_lowPriority = false; - bool m_unixTerminalDisabled = false; - bool m_useCtrlCStub = false; // debug only - bool m_belowNormalPriority = false; // internal, dependent on other fields and specific code path + std::function startProcessHook; + std::function systemEnvironmentForBinary; }; -class QTCREATOR_UTILS_EXPORT ProcessInterface : public QObject -{ - Q_OBJECT - -public: - ProcessInterface(QObject *parent) : QObject(parent) {} - - virtual void start() { defaultStart(); } - virtual void terminate() = 0; - virtual void kill() = 0; - virtual void close() = 0; - - virtual QByteArray readAllStandardOutput() = 0; - virtual QByteArray readAllStandardError() = 0; - virtual qint64 write(const QByteArray &data) = 0; - - virtual qint64 processId() const = 0; - virtual QProcess::ProcessState state() const = 0; - virtual int exitCode() const = 0; - virtual QProcess::ExitStatus exitStatus() const = 0; - - virtual QProcess::ProcessError error() 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; } - -signals: - void started(); - void finished(); - void errorOccurred(QProcess::ProcessError error); - void readyReadStandardOutput(); - void readyReadStandardError(); - -protected: - void defaultStart(); - - ProcessSetupData m_setup; - -private: - virtual void doDefaultStart(const QString &program, const QStringList &arguments) - { Q_UNUSED(program) Q_UNUSED(arguments) QTC_CHECK(false); } - bool dissolveCommand(QString *program, QStringList *arguments); - bool ensureProgramExists(const QString &program); - friend class QtcProcess; -}; - - using ExitCodeInterpreter = std::function; } // namespace Utils