Utils: Merge TerminalProcess into TerminalImpl

Change-Id: I60a03f315e84e17877d4ecd809a994f08934bedf
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
hjk
2022-03-31 15:50:28 +02:00
parent e437cf7a71
commit 6297851f29
3 changed files with 106 additions and 189 deletions

View File

@@ -212,62 +212,6 @@ public:
bool keepRawData = true; bool keepRawData = true;
}; };
class TerminalImpl : public ProcessInterface
{
public:
TerminalImpl() : m_terminal(this)
{
connect(&m_terminal, &Internal::TerminalProcess::started,
this, &ProcessInterface::started);
connect(&m_terminal, &Internal::TerminalProcess::finished,
this, &ProcessInterface::finished);
connect(&m_terminal, &Internal::TerminalProcess::errorOccurred,
this, &ProcessInterface::errorOccurred);
}
~TerminalImpl() override
{
}
QByteArray readAllStandardOutput() override { QTC_CHECK(false); return {}; }
QByteArray readAllStandardError() override { QTC_CHECK(false); return {}; }
void start() override
{
m_terminal.setProcessImpl(m_setup->m_processImpl);
m_terminal.setTerminalMode(m_setup->m_terminalMode);
m_terminal.setAbortOnMetaChars(m_setup->m_abortOnMetaChars);
m_terminal.setCommand(m_setup->m_commandLine);
m_terminal.setWorkingDirectory(m_setup->m_workingDirectory);
m_terminal.setEnvironment(m_setup->m_environment);
m_terminal.start();
}
void interrupt() override { m_terminal.interrupt(); }
void terminate() override { m_terminal.stopProcess(); }
void kill() override { m_terminal.stopProcess(); }
void close() override { m_terminal.stopProcess(); }
qint64 write(const QByteArray &) override { QTC_CHECK(false); return -1; }
QProcess::ProcessError error() const override { return m_terminal.error(); }
QProcess::ProcessState state() const override { return m_terminal.state(); }
qint64 processId() const override { return m_terminal.processId(); }
int exitCode() const override { return m_terminal.exitCode(); }
QProcess::ExitStatus exitStatus() const override { return m_terminal.exitStatus(); }
QString errorString() const override { return m_terminal.errorString(); }
void setErrorString(const QString &) override { QTC_CHECK(false); }
// intentionally no-op without an assert
bool waitForStarted(int) override { return false; }
bool waitForReadyRead(int) override { QTC_CHECK(false); return false; }
// intentionally no-op without an assert
bool waitForFinished(int) override { return false; }
void kickoffProcess() override { m_terminal.kickoffProcess(); }
qint64 applicationMainThreadID() const override { return m_terminal.applicationMainThreadID(); }
private:
Internal::TerminalProcess m_terminal;
};
class DefaultImpl : public ProcessInterface class DefaultImpl : public ProcessInterface
{ {
public: public:

View File

@@ -81,43 +81,43 @@ static QString modeOption(TerminalMode m)
static QString msgCommChannelFailed(const QString &error) static QString msgCommChannelFailed(const QString &error)
{ {
return TerminalProcess::tr("Cannot set up communication channel: %1").arg(error); return TerminalImpl::tr("Cannot set up communication channel: %1").arg(error);
} }
static QString msgPromptToClose() static QString msgPromptToClose()
{ {
// Shown in a terminal which might have a different character set on Windows. // Shown in a terminal which might have a different character set on Windows.
return TerminalProcess::tr("Press <RETURN> to close this window..."); return TerminalImpl::tr("Press <RETURN> to close this window...");
} }
static QString msgCannotCreateTempFile(const QString &why) static QString msgCannotCreateTempFile(const QString &why)
{ {
return TerminalProcess::tr("Cannot create temporary file: %1").arg(why); return TerminalImpl::tr("Cannot create temporary file: %1").arg(why);
} }
static QString msgCannotWriteTempFile() static QString msgCannotWriteTempFile()
{ {
return TerminalProcess::tr("Cannot write temporary file. Disk full?"); return TerminalImpl::tr("Cannot write temporary file. Disk full?");
} }
static QString msgCannotCreateTempDir(const QString & dir, const QString &why) static QString msgCannotCreateTempDir(const QString & dir, const QString &why)
{ {
return TerminalProcess::tr("Cannot create temporary directory \"%1\": %2").arg(dir, why); return TerminalImpl::tr("Cannot create temporary directory \"%1\": %2").arg(dir, why);
} }
static QString msgUnexpectedOutput(const QByteArray &what) static QString msgUnexpectedOutput(const QByteArray &what)
{ {
return TerminalProcess::tr("Unexpected output from helper program (%1).").arg(QString::fromLatin1(what)); return TerminalImpl::tr("Unexpected output from helper program (%1).").arg(QString::fromLatin1(what));
} }
static QString msgCannotChangeToWorkDir(const FilePath &dir, const QString &why) static QString msgCannotChangeToWorkDir(const FilePath &dir, const QString &why)
{ {
return TerminalProcess::tr("Cannot change to working directory \"%1\": %2").arg(dir.toString(), why); return TerminalImpl::tr("Cannot change to working directory \"%1\": %2").arg(dir.toString(), why);
} }
static QString msgCannotExecute(const QString & p, const QString &why) static QString msgCannotExecute(const QString & p, const QString &why)
{ {
return TerminalProcess::tr("Cannot execute \"%1\": %2").arg(p, why); return TerminalImpl::tr("Cannot execute \"%1\": %2").arg(p, why);
} }
class TerminalProcessPrivate class TerminalProcessPrivate
@@ -126,19 +126,14 @@ public:
TerminalProcessPrivate(QObject *parent) TerminalProcessPrivate(QObject *parent)
: m_process(parent) {} : m_process(parent) {}
TerminalMode m_terminalMode = TerminalMode::On;
FilePath m_workingDir;
Environment m_environment;
qint64 m_processId = 0; qint64 m_processId = 0;
int m_exitCode = 0; int m_exitCode = 0;
CommandLine m_commandLine;
QProcess::ExitStatus m_appStatus = QProcess::NormalExit; QProcess::ExitStatus m_appStatus = QProcess::NormalExit;
QLocalServer m_stubServer; QLocalServer m_stubServer;
QLocalSocket *m_stubSocket = nullptr; QLocalSocket *m_stubSocket = nullptr;
QTemporaryFile *m_tempFile = nullptr; QTemporaryFile *m_tempFile = nullptr;
QProcess::ProcessError m_error = QProcess::UnknownError; QProcess::ProcessError m_error = QProcess::UnknownError;
QString m_errorString; QString m_errorString;
bool m_abortOnMetaChars = true;
// Used on Unix only // Used on Unix only
QtcProcess m_process; QtcProcess m_process;
@@ -156,50 +151,29 @@ public:
#endif #endif
}; };
TerminalProcess::TerminalProcess(QObject *parent) TerminalImpl::TerminalImpl()
: QObject(parent), d(new TerminalProcessPrivate(this)) : d(new TerminalProcessPrivate(this))
{ {
connect(&d->m_stubServer, &QLocalServer::newConnection, connect(&d->m_stubServer, &QLocalServer::newConnection,
this, &TerminalProcess::stubConnectionAvailable); this, &TerminalImpl::stubConnectionAvailable);
d->m_process.setProcessChannelMode(QProcess::ForwardedChannels); d->m_process.setProcessChannelMode(QProcess::ForwardedChannels);
} }
TerminalProcess::~TerminalProcess() TerminalImpl::~TerminalImpl()
{ {
stopProcess(); stopProcess();
delete d; delete d;
} }
void TerminalProcess::setProcessImpl(ProcessImpl processImpl) qint64 TerminalImpl::applicationMainThreadID() const
{
d->m_process.setProcessImpl(processImpl);
}
void TerminalProcess::setTerminalMode(TerminalMode mode)
{
QTC_ASSERT(mode != TerminalMode::Off, return);
d->m_terminalMode = mode;
}
void TerminalProcess::setCommand(const CommandLine &command)
{
d->m_commandLine = command;
}
void TerminalProcess::setAbortOnMetaChars(bool abort)
{
d->m_abortOnMetaChars = abort;
}
qint64 TerminalProcess::applicationMainThreadID() const
{ {
if (HostOsInfo::isWindowsHost()) if (HostOsInfo::isWindowsHost())
return d->m_appMainThreadId; return d->m_appMainThreadId;
return -1; return -1;
} }
void TerminalProcess::start() void TerminalImpl::start()
{ {
if (isRunning()) if (isRunning())
return; return;
@@ -211,13 +185,13 @@ void TerminalProcess::start()
QString pcmd; QString pcmd;
QString pargs; QString pargs;
if (d->m_terminalMode != TerminalMode::Run) { // The debugger engines already pre-process the arguments. if (m_setup->m_terminalMode != TerminalMode::Run) { // The debugger engines already pre-process the arguments.
pcmd = d->m_commandLine.executable().toString(); pcmd = m_setup->m_commandLine.executable().toString();
pargs = d->m_commandLine.arguments(); pargs = m_setup->m_commandLine.arguments();
} else { } else {
ProcessArgs outArgs; ProcessArgs outArgs;
ProcessArgs::prepareCommand(d->m_commandLine, &pcmd, &outArgs, ProcessArgs::prepareCommand(m_setup->m_commandLine, &pcmd, &outArgs,
&d->m_environment, &d->m_workingDir); &m_setup->m_environment, &m_setup->m_workingDirectory);
pargs = outArgs.toWindowsArgs(); pargs = outArgs.toWindowsArgs();
} }
@@ -227,7 +201,7 @@ void TerminalProcess::start()
return; return;
} }
QStringList env = d->m_environment.toStringList(); QStringList env = m_setup->m_environment.toStringList();
if (!env.isEmpty()) { if (!env.isEmpty()) {
d->m_tempFile = new QTemporaryFile(); d->m_tempFile = new QTemporaryFile();
if (!d->m_tempFile->open()) { if (!d->m_tempFile->open()) {
@@ -274,7 +248,7 @@ void TerminalProcess::start()
d->m_pid = new PROCESS_INFORMATION; d->m_pid = new PROCESS_INFORMATION;
ZeroMemory(d->m_pid, sizeof(PROCESS_INFORMATION)); ZeroMemory(d->m_pid, sizeof(PROCESS_INFORMATION));
QString workDir = d->m_workingDir.toUserOutput(); QString workDir = m_setup->m_workingDirectory.toUserOutput();
if (!workDir.isEmpty() && !workDir.endsWith(QLatin1Char('\\'))) if (!workDir.isEmpty() && !workDir.endsWith(QLatin1Char('\\')))
workDir.append(QLatin1Char('\\')); workDir.append(QLatin1Char('\\'));
@@ -330,7 +304,7 @@ void TerminalProcess::start()
}; };
QStringList stubArgs; QStringList stubArgs;
stubArgs << modeOption(d->m_terminalMode) stubArgs << modeOption(m_setup->m_terminalMode)
<< d->m_stubServer.fullServerName() << d->m_stubServer.fullServerName()
<< workDir << workDir
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString()) << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
@@ -356,27 +330,27 @@ void TerminalProcess::start()
d->processFinishedNotifier = new QWinEventNotifier(d->m_pid->hProcess, this); d->processFinishedNotifier = new QWinEventNotifier(d->m_pid->hProcess, this);
connect(d->processFinishedNotifier, &QWinEventNotifier::activated, connect(d->processFinishedNotifier, &QWinEventNotifier::activated,
this, &TerminalProcess::stubExited); this, &TerminalImpl::stubExited);
#else #else
ProcessArgs::SplitError perr; ProcessArgs::SplitError perr;
ProcessArgs pargs = ProcessArgs::prepareArgs(d->m_commandLine.arguments(), ProcessArgs pargs = ProcessArgs::prepareArgs(m_setup->m_commandLine.arguments(),
&perr, &perr,
HostOsInfo::hostOs(), HostOsInfo::hostOs(),
&d->m_environment, &m_setup->m_environment,
&d->m_workingDir, &m_setup->m_workingDirectory,
d->m_abortOnMetaChars); m_setup->m_abortOnMetaChars);
QString pcmd; QString pcmd;
if (perr == ProcessArgs::SplitOk) { if (perr == ProcessArgs::SplitOk) {
pcmd = d->m_commandLine.executable().toString(); pcmd = m_setup->m_commandLine.executable().toString();
} else { } else {
if (perr != ProcessArgs::FoundMeta) { if (perr != ProcessArgs::FoundMeta) {
emitError(QProcess::FailedToStart, tr("Quoting error in command.")); emitError(QProcess::FailedToStart, tr("Quoting error in command."));
return; return;
} }
if (d->m_terminalMode == TerminalMode::Debug) { if (m_setup->m_terminalMode == TerminalMode::Debug) {
// FIXME: QTCREATORBUG-2809 // FIXME: QTCREATORBUG-2809
emitError(QProcess::FailedToStart, tr("Debugging complex shell commands in a terminal" emitError(QProcess::FailedToStart, tr("Debugging complex shell commands in a terminal"
" is currently not supported.")); " is currently not supported."));
@@ -384,8 +358,8 @@ void TerminalProcess::start()
} }
pcmd = qEnvironmentVariable("SHELL", "/bin/sh"); pcmd = qEnvironmentVariable("SHELL", "/bin/sh");
pargs = ProcessArgs::createUnixArgs( pargs = ProcessArgs::createUnixArgs(
{"-c", (ProcessArgs::quoteArg(d->m_commandLine.executable().toString()) {"-c", (ProcessArgs::quoteArg(m_setup->m_commandLine.executable().toString())
+ ' ' + d->m_commandLine.arguments())}); + ' ' + m_setup->m_commandLine.arguments())});
} }
ProcessArgs::SplitError qerr; ProcessArgs::SplitError qerr;
@@ -393,8 +367,8 @@ void TerminalProcess::start()
const ProcessArgs terminalArgs = ProcessArgs::prepareArgs(terminal.executeArgs, const ProcessArgs terminalArgs = ProcessArgs::prepareArgs(terminal.executeArgs,
&qerr, &qerr,
HostOsInfo::hostOs(), HostOsInfo::hostOs(),
&d->m_environment, &m_setup->m_environment,
&d->m_workingDir); &m_setup->m_workingDirectory);
if (qerr != ProcessArgs::SplitOk) { if (qerr != ProcessArgs::SplitOk) {
emitError(QProcess::FailedToStart, qerr == ProcessArgs::BadQuoting emitError(QProcess::FailedToStart, qerr == ProcessArgs::BadQuoting
? tr("Quoting error in terminal command.") ? tr("Quoting error in terminal command.")
@@ -408,9 +382,9 @@ void TerminalProcess::start()
return; return;
} }
d->m_environment.unset(QLatin1String("TERM")); m_setup->m_environment.unset(QLatin1String("TERM"));
const QStringList env = d->m_environment.toStringList(); const QStringList env = m_setup->m_environment.toStringList();
if (!env.isEmpty()) { if (!env.isEmpty()) {
d->m_tempFile = new QTemporaryFile(); d->m_tempFile = new QTemporaryFile();
if (!d->m_tempFile->open()) { if (!d->m_tempFile->open()) {
@@ -434,10 +408,10 @@ void TerminalProcess::start()
QStringList allArgs = terminalArgs.toUnixArgs(); QStringList allArgs = terminalArgs.toUnixArgs();
allArgs << stubPath allArgs << stubPath
<< modeOption(d->m_terminalMode) << modeOption(m_setup->m_terminalMode)
<< d->m_stubServer.fullServerName() << d->m_stubServer.fullServerName()
<< msgPromptToClose() << msgPromptToClose()
<< d->m_workingDir.path() << m_setup->m_workingDirectory.path()
<< (d->m_tempFile ? d->m_tempFile->fileName() : QString()) << (d->m_tempFile ? d->m_tempFile->fileName() : QString())
<< QString::number(getpid()) << QString::number(getpid())
<< pcmd << pcmd
@@ -446,8 +420,9 @@ void TerminalProcess::start()
if (terminal.needsQuotes) if (terminal.needsQuotes)
allArgs = QStringList { ProcessArgs::joinArgs(allArgs) }; allArgs = QStringList { ProcessArgs::joinArgs(allArgs) };
d->m_process.setEnvironment(d->m_environment); d->m_process.setEnvironment(m_setup->m_environment);
d->m_process.setCommand({FilePath::fromString(terminal.command), allArgs}); d->m_process.setCommand({FilePath::fromString(terminal.command), allArgs});
d->m_process.setProcessImpl(m_setup->m_processImpl);
d->m_process.start(); d->m_process.start();
if (!d->m_process.waitForStarted()) { if (!d->m_process.waitForStarted()) {
const QString msg = tr("Cannot start the terminal emulator \"%1\", change the setting in the " const QString msg = tr("Cannot start the terminal emulator \"%1\", change the setting in the "
@@ -456,14 +431,14 @@ void TerminalProcess::start()
return; return;
} }
d->m_stubConnectTimer = new QTimer(this); d->m_stubConnectTimer = new QTimer(this);
connect(d->m_stubConnectTimer, &QTimer::timeout, this, &TerminalProcess::stopProcess); connect(d->m_stubConnectTimer, &QTimer::timeout, this, &TerminalImpl::stopProcess);
d->m_stubConnectTimer->setSingleShot(true); d->m_stubConnectTimer->setSingleShot(true);
d->m_stubConnectTimer->start(10000); d->m_stubConnectTimer->start(10000);
#endif #endif
} }
void TerminalProcess::cleanupAfterStartFailure(const QString &errorMessage) void TerminalImpl::cleanupAfterStartFailure(const QString &errorMessage)
{ {
stubServerShutdown(); stubServerShutdown();
emitError(QProcess::FailedToStart, errorMessage); emitError(QProcess::FailedToStart, errorMessage);
@@ -471,7 +446,7 @@ void TerminalProcess::cleanupAfterStartFailure(const QString &errorMessage)
d->m_tempFile = nullptr; d->m_tempFile = nullptr;
} }
void TerminalProcess::finish(int exitCode, QProcess::ExitStatus exitStatus) void TerminalImpl::finish(int exitCode, QProcess::ExitStatus exitStatus)
{ {
d->m_processId = 0; d->m_processId = 0;
d->m_exitCode = exitCode; d->m_exitCode = exitCode;
@@ -479,7 +454,7 @@ void TerminalProcess::finish(int exitCode, QProcess::ExitStatus exitStatus)
emit finished(); emit finished();
} }
void TerminalProcess::kickoffProcess() void TerminalImpl::kickoffProcess()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Not used. // Not used.
@@ -491,7 +466,7 @@ void TerminalProcess::kickoffProcess()
#endif #endif
} }
void TerminalProcess::interrupt() void TerminalImpl::interrupt()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// Not used. // Not used.
@@ -503,7 +478,7 @@ void TerminalProcess::interrupt()
#endif #endif
} }
void TerminalProcess::killProcess() void TerminalImpl::killProcess()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (d->m_hInferior != NULL) { if (d->m_hInferior != NULL) {
@@ -519,7 +494,7 @@ void TerminalProcess::killProcess()
d->m_processId = 0; d->m_processId = 0;
} }
void TerminalProcess::killStub() void TerminalImpl::killStub()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (d->m_pid) { if (d->m_pid) {
@@ -536,7 +511,7 @@ void TerminalProcess::killStub()
#endif #endif
} }
void TerminalProcess::stopProcess() void TerminalImpl::stopProcess()
{ {
killProcess(); killProcess();
killStub(); killStub();
@@ -549,7 +524,7 @@ void TerminalProcess::stopProcess()
} }
} }
bool TerminalProcess::isRunning() const bool TerminalImpl::isRunning() const
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return d->m_pid != nullptr; return d->m_pid != nullptr;
@@ -559,7 +534,7 @@ bool TerminalProcess::isRunning() const
#endif #endif
} }
QProcess::ProcessState TerminalProcess::state() const QProcess::ProcessState TerminalImpl::state() const
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
return (d->m_pid != nullptr) ? QProcess::Running : QProcess::NotRunning; return (d->m_pid != nullptr) ? QProcess::Running : QProcess::NotRunning;
@@ -569,7 +544,7 @@ QProcess::ProcessState TerminalProcess::state() const
#endif #endif
} }
QString TerminalProcess::stubServerListen() QString TerminalImpl::stubServerListen()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (d->m_stubServer.listen(QString::fromLatin1("creator-%1-%2") if (d->m_stubServer.listen(QString::fromLatin1("creator-%1-%2")
@@ -604,7 +579,7 @@ QString TerminalProcess::stubServerListen()
#endif #endif
} }
void TerminalProcess::stubServerShutdown() void TerminalImpl::stubServerShutdown()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
delete d->m_stubSocket; delete d->m_stubSocket;
@@ -625,7 +600,7 @@ void TerminalProcess::stubServerShutdown()
#endif #endif
} }
void TerminalProcess::stubConnectionAvailable() void TerminalImpl::stubConnectionAvailable()
{ {
if (d->m_stubConnectTimer) { if (d->m_stubConnectTimer) {
delete d->m_stubConnectTimer; delete d->m_stubConnectTimer;
@@ -633,10 +608,10 @@ void TerminalProcess::stubConnectionAvailable()
} }
d->m_stubSocket = d->m_stubServer.nextPendingConnection(); d->m_stubSocket = d->m_stubServer.nextPendingConnection();
connect(d->m_stubSocket, &QIODevice::readyRead, this, &TerminalProcess::readStubOutput); connect(d->m_stubSocket, &QIODevice::readyRead, this, &TerminalImpl::readStubOutput);
if (HostOsInfo::isAnyUnixHost()) if (HostOsInfo::isAnyUnixHost())
connect(d->m_stubSocket, &QLocalSocket::disconnected, this, &TerminalProcess::stubExited); connect(d->m_stubSocket, &QLocalSocket::disconnected, this, &TerminalImpl::stubExited);
} }
static QString errorMsg(int code) static QString errorMsg(int code)
@@ -644,16 +619,18 @@ static QString errorMsg(int code)
return QString::fromLocal8Bit(strerror(code)); return QString::fromLocal8Bit(strerror(code));
} }
void TerminalProcess::readStubOutput() void TerminalImpl::readStubOutput()
{ {
while (d->m_stubSocket->canReadLine()) { while (d->m_stubSocket->canReadLine()) {
QByteArray out = d->m_stubSocket->readLine(); QByteArray out = d->m_stubSocket->readLine();
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
out.chop(2); // \r\n out.chop(2); // \r\n
if (out.startsWith("err:chdir ")) { if (out.startsWith("err:chdir ")) {
emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(d->m_workingDir, winErrorMessage(out.mid(10).toInt()))); emitError(QProcess::FailedToStart,
msgCannotChangeToWorkDir(m_setup->m_workingDirectory, winErrorMessage(out.mid(10).toInt())));
} else if (out.startsWith("err:exec ")) { } else if (out.startsWith("err:exec ")) {
emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toUserOutput(), winErrorMessage(out.mid(9).toInt()))); emitError(QProcess::FailedToStart,
msgCannotExecute(m_setup->m_commandLine.executable().toUserOutput(), winErrorMessage(out.mid(9).toInt())));
} else if (out.startsWith("thread ")) { // Windows only } else if (out.startsWith("thread ")) { // Windows only
d->m_appMainThreadId = out.mid(7).toLongLong(); d->m_appMainThreadId = out.mid(7).toLongLong();
} else if (out.startsWith("pid ")) { } else if (out.startsWith("pid ")) {
@@ -691,9 +668,11 @@ void TerminalProcess::readStubOutput()
#else #else
out.chop(1); // \n out.chop(1); // \n
if (out.startsWith("err:chdir ")) { if (out.startsWith("err:chdir ")) {
emitError(QProcess::FailedToStart, msgCannotChangeToWorkDir(d->m_workingDir, errorMsg(out.mid(10).toInt()))); emitError(QProcess::FailedToStart,
msgCannotChangeToWorkDir(m_setup->m_workingDirectory, errorMsg(out.mid(10).toInt())));
} else if (out.startsWith("err:exec ")) { } else if (out.startsWith("err:exec ")) {
emitError(QProcess::FailedToStart, msgCannotExecute(d->m_commandLine.executable().toString(), errorMsg(out.mid(9).toInt()))); emitError(QProcess::FailedToStart,
msgCannotExecute(m_setup->m_commandLine.executable().toString(), errorMsg(out.mid(9).toInt())));
} else if (out.startsWith("spid ")) { } else if (out.startsWith("spid ")) {
delete d->m_tempFile; delete d->m_tempFile;
d->m_tempFile = nullptr; d->m_tempFile = nullptr;
@@ -713,7 +692,7 @@ void TerminalProcess::readStubOutput()
} // while } // while
} }
void TerminalProcess::stubExited() void TerminalImpl::stubExited()
{ {
// The stub exit might get noticed before we read the pid for the kill on Windows // The stub exit might get noticed before we read the pid for the kill on Windows
// or the error status elsewhere. // or the error status elsewhere.
@@ -736,7 +715,7 @@ void TerminalProcess::stubExited()
#endif #endif
} }
void TerminalProcess::cleanupInferior() void TerminalImpl::cleanupInferior()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
delete d->inferiorFinishedNotifier; delete d->inferiorFinishedNotifier;
@@ -746,7 +725,7 @@ void TerminalProcess::cleanupInferior()
#endif #endif
} }
void TerminalProcess::cleanupStub() void TerminalImpl::cleanupStub()
{ {
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
stubServerShutdown(); stubServerShutdown();
@@ -761,42 +740,32 @@ void TerminalProcess::cleanupStub()
#endif #endif
} }
qint64 TerminalProcess::processId() const qint64 TerminalImpl::processId() const
{ {
return d->m_processId; return d->m_processId;
} }
int TerminalProcess::exitCode() const int TerminalImpl::exitCode() const
{ {
return d->m_exitCode; return d->m_exitCode;
} // This will be the signal number if exitStatus == CrashExit } // This will be the signal number if exitStatus == CrashExit
QProcess::ExitStatus TerminalProcess::exitStatus() const QProcess::ExitStatus TerminalImpl::exitStatus() const
{ {
return d->m_appStatus; return d->m_appStatus;
} }
void TerminalProcess::setWorkingDirectory(const FilePath &dir) QProcess::ProcessError TerminalImpl::error() const
{
d->m_workingDir = dir;
}
void TerminalProcess::setEnvironment(const Environment &env)
{
d->m_environment = env;
}
QProcess::ProcessError TerminalProcess::error() const
{ {
return d->m_error; return d->m_error;
} }
QString TerminalProcess::errorString() const QString TerminalImpl::errorString() const
{ {
return d->m_errorString; return d->m_errorString;
} }
void TerminalProcess::emitError(QProcess::ProcessError err, const QString &errorString) void TerminalImpl::emitError(QProcess::ProcessError err, const QString &errorString)
{ {
d->m_error = err; d->m_error = err;
d->m_errorString = errorString; d->m_errorString = errorString;

View File

@@ -26,6 +26,8 @@
#pragma once #pragma once
#include "processenums.h" #include "processenums.h"
#include "processinterface.h"
#include "qtcassert.h"
#include <QProcess> #include <QProcess>
@@ -37,46 +39,48 @@ class FilePath;
namespace Internal { namespace Internal {
class TerminalProcess : public QObject class TerminalImpl : public ProcessInterface
{ {
Q_OBJECT
public: public:
explicit TerminalProcess(QObject *parent); TerminalImpl();
~TerminalProcess() override; ~TerminalImpl() final;
void setProcessImpl(ProcessImpl processImpl); QByteArray readAllStandardOutput() final { QTC_CHECK(false); return {}; }
void setTerminalMode(TerminalMode mode); QByteArray readAllStandardError() final { QTC_CHECK(false); return {}; }
void setCommand(const CommandLine &command);
void setWorkingDirectory(const FilePath &dir);
void setEnvironment(const Environment &env);
QProcess::ProcessError error() const; qint64 write(const QByteArray &) final { QTC_CHECK(false); return -1; }
QString errorString() const; void setErrorString(const QString &) final { QTC_CHECK(false); }
void start(); void terminate() final { stopProcess(); }
void stopProcess(); void kill() final { stopProcess(); }
void close() final { stopProcess(); }
// intentionally no-op without an assert
bool waitForStarted(int) final { return false; }
bool waitForReadyRead(int) final { QTC_CHECK(false); return false; }
// intentionally no-op without an assert
bool waitForFinished(int) final { return false; }
QProcess::ProcessError error() const final;
QString errorString() const final;
void start() final;
QProcess::ProcessState state() const final;
qint64 processId() const final;
int exitCode() const final;
QProcess::ExitStatus exitStatus() const final;
void kickoffProcess() final; // only debugger terminal, only non-windows
void interrupt() final; // only debugger terminal, only non-windows
qint64 applicationMainThreadID() const final; // only debugger terminal, only windows (-1 otherwise)
private:
// OK, however, impl looks a bit different (!= NotRunning vs == Running). // OK, however, impl looks a bit different (!= NotRunning vs == Running).
// Most probably changing it into (== Running) should be OK. // Most probably changing it into (== Running) should be OK.
bool isRunning() const; bool isRunning() const;
QProcess::ProcessState state() const; void stopProcess();
qint64 processId() const;
int exitCode() const;
QProcess::ExitStatus exitStatus() const;
void setAbortOnMetaChars(bool abort); // used only in sshDeviceProcess
void kickoffProcess(); // only debugger terminal, only non-windows
void interrupt(); // only debugger terminal, only non-windows
qint64 applicationMainThreadID() const; // only debugger terminal, only windows (-1 otherwise)
signals:
void started();
void finished();
void errorOccurred(QProcess::ProcessError error);
private:
void stubConnectionAvailable(); void stubConnectionAvailable();
void readStubOutput(); void readStubOutput();
void stubExited(); void stubExited();