forked from qt-creator/qt-creator
ProcessInterface: Add readyRead() signal
And get rid of readyReadStandard[Output/Error]() signals. Get rid of readAllStandard[Output/Error]() accessors, as this data is passed with readyRead() signal. Task-number: QTCREATORBUG-27358 Change-Id: I01341feba650e650761f97e90f83b6042c899251 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -33,8 +33,6 @@
|
|||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <QMutexLocker>
|
#include <QMutexLocker>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -184,29 +182,7 @@ void CallerHandle::handleStarted(const StartedSignal *launcherSignal)
|
|||||||
void CallerHandle::handleReadyRead(const ReadyReadSignal *launcherSignal)
|
void CallerHandle::handleReadyRead(const ReadyReadSignal *launcherSignal)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return);
|
QTC_ASSERT(isCalledFromCallersThread(), return);
|
||||||
if (m_setup->m_processChannelMode == QProcess::MergedChannels) {
|
emit readyRead(launcherSignal->stdOut(), launcherSignal->stdErr());
|
||||||
m_stdout += launcherSignal->stdOut();
|
|
||||||
m_stdout += launcherSignal->stdErr();
|
|
||||||
if (!m_stdout.isEmpty())
|
|
||||||
emit readyReadStandardOutput();
|
|
||||||
} else {
|
|
||||||
if (m_setup->m_processChannelMode == QProcess::ForwardedOutputChannel
|
|
||||||
|| m_setup->m_processChannelMode == QProcess::ForwardedChannels) {
|
|
||||||
std::cout << launcherSignal->stdOut().constData() << std::flush;
|
|
||||||
} else {
|
|
||||||
m_stdout += launcherSignal->stdOut();
|
|
||||||
if (!m_stdout.isEmpty())
|
|
||||||
emit readyReadStandardOutput();
|
|
||||||
}
|
|
||||||
if (m_setup->m_processChannelMode == QProcess::ForwardedErrorChannel
|
|
||||||
|| m_setup->m_processChannelMode == QProcess::ForwardedChannels) {
|
|
||||||
std::cerr << launcherSignal->stdErr().constData() << std::flush;
|
|
||||||
} else {
|
|
||||||
m_stderr += launcherSignal->stdErr();
|
|
||||||
if (!m_stderr.isEmpty())
|
|
||||||
emit readyReadStandardError();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CallerHandle::handleDone(const DoneSignal *launcherSignal)
|
void CallerHandle::handleDone(const DoneSignal *launcherSignal)
|
||||||
@@ -297,18 +273,6 @@ void CallerHandle::kill()
|
|||||||
sendStopPacket(StopProcessPacket::SignalType::Kill);
|
sendStopPacket(StopProcessPacket::SignalType::Kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray CallerHandle::readAllStandardOutput()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return {});
|
|
||||||
return readAndClear(m_stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray CallerHandle::readAllStandardError()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return {});
|
|
||||||
return readAndClear(m_stderr);
|
|
||||||
}
|
|
||||||
|
|
||||||
qint64 CallerHandle::processId() const
|
qint64 CallerHandle::processId() const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(isCalledFromCallersThread(), return 0);
|
QTC_ASSERT(isCalledFromCallersThread(), return 0);
|
||||||
|
|||||||
@@ -93,9 +93,6 @@ public:
|
|||||||
void terminate();
|
void terminate();
|
||||||
void kill();
|
void kill();
|
||||||
|
|
||||||
QByteArray readAllStandardOutput();
|
|
||||||
QByteArray readAllStandardError();
|
|
||||||
|
|
||||||
qint64 processId() const;
|
qint64 processId() const;
|
||||||
|
|
||||||
void start(const QString &program, const QStringList &arguments);
|
void start(const QString &program, const QStringList &arguments);
|
||||||
@@ -113,8 +110,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
void done(const Utils::ProcessResultData &resultData);
|
void done(const Utils::ProcessResultData &resultData);
|
||||||
void readyReadStandardOutput();
|
void readyRead(const QByteArray &outputData, const QByteArray &errorData);
|
||||||
void readyReadStandardError();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool waitForSignal(int msecs, SignalType newSignal);
|
bool waitForSignal(int msecs, SignalType newSignal);
|
||||||
@@ -153,8 +149,6 @@ private:
|
|||||||
std::atomic<QProcess::ProcessState> m_processState = QProcess::NotRunning;
|
std::atomic<QProcess::ProcessState> m_processState = QProcess::NotRunning;
|
||||||
std::unique_ptr<StartProcessPacket> m_startPacket;
|
std::unique_ptr<StartProcessPacket> m_startPacket;
|
||||||
int m_processId = 0;
|
int m_processId = 0;
|
||||||
QByteArray m_stdout;
|
|
||||||
QByteArray m_stderr;
|
|
||||||
|
|
||||||
QString m_command;
|
QString m_command;
|
||||||
QStringList m_arguments;
|
QStringList m_arguments;
|
||||||
|
|||||||
@@ -49,7 +49,6 @@ public:
|
|||||||
Environment m_environment;
|
Environment m_environment;
|
||||||
Environment m_remoteEnvironment;
|
Environment m_remoteEnvironment;
|
||||||
QByteArray m_writeData;
|
QByteArray m_writeData;
|
||||||
QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels;
|
|
||||||
QVariantHash m_extraData;
|
QVariantHash m_extraData;
|
||||||
QString m_standardInputFile;
|
QString m_standardInputFile;
|
||||||
QString m_nativeArguments; // internal, dependent on specific code path
|
QString m_nativeArguments; // internal, dependent on specific code path
|
||||||
@@ -86,8 +85,6 @@ public:
|
|||||||
virtual void kill() = 0;
|
virtual void kill() = 0;
|
||||||
virtual void close() = 0;
|
virtual void close() = 0;
|
||||||
|
|
||||||
virtual QByteArray readAllStandardOutput() = 0;
|
|
||||||
virtual QByteArray readAllStandardError() = 0;
|
|
||||||
virtual qint64 write(const QByteArray &data) = 0;
|
virtual qint64 write(const QByteArray &data) = 0;
|
||||||
|
|
||||||
virtual qint64 processId() const = 0;
|
virtual qint64 processId() const = 0;
|
||||||
@@ -102,9 +99,8 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void started();
|
void started();
|
||||||
|
void readyRead(const QByteArray &outputData, const QByteArray &errorData);
|
||||||
void done(const Utils::ProcessResultData &resultData);
|
void done(const Utils::ProcessResultData &resultData);
|
||||||
void readyReadStandardOutput();
|
|
||||||
void readyReadStandardError();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ProcessSetupData::Ptr m_setup;
|
ProcessSetupData::Ptr m_setup;
|
||||||
@@ -123,11 +119,8 @@ public:
|
|||||||
{
|
{
|
||||||
m_target->setParent(this);
|
m_target->setParent(this);
|
||||||
connect(m_target, &ProcessInterface::started, this, &ProcessInterface::started);
|
connect(m_target, &ProcessInterface::started, this, &ProcessInterface::started);
|
||||||
|
connect(m_target, &ProcessInterface::readyRead, this, &ProcessInterface::readyRead);
|
||||||
connect(m_target, &ProcessInterface::done, this, &ProcessInterface::done);
|
connect(m_target, &ProcessInterface::done, this, &ProcessInterface::done);
|
||||||
connect(m_target, &ProcessInterface::readyReadStandardOutput,
|
|
||||||
this, &ProcessInterface::readyReadStandardOutput);
|
|
||||||
connect(m_target, &ProcessInterface::readyReadStandardError,
|
|
||||||
this, &ProcessInterface::readyReadStandardError);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void start() override { m_target->start(); }
|
void start() override { m_target->start(); }
|
||||||
@@ -136,8 +129,6 @@ public:
|
|||||||
void kill() override { m_target->kill(); }
|
void kill() override { m_target->kill(); }
|
||||||
void close() override { m_target->close(); }
|
void close() override { m_target->close(); }
|
||||||
|
|
||||||
QByteArray readAllStandardOutput() override { return m_target->readAllStandardOutput(); }
|
|
||||||
QByteArray readAllStandardError() override { return m_target->readAllStandardError(); }
|
|
||||||
qint64 write(const QByteArray &data) override { return m_target->write(data); }
|
qint64 write(const QByteArray &data) override { return m_target->write(data); }
|
||||||
|
|
||||||
qint64 processId() const override { return m_target->processId(); }
|
qint64 processId() const override { return m_target->processId(); }
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -337,16 +338,15 @@ public:
|
|||||||
this, &QProcessImpl::handleFinished);
|
this, &QProcessImpl::handleFinished);
|
||||||
connect(m_process, &QProcess::errorOccurred,
|
connect(m_process, &QProcess::errorOccurred,
|
||||||
this, &QProcessImpl::handleError);
|
this, &QProcessImpl::handleError);
|
||||||
connect(m_process, &QProcess::readyReadStandardOutput,
|
connect(m_process, &QProcess::readyReadStandardOutput, this, [this] {
|
||||||
this, &ProcessInterface::readyReadStandardOutput);
|
emit readyRead(m_process->readAllStandardOutput(), {});
|
||||||
connect(m_process, &QProcess::readyReadStandardError,
|
});
|
||||||
this, &ProcessInterface::readyReadStandardError);
|
connect(m_process, &QProcess::readyReadStandardError, this, [this] {
|
||||||
|
emit readyRead({}, m_process->readAllStandardError());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
~QProcessImpl() final { ProcessReaper::reap(m_process); }
|
~QProcessImpl() final { ProcessReaper::reap(m_process); }
|
||||||
|
|
||||||
QByteArray readAllStandardOutput() final { return m_process->readAllStandardOutput(); }
|
|
||||||
QByteArray readAllStandardError() final { return m_process->readAllStandardError(); }
|
|
||||||
|
|
||||||
void interrupt() final { ProcessHelper::interruptProcess(m_process); }
|
void interrupt() final { ProcessHelper::interruptProcess(m_process); }
|
||||||
void terminate() final { ProcessHelper::terminateProcess(m_process); }
|
void terminate() final { ProcessHelper::terminateProcess(m_process); }
|
||||||
void kill() final { m_process->kill(); }
|
void kill() final { m_process->kill(); }
|
||||||
@@ -372,7 +372,6 @@ private:
|
|||||||
m_process->setProcessEnvironment(m_setup->m_environment.toProcessEnvironment());
|
m_process->setProcessEnvironment(m_setup->m_environment.toProcessEnvironment());
|
||||||
m_process->setWorkingDirectory(m_setup->m_workingDirectory.path());
|
m_process->setWorkingDirectory(m_setup->m_workingDirectory.path());
|
||||||
m_process->setStandardInputFile(m_setup->m_standardInputFile);
|
m_process->setStandardInputFile(m_setup->m_standardInputFile);
|
||||||
m_process->setProcessChannelMode(m_setup->m_processChannelMode);
|
|
||||||
if (m_setup->m_lowPriority)
|
if (m_setup->m_lowPriority)
|
||||||
m_process->setLowPriority();
|
m_process->setLowPriority();
|
||||||
if (m_setup->m_unixTerminalDisabled)
|
if (m_setup->m_unixTerminalDisabled)
|
||||||
@@ -423,12 +422,10 @@ public:
|
|||||||
m_handle->setProcessSetupData(m_setup);
|
m_handle->setProcessSetupData(m_setup);
|
||||||
connect(m_handle, &CallerHandle::started,
|
connect(m_handle, &CallerHandle::started,
|
||||||
this, &ProcessInterface::started);
|
this, &ProcessInterface::started);
|
||||||
|
connect(m_handle, &CallerHandle::readyRead,
|
||||||
|
this, &ProcessInterface::readyRead);
|
||||||
connect(m_handle, &CallerHandle::done,
|
connect(m_handle, &CallerHandle::done,
|
||||||
this, &ProcessInterface::done);
|
this, &ProcessInterface::done);
|
||||||
connect(m_handle, &CallerHandle::readyReadStandardOutput,
|
|
||||||
this, &ProcessInterface::readyReadStandardOutput);
|
|
||||||
connect(m_handle, &CallerHandle::readyReadStandardError,
|
|
||||||
this, &ProcessInterface::readyReadStandardError);
|
|
||||||
}
|
}
|
||||||
~ProcessLauncherImpl() final
|
~ProcessLauncherImpl() final
|
||||||
{
|
{
|
||||||
@@ -437,9 +434,6 @@ public:
|
|||||||
m_handle = nullptr;
|
m_handle = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray readAllStandardOutput() final { return m_handle->readAllStandardOutput(); }
|
|
||||||
QByteArray readAllStandardError() final { return m_handle->readAllStandardError(); }
|
|
||||||
|
|
||||||
void interrupt() final
|
void interrupt() final
|
||||||
{
|
{
|
||||||
if (m_setup->m_useCtrlCStub) // bypass launcher and interrupt directly
|
if (m_setup->m_useCtrlCStub) // bypass launcher and interrupt directly
|
||||||
@@ -504,26 +498,10 @@ public:
|
|||||||
|
|
||||||
connect(m_process.get(), &ProcessInterface::started,
|
connect(m_process.get(), &ProcessInterface::started,
|
||||||
this, &QtcProcessPrivate::emitStarted);
|
this, &QtcProcessPrivate::emitStarted);
|
||||||
|
connect(m_process.get(), &ProcessInterface::readyRead,
|
||||||
|
this, &QtcProcessPrivate::handleReadyRead);
|
||||||
connect(m_process.get(), &ProcessInterface::done,
|
connect(m_process.get(), &ProcessInterface::done,
|
||||||
this, &QtcProcessPrivate::handleDone);
|
this, &QtcProcessPrivate::handleDone);
|
||||||
connect(m_process.get(), &ProcessInterface::readyReadStandardOutput,
|
|
||||||
this, &QtcProcessPrivate::handleReadyReadStandardOutput);
|
|
||||||
connect(m_process.get(), &ProcessInterface::readyReadStandardError,
|
|
||||||
this, &QtcProcessPrivate::handleReadyReadStandardError);
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleReadyReadStandardOutput()
|
|
||||||
{
|
|
||||||
m_stdOut.append(m_process->readAllStandardOutput());
|
|
||||||
m_hangTimerCount = 0;
|
|
||||||
emitReadyReadStandardOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleReadyReadStandardError()
|
|
||||||
{
|
|
||||||
m_stdErr.append(m_process->readAllStandardError());
|
|
||||||
m_hangTimerCount = 0;
|
|
||||||
emitReadyReadStandardError();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandLine fullCommandLine() const
|
CommandLine fullCommandLine() const
|
||||||
@@ -558,6 +536,7 @@ public:
|
|||||||
ProcessSetupData m_setup;
|
ProcessSetupData m_setup;
|
||||||
|
|
||||||
void slotTimeout();
|
void slotTimeout();
|
||||||
|
void handleReadyRead(const QByteArray &outputData, const QByteArray &errorData);
|
||||||
void handleDone(const ProcessResultData &data);
|
void handleDone(const ProcessResultData &data);
|
||||||
void handleError();
|
void handleError();
|
||||||
void clearForRun();
|
void clearForRun();
|
||||||
@@ -570,6 +549,7 @@ public:
|
|||||||
|
|
||||||
ProcessResult interpretExitCode(int exitCode);
|
ProcessResult interpretExitCode(int exitCode);
|
||||||
|
|
||||||
|
QProcess::ProcessChannelMode m_processChannelMode = QProcess::SeparateChannels;
|
||||||
ProcessResultData m_resultData;
|
ProcessResultData m_resultData;
|
||||||
|
|
||||||
QTextCodec *m_codec = QTextCodec::codecForLocale();
|
QTextCodec *m_codec = QTextCodec::codecForLocale();
|
||||||
@@ -1154,7 +1134,8 @@ qint64 QtcProcess::applicationMainThreadID() const
|
|||||||
|
|
||||||
void QtcProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode)
|
void QtcProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode)
|
||||||
{
|
{
|
||||||
d->m_setup.m_processChannelMode = mode;
|
QTC_CHECK(state() == QProcess::NotRunning);
|
||||||
|
d->m_processChannelMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
QProcess::ProcessState QtcProcess::state() const
|
QProcess::ProcessState QtcProcess::state() const
|
||||||
@@ -1489,11 +1470,6 @@ void QtcProcess::runBlocking(EventLoopMode eventLoopMode)
|
|||||||
d->m_eventLoop = &eventLoop;
|
d->m_eventLoop = &eventLoop;
|
||||||
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
|
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
|
||||||
d->m_eventLoop = nullptr;
|
d->m_eventLoop = nullptr;
|
||||||
d->m_stdOut.append(d->m_process->readAllStandardOutput());
|
|
||||||
d->m_stdErr.append(d->m_process->readAllStandardError());
|
|
||||||
d->m_stdOut.handleRest();
|
|
||||||
d->m_stdErr.handleRest();
|
|
||||||
|
|
||||||
timer.stop();
|
timer.stop();
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
if (isGuiThread())
|
if (isGuiThread())
|
||||||
@@ -1512,10 +1488,6 @@ void QtcProcess::runBlocking(EventLoopMode eventLoopMode)
|
|||||||
kill();
|
kill();
|
||||||
waitForFinished(1000);
|
waitForFinished(1000);
|
||||||
}
|
}
|
||||||
d->m_stdOut.append(d->m_process->readAllStandardOutput());
|
|
||||||
d->m_stdErr.append(d->m_process->readAllStandardError());
|
|
||||||
d->m_stdOut.handleRest();
|
|
||||||
d->m_stdErr.handleRest();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1567,6 +1539,37 @@ void QtcProcessPrivate::slotTimeout()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void QtcProcessPrivate::handleReadyRead(const QByteArray &outputData, const QByteArray &errorData)
|
||||||
|
{
|
||||||
|
// TODO: check why we need this timer?
|
||||||
|
m_hangTimerCount = 0;
|
||||||
|
// TODO: store a copy of m_processChannelMode on start()? Currently we assert that state
|
||||||
|
// is NotRunning when setting the process channel mode.
|
||||||
|
if (m_processChannelMode == QProcess::MergedChannels) {
|
||||||
|
m_stdOut.append(outputData);
|
||||||
|
m_stdOut.append(errorData);
|
||||||
|
if (!outputData.isEmpty() || !errorData.isEmpty())
|
||||||
|
emitReadyReadStandardOutput();
|
||||||
|
} else {
|
||||||
|
if (m_processChannelMode == QProcess::ForwardedOutputChannel
|
||||||
|
|| m_processChannelMode == QProcess::ForwardedChannels) {
|
||||||
|
std::cout << outputData.constData() << std::flush;
|
||||||
|
} else {
|
||||||
|
m_stdOut.append(outputData);
|
||||||
|
if (!outputData.isEmpty())
|
||||||
|
emitReadyReadStandardOutput();
|
||||||
|
}
|
||||||
|
if (m_processChannelMode == QProcess::ForwardedErrorChannel
|
||||||
|
|| m_processChannelMode == QProcess::ForwardedChannels) {
|
||||||
|
std::cerr << errorData.constData() << std::flush;
|
||||||
|
} else {
|
||||||
|
m_stdErr.append(errorData);
|
||||||
|
if (!errorData.isEmpty())
|
||||||
|
emitReadyReadStandardError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QtcProcessPrivate::handleDone(const ProcessResultData &data)
|
void QtcProcessPrivate::handleDone(const ProcessResultData &data)
|
||||||
{
|
{
|
||||||
m_resultData = data;
|
m_resultData = data;
|
||||||
@@ -1616,9 +1619,6 @@ void QtcProcessPrivate::handleError()
|
|||||||
// Was hang detected before and killed?
|
// Was hang detected before and killed?
|
||||||
if (m_result != ProcessResult::Hang)
|
if (m_result != ProcessResult::Hang)
|
||||||
m_result = ProcessResult::StartFailed;
|
m_result = ProcessResult::StartFailed;
|
||||||
if (m_eventLoop)
|
|
||||||
m_eventLoop->quit();
|
|
||||||
|
|
||||||
emitErrorOccurred(m_resultData.m_error);
|
emitErrorOccurred(m_resultData.m_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,9 +45,6 @@ public:
|
|||||||
TerminalImpl();
|
TerminalImpl();
|
||||||
~TerminalImpl() final;
|
~TerminalImpl() final;
|
||||||
|
|
||||||
QByteArray readAllStandardOutput() final { QTC_CHECK(false); return {}; }
|
|
||||||
QByteArray readAllStandardError() final { QTC_CHECK(false); return {}; }
|
|
||||||
|
|
||||||
qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; }
|
qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; }
|
||||||
|
|
||||||
void terminate() final { stopProcess(); }
|
void terminate() final { stopProcess(); }
|
||||||
|
|||||||
Reference in New Issue
Block a user