forked from qt-creator/qt-creator
Reuse ProcessHelper in process launcher
Handle lowPriority and unixTerminalDisabled inside process launcher. Change-Id: I7a8998e303da0e79186c1201fc6e1a76edb4e1b3 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
This commit is contained in:
@@ -59,13 +59,15 @@ StartProcessPacket::StartProcessPacket(quintptr token)
|
|||||||
void StartProcessPacket::doSerialize(QDataStream &stream) const
|
void StartProcessPacket::doSerialize(QDataStream &stream) const
|
||||||
{
|
{
|
||||||
stream << command << arguments << workingDir << env << processMode << writeData << channelMode
|
stream << command << arguments << workingDir << env << processMode << writeData << channelMode
|
||||||
<< standardInputFile << belowNormalPriority << nativeArguments;
|
<< standardInputFile << belowNormalPriority << nativeArguments << lowPriority
|
||||||
|
<< unixTerminalDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartProcessPacket::doDeserialize(QDataStream &stream)
|
void StartProcessPacket::doDeserialize(QDataStream &stream)
|
||||||
{
|
{
|
||||||
stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode
|
stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode
|
||||||
>> standardInputFile >> belowNormalPriority >> nativeArguments;
|
>> standardInputFile >> belowNormalPriority >> nativeArguments >> lowPriority
|
||||||
|
>> unixTerminalDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -117,6 +117,8 @@ public:
|
|||||||
QString standardInputFile;
|
QString standardInputFile;
|
||||||
bool belowNormalPriority = false;
|
bool belowNormalPriority = false;
|
||||||
QString nativeArguments;
|
QString nativeArguments;
|
||||||
|
bool lowPriority = false;
|
||||||
|
bool unixTerminalDisabled = false;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void doSerialize(QDataStream &stream) const override;
|
void doSerialize(QDataStream &stream) const override;
|
||||||
|
@@ -105,6 +105,8 @@ public:
|
|||||||
|
|
||||||
void setBelowNormalPriority() { m_belowNormalPriority = true; }
|
void setBelowNormalPriority() { m_belowNormalPriority = true; }
|
||||||
void setNativeArguments(const QString &arguments) { m_nativeArguments = arguments; }
|
void setNativeArguments(const QString &arguments) { m_nativeArguments = arguments; }
|
||||||
|
void setLowPriority() { m_lowPriority = true; }
|
||||||
|
void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void errorOccurred(QProcess::ProcessError error);
|
void errorOccurred(QProcess::ProcessError error);
|
||||||
@@ -187,6 +189,8 @@ private:
|
|||||||
|
|
||||||
bool m_belowNormalPriority = false;
|
bool m_belowNormalPriority = false;
|
||||||
QString m_nativeArguments;
|
QString m_nativeArguments;
|
||||||
|
bool m_lowPriority = false;
|
||||||
|
bool m_unixTerminalDisabled = false;
|
||||||
|
|
||||||
friend class LauncherSocket;
|
friend class LauncherSocket;
|
||||||
friend class CallerHandle;
|
friend class CallerHandle;
|
||||||
|
@@ -24,13 +24,13 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include "processutils.h"
|
#include "processutils.h"
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
#ifdef QTCREATOR_PCH_H
|
|
||||||
#define CALLBACK WINAPI
|
|
||||||
#endif
|
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
|
#else
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -86,4 +86,21 @@ void ProcessStartHandler::setNativeArguments(QProcess *process, const QString &a
|
|||||||
#endif // Q_OS_WIN
|
#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
|
} // namespace Utils
|
||||||
|
@@ -26,10 +26,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QIODevice>
|
#include <QIODevice>
|
||||||
|
#include <QProcess>
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
class QProcess;
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
@@ -54,6 +51,30 @@ private:
|
|||||||
QByteArray m_writeData;
|
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
|
} // namespace Utils
|
||||||
|
|
||||||
|
@@ -57,13 +57,8 @@
|
|||||||
#define CALLBACK WINAPI
|
#define CALLBACK WINAPI
|
||||||
#endif
|
#endif
|
||||||
#include <qt_windows.h>
|
#include <qt_windows.h>
|
||||||
#else
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
using namespace Utils::Internal;
|
using namespace Utils::Internal;
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -132,9 +127,10 @@ public:
|
|||||||
virtual bool waitForReadyRead(int msecs) = 0;
|
virtual bool waitForReadyRead(int msecs) = 0;
|
||||||
virtual bool waitForFinished(int msecs) = 0;
|
virtual bool waitForFinished(int msecs) = 0;
|
||||||
|
|
||||||
virtual void setLowPriority() = 0;
|
void setLowPriority() { m_lowPriority = true; }
|
||||||
virtual bool lowPriority() const = 0;
|
bool isLowPriority() const { return m_lowPriority; }
|
||||||
virtual void setDisableUnixTerminal() = 0;
|
void setUnixTerminalDisabled() { m_unixTerminalDisabled = true; }
|
||||||
|
bool isUnixTerminalDisabled() const { return m_unixTerminalDisabled; }
|
||||||
|
|
||||||
void setBelowNormalPriority() { m_belowNormalPriority = true; }
|
void setBelowNormalPriority() { m_belowNormalPriority = true; }
|
||||||
bool isBelowNormalPriority() const { return m_belowNormalPriority; }
|
bool isBelowNormalPriority() const { return m_belowNormalPriority; }
|
||||||
@@ -154,42 +150,8 @@ private:
|
|||||||
const ProcessMode m_processMode;
|
const ProcessMode m_processMode;
|
||||||
bool m_belowNormalPriority = false;
|
bool m_belowNormalPriority = false;
|
||||||
QString m_nativeArguments;
|
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_lowPriority = false;
|
||||||
bool m_disableUnixTerminal = false;
|
bool m_unixTerminalDisabled = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QProcessImpl : public ProcessInterface
|
class QProcessImpl : public ProcessInterface
|
||||||
@@ -223,6 +185,10 @@ public:
|
|||||||
if (isBelowNormalPriority())
|
if (isBelowNormalPriority())
|
||||||
m_processStartHandler.setBelowNormalPriority(&m_process);
|
m_processStartHandler.setBelowNormalPriority(&m_process);
|
||||||
m_processStartHandler.setNativeArguments(&m_process, nativeArguments());
|
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_process.start(program, arguments, m_processStartHandler.openMode());
|
||||||
m_processStartHandler.handleProcessStart(&m_process);
|
m_processStartHandler.handleProcessStart(&m_process);
|
||||||
}
|
}
|
||||||
@@ -262,13 +228,6 @@ public:
|
|||||||
bool waitForFinished(int msecs) override
|
bool waitForFinished(int msecs) override
|
||||||
{ return m_process.waitForFinished(msecs); }
|
{ 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:
|
private:
|
||||||
void handleStarted()
|
void handleStarted()
|
||||||
{
|
{
|
||||||
@@ -321,6 +280,10 @@ public:
|
|||||||
if (isBelowNormalPriority())
|
if (isBelowNormalPriority())
|
||||||
m_handle->setBelowNormalPriority();
|
m_handle->setBelowNormalPriority();
|
||||||
m_handle->setNativeArguments(nativeArguments());
|
m_handle->setNativeArguments(nativeArguments());
|
||||||
|
if (isLowPriority())
|
||||||
|
m_handle->setLowPriority();
|
||||||
|
if (isUnixTerminalDisabled())
|
||||||
|
m_handle->setUnixTerminalDisabled();
|
||||||
m_handle->start(program, arguments, writeData);
|
m_handle->start(program, arguments, writeData);
|
||||||
}
|
}
|
||||||
void terminate() override { cancel(); } // TODO: what are differences among terminate, kill and close?
|
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 waitForReadyRead(int msecs) override { return m_handle->waitForReadyRead(msecs); }
|
||||||
bool waitForFinished(int msecs) override { return m_handle->waitForFinished(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:
|
private:
|
||||||
typedef void (ProcessLauncherImpl::*PreSignal)(void);
|
typedef void (ProcessLauncherImpl::*PreSignal)(void);
|
||||||
|
|
||||||
@@ -610,12 +569,12 @@ void QtcProcess::start()
|
|||||||
if (d->m_commandLine.executable().osType() == OsTypeWindows) {
|
if (d->m_commandLine.executable().osType() == OsTypeWindows) {
|
||||||
QString args;
|
QString args;
|
||||||
if (d->m_useCtrlCStub) {
|
if (d->m_useCtrlCStub) {
|
||||||
if (d->m_process->lowPriority())
|
if (d->m_process->isLowPriority())
|
||||||
ProcessArgs::addArg(&args, "-nice");
|
ProcessArgs::addArg(&args, "-nice");
|
||||||
ProcessArgs::addArg(&args, QDir::toNativeSeparators(command));
|
ProcessArgs::addArg(&args, QDir::toNativeSeparators(command));
|
||||||
command = QCoreApplication::applicationDirPath()
|
command = QCoreApplication::applicationDirPath()
|
||||||
+ QLatin1String("/qtcreator_ctrlc_stub.exe");
|
+ QLatin1String("/qtcreator_ctrlc_stub.exe");
|
||||||
} else if (d->m_process->lowPriority()) {
|
} else if (d->m_process->isLowPriority()) {
|
||||||
d->m_process->setBelowNormalPriority();
|
d->m_process->setBelowNormalPriority();
|
||||||
}
|
}
|
||||||
ProcessArgs::addArgs(&args, arguments.toWindowsArgs());
|
ProcessArgs::addArgs(&args, arguments.toWindowsArgs());
|
||||||
@@ -687,7 +646,7 @@ void QtcProcess::setLowPriority()
|
|||||||
|
|
||||||
void QtcProcess::setDisableUnixTerminal()
|
void QtcProcess::setDisableUnixTerminal()
|
||||||
{
|
{
|
||||||
d->m_process->setDisableUnixTerminal();
|
d->m_process->setUnixTerminalDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtcProcess::setStandardInputFile(const QString &inputFile)
|
void QtcProcess::setStandardInputFile(const QString &inputFile)
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "launchersockethandler.h"
|
#include "launchersockethandler.h"
|
||||||
|
|
||||||
#include "launcherlogging.h"
|
#include "launcherlogging.h"
|
||||||
|
#include "processutils.h"
|
||||||
|
|
||||||
#include <QtCore/qcoreapplication.h>
|
#include <QtCore/qcoreapplication.h>
|
||||||
#include <QtCore/qprocess.h>
|
#include <QtCore/qprocess.h>
|
||||||
@@ -35,12 +36,12 @@
|
|||||||
namespace Utils {
|
namespace Utils {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class Process : public QProcess
|
class Process : public ProcessHelper
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
Process(quintptr token, QObject *parent = nullptr) :
|
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);
|
m_stopTimer->setSingleShot(true);
|
||||||
connect(m_stopTimer, &QTimer::timeout, this, &Process::cancel);
|
connect(m_stopTimer, &QTimer::timeout, this, &Process::cancel);
|
||||||
@@ -246,6 +247,10 @@ void LauncherSocketHandler::handleStartPacket()
|
|||||||
if (packet.belowNormalPriority)
|
if (packet.belowNormalPriority)
|
||||||
handler->setBelowNormalPriority(process);
|
handler->setBelowNormalPriority(process);
|
||||||
handler->setNativeArguments(process, packet.nativeArguments);
|
handler->setNativeArguments(process, packet.nativeArguments);
|
||||||
|
if (packet.lowPriority)
|
||||||
|
process->setLowPriority();
|
||||||
|
if (packet.unixTerminalDisabled)
|
||||||
|
process->setUnixTerminalDisabled();
|
||||||
process->start(packet.command, packet.arguments, handler->openMode());
|
process->start(packet.command, packet.arguments, handler->openMode());
|
||||||
handler->handleProcessStart(process);
|
handler->handleProcessStart(process);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user