diff --git a/src/libs/utils/launcherpackets.cpp b/src/libs/utils/launcherpackets.cpp index cb0e221ad2a..92498b97f1b 100644 --- a/src/libs/utils/launcherpackets.cpp +++ b/src/libs/utils/launcherpackets.cpp @@ -59,13 +59,15 @@ StartProcessPacket::StartProcessPacket(quintptr token) void StartProcessPacket::doSerialize(QDataStream &stream) const { stream << command << arguments << workingDir << env << processMode << writeData << channelMode - << standardInputFile << belowNormalPriority << nativeArguments; + << standardInputFile << belowNormalPriority << nativeArguments << lowPriority + << unixTerminalDisabled; } void StartProcessPacket::doDeserialize(QDataStream &stream) { stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode - >> standardInputFile >> belowNormalPriority >> nativeArguments; + >> standardInputFile >> belowNormalPriority >> nativeArguments >> lowPriority + >> unixTerminalDisabled; } diff --git a/src/libs/utils/launcherpackets.h b/src/libs/utils/launcherpackets.h index 642cd6400df..60ef92cb2fb 100644 --- a/src/libs/utils/launcherpackets.h +++ b/src/libs/utils/launcherpackets.h @@ -117,6 +117,8 @@ public: QString standardInputFile; bool belowNormalPriority = false; QString nativeArguments; + bool lowPriority = false; + bool unixTerminalDisabled = false; private: void doSerialize(QDataStream &stream) const override; diff --git a/src/libs/utils/launchersocket.h b/src/libs/utils/launchersocket.h index 181c62b445f..67474d996cb 100644 --- a/src/libs/utils/launchersocket.h +++ b/src/libs/utils/launchersocket.h @@ -105,6 +105,8 @@ public: void setBelowNormalPriority() { m_belowNormalPriority = true; } void setNativeArguments(const QString &arguments) { m_nativeArguments = arguments; } + void setLowPriority() { m_lowPriority = true; } + void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; } signals: void errorOccurred(QProcess::ProcessError error); @@ -187,6 +189,8 @@ private: bool m_belowNormalPriority = false; QString m_nativeArguments; + bool m_lowPriority = false; + bool m_unixTerminalDisabled = false; friend class LauncherSocket; friend class CallerHandle; diff --git a/src/libs/utils/processutils.cpp b/src/libs/utils/processutils.cpp index cd88e53d4d6..f949c05f72c 100644 --- a/src/libs/utils/processutils.cpp +++ b/src/libs/utils/processutils.cpp @@ -24,13 +24,13 @@ ****************************************************************************/ #include "processutils.h" -#include #ifdef Q_OS_WIN -#ifdef QTCREATOR_PCH_H -#define CALLBACK WINAPI -#endif #include +#else +#include +#include +#include #endif namespace Utils { @@ -86,4 +86,21 @@ void ProcessStartHandler::setNativeArguments(QProcess *process, const QString &a #endif // Q_OS_WIN } + +void ProcessHelper::setupChildProcess_impl() +{ +#if defined Q_OS_UNIX + // nice value range is -20 to +19 where -20 is highest, 0 default and +19 is lowest + if (m_lowPriority) { + errno = 0; + if (::nice(5) == -1 && errno != 0) + perror("Failed to set nice value"); + } + + // Disable terminal by becoming a session leader. + if (m_unixTerminalDisabled) + setsid(); +#endif +} + } // namespace Utils diff --git a/src/libs/utils/processutils.h b/src/libs/utils/processutils.h index 27736afac4a..df176f1d959 100644 --- a/src/libs/utils/processutils.h +++ b/src/libs/utils/processutils.h @@ -26,10 +26,7 @@ #pragma once #include - -QT_BEGIN_NAMESPACE -class QProcess; -QT_END_NAMESPACE +#include namespace Utils { @@ -54,6 +51,30 @@ private: QByteArray m_writeData; }; +class ProcessHelper : public QProcess +{ +public: + ProcessHelper(QObject *parent = nullptr) : QProcess(parent) + { +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX) + setChildProcessModifier([this] { setupChildProcess_impl(); }); +#endif + } + +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + void setupChildProcess() override { setupChildProcess_impl(); } +#endif + + using QProcess::setErrorString; + + void setLowPriority() { m_lowPriority = true; } + void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; } + +private: + void setupChildProcess_impl(); + bool m_lowPriority = false; + bool m_unixTerminalDisabled = false; +}; } // namespace Utils diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 38e65e8e84c..9a6fa48e181 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -57,13 +57,8 @@ #define CALLBACK WINAPI #endif #include -#else -#include -#include -#include #endif - using namespace Utils::Internal; namespace Utils { @@ -132,9 +127,10 @@ public: virtual bool waitForReadyRead(int msecs) = 0; virtual bool waitForFinished(int msecs) = 0; - virtual void setLowPriority() = 0; - virtual bool lowPriority() const = 0; - virtual void setDisableUnixTerminal() = 0; + void setLowPriority() { m_lowPriority = true; } + bool isLowPriority() const { return m_lowPriority; } + void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; } + bool isUnixTerminalDisabled() const { return m_unixTerminalDisabled; } void setBelowNormalPriority() { m_belowNormalPriority = true; } bool isBelowNormalPriority() const { return m_belowNormalPriority; } @@ -154,42 +150,8 @@ private: const ProcessMode m_processMode; bool m_belowNormalPriority = false; QString m_nativeArguments; -}; - -class ProcessHelper : public QProcess -{ -public: - ProcessHelper() - { -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && defined(Q_OS_UNIX) - setChildProcessModifier([this] { setupChildProcess_impl(); }); -#endif - } - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - void setupChildProcess() override { setupChildProcess_impl(); } -#endif - - void setupChildProcess_impl() - { -#if defined Q_OS_UNIX - // nice value range is -20 to +19 where -20 is highest, 0 default and +19 is lowest - if (m_lowPriority) { - errno = 0; - if (::nice(5) == -1 && errno != 0) - perror("Failed to set nice value"); - } - - // Disable terminal by becoming a session leader. - if (m_disableUnixTerminal) - setsid(); -#endif - } - - using QProcess::setErrorString; - bool m_lowPriority = false; - bool m_disableUnixTerminal = false; + bool m_unixTerminalDisabled = false; }; class QProcessImpl : public ProcessInterface @@ -223,6 +185,10 @@ public: if (isBelowNormalPriority()) m_processStartHandler.setBelowNormalPriority(&m_process); m_processStartHandler.setNativeArguments(&m_process, nativeArguments()); + if (isLowPriority()) + m_process.setLowPriority(); + if (isUnixTerminalDisabled()) + m_process.setUnixTerminalDisabled(); m_process.start(program, arguments, m_processStartHandler.openMode()); m_processStartHandler.handleProcessStart(&m_process); } @@ -262,13 +228,6 @@ public: bool waitForFinished(int msecs) override { return m_process.waitForFinished(msecs); } - void setLowPriority() override - { m_process.m_lowPriority = true; } - bool lowPriority() const override - { return m_process.m_lowPriority; } - void setDisableUnixTerminal() override - { m_process.m_disableUnixTerminal = true; } - private: void handleStarted() { @@ -321,6 +280,10 @@ public: if (isBelowNormalPriority()) m_handle->setBelowNormalPriority(); m_handle->setNativeArguments(nativeArguments()); + if (isLowPriority()) + m_handle->setLowPriority(); + if (isUnixTerminalDisabled()) + m_handle->setUnixTerminalDisabled(); m_handle->start(program, arguments, writeData); } void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close? @@ -343,10 +306,6 @@ public: bool waitForReadyRead(int msecs) override { return m_handle->waitForReadyRead(msecs); } bool waitForFinished(int msecs) override { return m_handle->waitForFinished(msecs); } - void setLowPriority() override { QTC_CHECK(false); } - bool lowPriority() const override { QTC_CHECK(false); return false; } - void setDisableUnixTerminal() override { QTC_CHECK(false); } - private: typedef void (ProcessLauncherImpl::*PreSignal)(void); @@ -610,12 +569,12 @@ void QtcProcess::start() if (d->m_commandLine.executable().osType() == OsTypeWindows) { QString args; if (d->m_useCtrlCStub) { - if (d->m_process->lowPriority()) + if (d->m_process->isLowPriority()) ProcessArgs::addArg(&args, "-nice"); ProcessArgs::addArg(&args, QDir::toNativeSeparators(command)); command = QCoreApplication::applicationDirPath() + QLatin1String("/qtcreator_ctrlc_stub.exe"); - } else if (d->m_process->lowPriority()) { + } else if (d->m_process->isLowPriority()) { d->m_process->setBelowNormalPriority(); } ProcessArgs::addArgs(&args, arguments.toWindowsArgs()); @@ -687,7 +646,7 @@ void QtcProcess::setLowPriority() void QtcProcess::setDisableUnixTerminal() { - d->m_process->setDisableUnixTerminal(); + d->m_process->setUnixTerminalDisabled(); } void QtcProcess::setStandardInputFile(const QString &inputFile) diff --git a/src/tools/processlauncher/launchersockethandler.cpp b/src/tools/processlauncher/launchersockethandler.cpp index 14d394bbaa3..f495f42d5d7 100644 --- a/src/tools/processlauncher/launchersockethandler.cpp +++ b/src/tools/processlauncher/launchersockethandler.cpp @@ -26,6 +26,7 @@ #include "launchersockethandler.h" #include "launcherlogging.h" +#include "processutils.h" #include #include @@ -35,12 +36,12 @@ namespace Utils { namespace Internal { -class Process : public QProcess +class Process : public ProcessHelper { Q_OBJECT public: Process(quintptr token, QObject *parent = nullptr) : - QProcess(parent), m_token(token), m_stopTimer(new QTimer(this)) + ProcessHelper(parent), m_token(token), m_stopTimer(new QTimer(this)) { m_stopTimer->setSingleShot(true); connect(m_stopTimer, &QTimer::timeout, this, &Process::cancel); @@ -246,6 +247,10 @@ void LauncherSocketHandler::handleStartPacket() if (packet.belowNormalPriority) handler->setBelowNormalPriority(process); handler->setNativeArguments(process, packet.nativeArguments); + if (packet.lowPriority) + process->setLowPriority(); + if (packet.unixTerminalDisabled) + process->setUnixTerminalDisabled(); process->start(packet.command, packet.arguments, handler->openMode()); handler->handleProcessStart(process); }