Refactor openMode/keepWriteChannelOpen/closeWriteChannel

Change-Id: I4090533875ce1da864b6f8554ce59dbc1392a142
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Jarek Kobus
2021-08-06 16:20:47 +02:00
parent 2b820cc42d
commit 25f585227f
15 changed files with 207 additions and 44 deletions

View File

@@ -123,6 +123,7 @@ add_qtc_library(Utils
portlist.cpp portlist.h portlist.cpp portlist.h
predicates.h predicates.h
processhandle.cpp processhandle.h processhandle.cpp processhandle.h
processutils.cpp processutils.h
progressindicator.cpp progressindicator.h progressindicator.cpp progressindicator.h
projectintropage.cpp projectintropage.h projectintropage.ui projectintropage.cpp projectintropage.h projectintropage.ui
proxyaction.cpp proxyaction.h proxyaction.cpp proxyaction.h

View File

@@ -58,12 +58,14 @@ StartProcessPacket::StartProcessPacket(quintptr token)
void StartProcessPacket::doSerialize(QDataStream &stream) const void StartProcessPacket::doSerialize(QDataStream &stream) const
{ {
stream << command << arguments << workingDir << env << openMode << channelMode << standardInputFile; stream << command << arguments << workingDir << env << processMode << writeData << channelMode
<< standardInputFile;
} }
void StartProcessPacket::doDeserialize(QDataStream &stream) void StartProcessPacket::doDeserialize(QDataStream &stream)
{ {
stream >> command >> arguments >> workingDir >> env >> openMode >> channelMode >> standardInputFile; stream >> command >> arguments >> workingDir >> env >> processMode >> writeData >> channelMode
>> standardInputFile;
} }

View File

@@ -25,6 +25,8 @@
#pragma once #pragma once
#include "processutils.h"
#include <QtCore/qdatastream.h> #include <QtCore/qdatastream.h>
#include <QtCore/qprocess.h> #include <QtCore/qprocess.h>
#include <QtCore/qstringlist.h> #include <QtCore/qstringlist.h>
@@ -109,7 +111,8 @@ public:
QStringList arguments; QStringList arguments;
QString workingDir; QString workingDir;
QStringList env; QStringList env;
QIODevice::OpenMode openMode = QIODevice::ReadWrite; ProcessMode processMode = ProcessMode::Reader;
QByteArray writeData;
QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels; QProcess::ProcessChannelMode channelMode = QProcess::SeparateChannels;
QString standardInputFile; QString standardInputFile;

View File

@@ -314,7 +314,7 @@ void LauncherHandle::cancel()
m_processState = QProcess::NotRunning; m_processState = QProcess::NotRunning;
} }
void LauncherHandle::start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode) void LauncherHandle::start(const QString &program, const QStringList &arguments, const QByteArray &writeData)
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
@@ -328,7 +328,7 @@ void LauncherHandle::start(const QString &program, const QStringList &arguments,
// TODO: check if state is not running // TODO: check if state is not running
// TODO: check if m_canceled is not true // TODO: check if m_canceled is not true
m_processState = QProcess::Starting; m_processState = QProcess::Starting;
m_openMode = mode; m_writeData = writeData;
if (LauncherInterface::socket()->isReady()) if (LauncherInterface::socket()->isReady())
doStart(); doStart();
} }
@@ -405,7 +405,8 @@ void LauncherHandle::doStart()
p.arguments = m_arguments; p.arguments = m_arguments;
p.env = m_environment.toStringList(); p.env = m_environment.toStringList();
p.workingDir = m_workingDirectory; p.workingDir = m_workingDirectory;
p.openMode = m_openMode; p.processMode = m_processMode;
p.writeData = m_writeData;
p.channelMode = m_channelMode; p.channelMode = m_channelMode;
p.standardInputFile = m_standardInputFile; p.standardInputFile = m_standardInputFile;
sendPacket(p); sendPacket(p);
@@ -427,13 +428,13 @@ void LauncherSocket::sendData(const QByteArray &data)
QMetaObject::invokeMethod(this, &LauncherSocket::handleRequests); QMetaObject::invokeMethod(this, &LauncherSocket::handleRequests);
} }
LauncherHandle *LauncherSocket::registerHandle(quintptr token) LauncherHandle *LauncherSocket::registerHandle(quintptr token, ProcessMode mode)
{ {
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
if (m_handles.contains(token)) if (m_handles.contains(token))
return nullptr; // TODO: issue a warning return nullptr; // TODO: issue a warning
LauncherHandle *handle = new LauncherHandle(token); LauncherHandle *handle = new LauncherHandle(token, mode);
handle->moveToThread(thread()); handle->moveToThread(thread());
// Call it after moving LauncherHandle to the launcher's thread. // Call it after moving LauncherHandle to the launcher's thread.
// Since this method is invoked from caller's thread, CallerHandle will live in caller's thread. // Since this method is invoked from caller's thread, CallerHandle will live in caller's thread.

View File

@@ -26,6 +26,7 @@
#pragma once #pragma once
#include "launcherpackets.h" #include "launcherpackets.h"
#include "processutils.h"
#include <QtCore/qobject.h> #include <QtCore/qobject.h>
@@ -82,12 +83,7 @@ public:
QString errorString() const { QMutexLocker locker(&m_mutex); return m_errorString; } QString errorString() const { QMutexLocker locker(&m_mutex); return m_errorString; }
void setErrorString(const QString &str) { QMutexLocker locker(&m_mutex); m_errorString = str; } void setErrorString(const QString &str) { QMutexLocker locker(&m_mutex); m_errorString = str; }
// Called from other thread. Create a temp object receiver which lives in caller's thread. void start(const QString &program, const QStringList &arguments, const QByteArray &writeData);
// Add started and finished signals to it and post a flush to it.
// When we are in waitForSignal() which is called from the same thread,
// we may flush the signal queue and emit these signals immediately.
// Who should remove this object? deleteLater()?
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode);
qint64 write(const QByteArray &data); qint64 write(const QByteArray &data);
@@ -131,7 +127,7 @@ private:
void slotFinished(); void slotFinished();
// called from this thread // called from this thread
LauncherHandle(quintptr token) : m_token(token) {} LauncherHandle(quintptr token, ProcessMode mode) : m_token(token), m_processMode(mode) {}
void createCallerHandle(); void createCallerHandle();
void destroyCallerHandle(); void destroyCallerHandle();
@@ -161,6 +157,7 @@ private:
mutable QMutex m_mutex; mutable QMutex m_mutex;
QWaitCondition m_waitCondition; QWaitCondition m_waitCondition;
const quintptr m_token; const quintptr m_token;
const ProcessMode m_processMode;
SignalType m_waitingFor = SignalType::NoSignal; SignalType m_waitingFor = SignalType::NoSignal;
QProcess::ProcessState m_processState = QProcess::NotRunning; QProcess::ProcessState m_processState = QProcess::NotRunning;
@@ -178,7 +175,7 @@ private:
QStringList m_arguments; QStringList m_arguments;
QProcessEnvironment m_environment; QProcessEnvironment m_environment;
QString m_workingDirectory; QString m_workingDirectory;
QIODevice::OpenMode m_openMode = QIODevice::ReadWrite; QByteArray m_writeData;
QProcess::ProcessChannelMode m_channelMode = QProcess::SeparateChannels; QProcess::ProcessChannelMode m_channelMode = QProcess::SeparateChannels;
QString m_standardInputFile; QString m_standardInputFile;
@@ -196,7 +193,7 @@ public:
bool isReady() const { return m_socket.load(); } bool isReady() const { return m_socket.load(); }
void sendData(const QByteArray &data); void sendData(const QByteArray &data);
LauncherHandle *registerHandle(quintptr token); LauncherHandle *registerHandle(quintptr token, ProcessMode mode);
void unregisterHandle(quintptr token); void unregisterHandle(quintptr token);
signals: signals:

View File

@@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#include "processutils.h"
#include <QProcess>
namespace Utils {
QIODevice::OpenMode ProcessStartHandler::openMode() const
{
if (m_processMode == ProcessMode::Writer)
return QIODevice::ReadWrite; // some writers also read data
if (m_writeData.isEmpty())
return QIODevice::ReadOnly; // only reading
return QIODevice::ReadWrite; // initial write and then reading (close the write channel)
}
void ProcessStartHandler::handleProcessStart(QProcess *process)
{
if (m_processMode == ProcessMode::Writer)
return;
if (m_writeData.isEmpty())
process->closeWriteChannel();
}
void ProcessStartHandler::handleProcessStarted(QProcess *process)
{
if (!m_writeData.isEmpty()) {
process->write(m_writeData);
m_writeData = {};
if (m_processMode == ProcessMode::Reader)
process->closeWriteChannel();
}
}
} // namespace Utils

View File

@@ -0,0 +1,58 @@
/****************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
****************************************************************************/
#pragma once
#include <QIODevice>
QT_BEGIN_NAMESPACE
class QProcess;
QT_END_NAMESPACE
namespace Utils {
enum class ProcessMode {
Reader, // This opens in ReadOnly mode if no write data or in ReadWrite mode otherwise,
// closes the write channel afterwards
Writer // This opens in ReadWrite mode and doesn't close the write channel
};
class ProcessStartHandler {
public:
void setProcessMode(ProcessMode mode) { m_processMode = mode; }
void setWriteData(const QByteArray &writeData) { m_writeData = writeData; }
QIODevice::OpenMode openMode() const;
void handleProcessStart(QProcess *process);
void handleProcessStarted(QProcess *process);
private:
ProcessMode m_processMode = ProcessMode::Reader;
QByteArray m_writeData;
};
} // namespace Utils
Q_DECLARE_METATYPE(Utils::ProcessMode);

View File

@@ -101,14 +101,17 @@ class ProcessInterface : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessInterface() : QObject() {} ProcessInterface(ProcessMode processMode)
: QObject()
, m_processMode(processMode) {}
virtual QByteArray readAllStandardOutput() = 0; virtual QByteArray readAllStandardOutput() = 0;
virtual QByteArray readAllStandardError() = 0; virtual QByteArray readAllStandardError() = 0;
virtual void setProcessEnvironment(const QProcessEnvironment &environment) = 0; virtual void setProcessEnvironment(const QProcessEnvironment &environment) = 0;
virtual void setWorkingDirectory(const QString &dir) = 0; virtual void setWorkingDirectory(const QString &dir) = 0;
virtual void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode) = 0; virtual void start(const QString &program, const QStringList &arguments,
const QByteArray &writeData) = 0;
virtual void terminate() = 0; virtual void terminate() = 0;
virtual void kill() = 0; virtual void kill() = 0;
virtual void close() = 0; virtual void close() = 0;
@@ -145,6 +148,11 @@ signals:
void errorOccurred(QProcess::ProcessError error); void errorOccurred(QProcess::ProcessError error);
void readyReadStandardOutput(); void readyReadStandardOutput();
void readyReadStandardError(); void readyReadStandardError();
protected:
ProcessMode processMode() const { return m_processMode; }
private:
const ProcessMode m_processMode;
}; };
class ProcessHelper : public QProcess class ProcessHelper : public QProcess
@@ -186,10 +194,10 @@ public:
class QProcessImpl : public ProcessInterface class QProcessImpl : public ProcessInterface
{ {
public: public:
QProcessImpl() : ProcessInterface() QProcessImpl(ProcessMode processMode) : ProcessInterface(processMode)
{ {
connect(&m_process, &QProcess::started, connect(&m_process, &QProcess::started,
this, &ProcessInterface::started); this, &QProcessImpl::handleStarted);
connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), connect(&m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
this, &ProcessInterface::finished); this, &ProcessInterface::finished);
connect(&m_process, &QProcess::errorOccurred, connect(&m_process, &QProcess::errorOccurred,
@@ -207,8 +215,13 @@ public:
{ m_process.setProcessEnvironment(environment); } { m_process.setProcessEnvironment(environment); }
void setWorkingDirectory(const QString &dir) override void setWorkingDirectory(const QString &dir) override
{ m_process.setWorkingDirectory(dir); } { m_process.setWorkingDirectory(dir); }
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode) override void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) override
{ m_process.start(program, arguments, mode); } {
m_processStartHandler.setProcessMode(processMode());
m_processStartHandler.setWriteData(writeData);
m_process.start(program, arguments, m_processStartHandler.openMode());
m_processStartHandler.handleProcessStart(&m_process);
}
void terminate() override void terminate() override
{ m_process.terminate(); } { m_process.terminate(); }
void kill() override void kill() override
@@ -262,7 +275,13 @@ public:
#endif #endif
private: private:
void handleStarted()
{
m_processStartHandler.handleProcessStarted(&m_process);
emit started();
}
ProcessHelper m_process; ProcessHelper m_process;
ProcessStartHandler m_processStartHandler;
}; };
static uint uniqueToken() static uint uniqueToken()
@@ -275,9 +294,10 @@ class ProcessLauncherImpl : public ProcessInterface
{ {
Q_OBJECT Q_OBJECT
public: public:
ProcessLauncherImpl() : ProcessInterface(), m_token(uniqueToken()) ProcessLauncherImpl(ProcessMode processMode)
: ProcessInterface(processMode), m_token(uniqueToken())
{ {
m_handle = LauncherInterface::socket()->registerHandle(token()); m_handle = LauncherInterface::socket()->registerHandle(token(), processMode);
connect(m_handle, &LauncherHandle::errorOccurred, connect(m_handle, &LauncherHandle::errorOccurred,
this, &ProcessInterface::errorOccurred); this, &ProcessInterface::errorOccurred);
connect(m_handle, &LauncherHandle::started, connect(m_handle, &LauncherHandle::started,
@@ -301,8 +321,8 @@ public:
void setProcessEnvironment(const QProcessEnvironment &environment) override void setProcessEnvironment(const QProcessEnvironment &environment) override
{ m_handle->setProcessEnvironment(environment); } { m_handle->setProcessEnvironment(environment); }
void setWorkingDirectory(const QString &dir) override { m_handle->setWorkingDirectory(dir); } void setWorkingDirectory(const QString &dir) override { m_handle->setWorkingDirectory(dir); }
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode) override void start(const QString &program, const QStringList &arguments, const QByteArray &writeData) override
{ m_handle->start(program, arguments, mode); } { 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?
void kill() override { cancel(); } // TODO: see above void kill() override { cancel(); } // TODO: see above
void close() override { cancel(); } // TODO: see above void close() override { cancel(); } // TODO: see above
@@ -355,18 +375,20 @@ void ProcessLauncherImpl::cancel()
m_handle->cancel(); m_handle->cancel();
} }
static ProcessInterface *newProcessInstance(QtcProcess::ProcessImpl processImpl) static ProcessInterface *newProcessInstance(QtcProcess::ProcessImpl processImpl, ProcessMode mode)
{ {
if (processImpl == QtcProcess::QProcessImpl) if (processImpl == QtcProcess::QProcessImpl)
return new QProcessImpl; return new QProcessImpl(mode);
return new ProcessLauncherImpl; return new ProcessLauncherImpl(mode);
} }
class QtcProcessPrivate : public QObject class QtcProcessPrivate : public QObject
{ {
public: public:
explicit QtcProcessPrivate(QtcProcess *parent, QtcProcess::ProcessImpl processImpl) explicit QtcProcessPrivate(QtcProcess *parent,
: q(parent), m_process(newProcessInstance(processImpl)) QtcProcess::ProcessImpl processImpl,
ProcessMode processMode)
: q(parent), m_process(newProcessInstance(processImpl, processMode)), m_processMode(processMode)
{ {
connect(m_process, &ProcessInterface::started, connect(m_process, &ProcessInterface::started,
q, &QtcProcess::started); q, &QtcProcess::started);
@@ -403,6 +425,7 @@ public:
QtcProcess *q; QtcProcess *q;
ProcessInterface *m_process; ProcessInterface *m_process;
const ProcessMode m_processMode;
CommandLine m_commandLine; CommandLine m_commandLine;
FilePath m_workingDirectory; FilePath m_workingDirectory;
Environment m_environment; Environment m_environment;
@@ -469,8 +492,8 @@ QtcProcess::Result QtcProcessPrivate::interpretExitCode(int exitCode)
\sa Utils::ProcessArgs \sa Utils::ProcessArgs
*/ */
QtcProcess::QtcProcess(ProcessImpl processImpl, QObject *parent) QtcProcess::QtcProcess(ProcessImpl processImpl, ProcessMode processMode, QObject *parent)
: QObject(parent), d(new QtcProcessPrivate(this, processImpl)) : QObject(parent), d(new QtcProcessPrivate(this, processImpl, processMode))
{ {
static int qProcessExitStatusMeta = qRegisterMetaType<QProcess::ExitStatus>(); static int qProcessExitStatusMeta = qRegisterMetaType<QProcess::ExitStatus>();
static int qProcessProcessErrorMeta = qRegisterMetaType<QProcess::ProcessError>(); static int qProcessProcessErrorMeta = qRegisterMetaType<QProcess::ProcessError>();
@@ -478,7 +501,11 @@ QtcProcess::QtcProcess(ProcessImpl processImpl, QObject *parent)
Q_UNUSED(qProcessProcessErrorMeta) Q_UNUSED(qProcessProcessErrorMeta)
} }
QtcProcess::QtcProcess(QObject *parent) : QtcProcess(QtcProcess::QProcessImpl, parent) {} QtcProcess::QtcProcess(ProcessMode processMode, QObject *parent)
: QtcProcess(QtcProcess::QProcessImpl, processMode, parent) {}
QtcProcess::QtcProcess(QObject *parent)
: QtcProcess(QtcProcess::QProcessImpl, ProcessMode::Reader, parent) {}
QtcProcess::~QtcProcess() QtcProcess::~QtcProcess()
{ {
@@ -615,7 +642,7 @@ void QtcProcess::start()
#endif #endif
// Note: Arguments set with setNativeArgs will be appended to the ones // Note: Arguments set with setNativeArgs will be appended to the ones
// passed with start() below. // passed with start() below.
d->m_process->start(command, QStringList(), d->m_openMode); d->m_process->start(command, QStringList(), d->m_writeData);
} else { } else {
if (!success) { if (!success) {
setErrorString(tr("Error in command line.")); setErrorString(tr("Error in command line."));
@@ -624,7 +651,7 @@ void QtcProcess::start()
emit errorOccurred(QProcess::UnknownError); emit errorOccurred(QProcess::UnknownError);
return; return;
} }
d->m_process->start(command, arguments.toUnixArgs(), d->m_openMode); d->m_process->start(command, arguments.toUnixArgs(), d->m_writeData);
} }
} }

View File

@@ -29,6 +29,7 @@
#include "environment.h" #include "environment.h"
#include "commandline.h" #include "commandline.h"
#include "processutils.h"
#include <QProcess> #include <QProcess>
#include <QTextCodec> #include <QTextCodec>
@@ -64,7 +65,8 @@ public:
ProcessLauncherImpl ProcessLauncherImpl
}; };
QtcProcess(ProcessImpl processImpl, QObject *parent = nullptr); QtcProcess(ProcessImpl processImpl, ProcessMode processMode, QObject *parent = nullptr);
QtcProcess(ProcessMode processMode, QObject *parent = nullptr);
QtcProcess(QObject *parent = nullptr); QtcProcess(QObject *parent = nullptr);
~QtcProcess(); ~QtcProcess();

View File

@@ -93,6 +93,7 @@ SOURCES += \
$$PWD/json.cpp \ $$PWD/json.cpp \
$$PWD/portlist.cpp \ $$PWD/portlist.cpp \
$$PWD/processhandle.cpp \ $$PWD/processhandle.cpp \
$$PWD/processutils.cpp \
$$PWD/appmainwindow.cpp \ $$PWD/appmainwindow.cpp \
$$PWD/basetreeview.cpp \ $$PWD/basetreeview.cpp \
$$PWD/qtcassert.cpp \ $$PWD/qtcassert.cpp \
@@ -230,6 +231,7 @@ HEADERS += \
$$PWD/runextensions.h \ $$PWD/runextensions.h \
$$PWD/portlist.h \ $$PWD/portlist.h \
$$PWD/processhandle.h \ $$PWD/processhandle.h \
$$PWD/processutils.h \
$$PWD/appmainwindow.h \ $$PWD/appmainwindow.h \
$$PWD/basetreeview.h \ $$PWD/basetreeview.h \
$$PWD/elfreader.h \ $$PWD/elfreader.h \

View File

@@ -220,6 +220,8 @@ Project {
"portlist.h", "portlist.h",
"processhandle.cpp", "processhandle.cpp",
"processhandle.h", "processhandle.h",
"processutils.cpp",
"processutils.h",
"progressindicator.cpp", "progressindicator.cpp",
"progressindicator.h", "progressindicator.h",
"projectintropage.cpp", "projectintropage.cpp",

View File

@@ -11,4 +11,6 @@ add_qtc_executable(qtcreator_processlauncher
processlauncher-main.cpp processlauncher-main.cpp
${UTILSDIR}/launcherpackets.cpp ${UTILSDIR}/launcherpackets.cpp
${UTILSDIR}/launcherpackets.h ${UTILSDIR}/launcherpackets.h
${UTILSDIR}/processutils.cpp
${UTILSDIR}/processutils.h
) )

View File

@@ -77,11 +77,13 @@ public:
} }
quintptr token() const { return m_token; } quintptr token() const { return m_token; }
ProcessStartHandler *processStartHandler() { return &m_processStartHandler; }
private: private:
const quintptr m_token; const quintptr m_token;
QTimer * const m_stopTimer; QTimer * const m_stopTimer;
enum class StopState { Inactive, Terminating, Killing } m_stopState = StopState::Inactive; enum class StopState { Inactive, Terminating, Killing } m_stopState = StopState::Inactive;
ProcessStartHandler m_processStartHandler;
}; };
LauncherSocketHandler::LauncherSocketHandler(QString serverPath, QObject *parent) LauncherSocketHandler::LauncherSocketHandler(QString serverPath, QObject *parent)
@@ -187,6 +189,7 @@ void LauncherSocketHandler::handleProcessStarted()
Process *proc = senderProcess(); Process *proc = senderProcess();
ProcessStartedPacket packet(proc->token()); ProcessStartedPacket packet(proc->token());
packet.processId = proc->processId(); packet.processId = proc->processId();
proc->processStartHandler()->handleProcessStarted(proc);
sendPacket(packet); sendPacket(packet);
} }
@@ -237,10 +240,11 @@ void LauncherSocketHandler::handleStartPacket()
process->setWorkingDirectory(packet.workingDir); process->setWorkingDirectory(packet.workingDir);
process->setProcessChannelMode(packet.channelMode); process->setProcessChannelMode(packet.channelMode);
process->setStandardInputFile(packet.standardInputFile); process->setStandardInputFile(packet.standardInputFile);
process->start(packet.command, packet.arguments, packet.openMode); ProcessStartHandler *handler = process->processStartHandler();
const bool shouldCloseWriteChannel = !(packet.openMode & QIODevice::WriteOnly); handler->setProcessMode(packet.processMode);
if (shouldCloseWriteChannel) handler->setWriteData(packet.writeData);
process->closeWriteChannel(); process->start(packet.command, packet.arguments, handler->openMode());
handler->handleProcessStart(process);
} }
void LauncherSocketHandler::handleWritePacket() void LauncherSocketHandler::handleWritePacket()

View File

@@ -12,10 +12,12 @@ INCLUDEPATH += $$UTILS_DIR
HEADERS += \ HEADERS += \
launcherlogging.h \ launcherlogging.h \
launchersockethandler.h \ launchersockethandler.h \
$$UTILS_DIR/launcherpackets.h $$UTILS_DIR/launcherpackets.h \
$$UTILS_DIR/processutils.h
SOURCES += \ SOURCES += \
launcherlogging.cpp \ launcherlogging.cpp \
launchersockethandler.cpp \ launchersockethandler.cpp \
processlauncher-main.cpp \ processlauncher-main.cpp \
$$UTILS_DIR/launcherpackets.cpp $$UTILS_DIR/launcherpackets.cpp \
$$UTILS_DIR/processutils.cpp

View File

@@ -23,6 +23,8 @@ QtcTool {
files: [ files: [
"launcherpackets.cpp", "launcherpackets.cpp",
"launcherpackets.h", "launcherpackets.h",
"processutils.cpp",
"processutils.h",
] ]
} }
} }