summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorAlex Trotsenko <alex1973tr@gmail.com>2020-12-24 17:10:33 +0200
committerAlex Trotsenko <alex1973tr@gmail.com>2020-12-30 23:40:53 +0200
commit8be9fb66f7872dc1e7a6ad729459be66ee5a1540 (patch)
tree3285748a7a3ee97e19cf3b5613b6cf434c256405 /src/corelib
parentefb3d87700fc057db1e2374c7cf5717df6dc68b8 (diff)
QProcess/Win: do not needlessly duplicate std handles in startProcess()
The idea was to create descriptors with HANDLE_FLAG_INHERIT. However, this can be assumed to be already the case for std descriptors, and if it isn't, the user messed up, and we shouldn't try to work around it. This is consistent with what we already do in startDetached(). Change-Id: I8135c5e612c361e77a0442541f2d50cfbb5b4601 Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qprocess_p.h1
-rw-r--r--src/corelib/io/qprocess_win.cpp72
2 files changed, 35 insertions, 38 deletions
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index b8b56be4f9..023d69e8d5 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -357,6 +357,7 @@ public:
void waitForDeadChild();
#endif
#ifdef Q_OS_WIN
+ STARTUPINFOW createStartupInfo();
bool callCreateProcess(QProcess::CreateProcessArguments *cpargs);
bool drainOutputPipes();
void flushPipeWriter();
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index add5435b45..886c4e8587 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -178,15 +178,6 @@ static bool qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
return true;
}
-static bool duplicateStdWriteChannel(Q_PIPE *pipe, DWORD nStdHandle)
-{
- pipe[0] = INVALID_Q_PIPE;
- HANDLE hStdWriteChannel = GetStdHandle(nStdHandle);
- HANDLE hCurrentProcess = GetCurrentProcess();
- return DuplicateHandle(hCurrentProcess, hStdWriteChannel, hCurrentProcess,
- &pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS);
-}
-
/*
Create the pipes to a QProcessPrivate::Channel.
@@ -196,30 +187,21 @@ bool QProcessPrivate::openChannel(Channel &channel)
{
Q_Q(QProcess);
- if (&channel == &stderrChannel && processChannelMode == QProcess::MergedChannels) {
- return DuplicateHandle(GetCurrentProcess(), stdoutChannel.pipe[1], GetCurrentProcess(),
- &stderrChannel.pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS);
- }
+ if (&channel == &stderrChannel && processChannelMode == QProcess::MergedChannels)
+ return true;
switch (channel.type) {
case Channel::Normal: {
// we're piping this channel to our own process
if (&channel == &stdinChannel) {
- if (inputChannelMode == QProcess::ForwardedInputChannel) {
- channel.pipe[1] = INVALID_Q_PIPE;
- HANDLE hStdReadChannel = GetStdHandle(STD_INPUT_HANDLE);
- HANDLE hCurrentProcess = GetCurrentProcess();
- return DuplicateHandle(hCurrentProcess, hStdReadChannel, hCurrentProcess,
- &channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS);
- }
-
- return qt_create_pipe(channel.pipe, true);
+ return inputChannelMode == QProcess::ForwardedInputChannel
+ || qt_create_pipe(channel.pipe, true);
}
if (&channel == &stdoutChannel) {
if (processChannelMode == QProcess::ForwardedChannels
|| processChannelMode == QProcess::ForwardedOutputChannel) {
- return duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE);
+ return true;
}
if (!stdoutChannel.reader) {
@@ -229,7 +211,7 @@ bool QProcessPrivate::openChannel(Channel &channel)
} else /* if (&channel == &stderrChannel) */ {
if (processChannelMode == QProcess::ForwardedChannels
|| processChannelMode == QProcess::ForwardedErrorChannel) {
- return duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE);
+ return true;
}
if (!stderrChannel.reader) {
@@ -495,6 +477,33 @@ static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Map &e
return envlist;
}
+static Q_PIPE pipeOrStdHandle(Q_PIPE pipe, DWORD handleNumber)
+{
+ return pipe != INVALID_Q_PIPE ? pipe : GetStdHandle(handleNumber);
+}
+
+STARTUPINFOW QProcessPrivate::createStartupInfo()
+{
+ Q_PIPE stdinPipe = pipeOrStdHandle(stdinChannel.pipe[0], STD_INPUT_HANDLE);
+ Q_PIPE stdoutPipe = pipeOrStdHandle(stdoutChannel.pipe[1], STD_OUTPUT_HANDLE);
+ Q_PIPE stderrPipe = stderrChannel.pipe[1];
+ if (stderrPipe == INVALID_Q_PIPE) {
+ stderrPipe = (processChannelMode == QProcess::MergedChannels)
+ ? stdoutPipe
+ : GetStdHandle(STD_ERROR_HANDLE);
+ }
+
+ return STARTUPINFOW{
+ sizeof(STARTUPINFOW), 0, 0, 0,
+ (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
+ (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
+ 0, 0, 0,
+ STARTF_USESTDHANDLES,
+ 0, 0, 0,
+ stdinPipe, stdoutPipe, stderrPipe
+ };
+}
+
bool QProcessPrivate::callCreateProcess(QProcess::CreateProcessArguments *cpargs)
{
if (modifyCreateProcessArgs)
@@ -565,15 +574,7 @@ void QProcessPrivate::startProcess()
// create new console windows (behavior consistent with UNIX).
DWORD dwCreationFlags = (GetConsoleWindow() ? 0 : CREATE_NO_WINDOW);
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
- STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0,
- (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
- (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
- 0, 0, 0,
- STARTF_USESTDHANDLES,
- 0, 0, 0,
- stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1]
- };
-
+ STARTUPINFOW startupInfo = createStartupInfo();
const QString nativeWorkingDirectory = QDir::toNativeSeparators(workingDirectory);
QProcess::CreateProcessArguments cpargs = {
nullptr, reinterpret_cast<wchar_t *>(const_cast<ushort *>(args.utf16())),
@@ -908,11 +909,6 @@ static bool startDetachedUacPrompt(const QString &programIn, const QStringList &
return true;
}
-static Q_PIPE pipeOrStdHandle(Q_PIPE pipe, DWORD handleNumber)
-{
- return pipe != INVALID_Q_PIPE ? pipe : GetStdHandle(handleNumber);
-}
-
bool QProcessPrivate::startDetached(qint64 *pid)
{
static const DWORD errorElevationRequired = 740;