diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/qprocess_unix.cpp | 26 | ||||
-rw-r--r-- | src/corelib/io/qprocess_win.cpp | 62 |
2 files changed, 69 insertions, 19 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 251f68c9b4..2b47f3e5b1 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -915,6 +915,17 @@ bool QProcessPrivate::startDetached(qint64 *pid) return false; } + if ((stdinChannel.type == Channel::Redirect && !openChannel(stdinChannel)) + || (stdoutChannel.type == Channel::Redirect && !openChannel(stdoutChannel)) + || (stderrChannel.type == Channel::Redirect && !openChannel(stderrChannel))) { + closeChannel(&stdinChannel); + closeChannel(&stdoutChannel); + closeChannel(&stderrChannel); + qt_safe_close(startedPipe[0]); + qt_safe_close(startedPipe[1]); + return false; + } + pid_t childPid = fork(); if (childPid == 0) { struct sigaction noaction; @@ -931,6 +942,18 @@ bool QProcessPrivate::startDetached(qint64 *pid) if (doubleForkPid == 0) { qt_safe_close(pidPipe[1]); + // copy the stdin socket if asked to (without closing on exec) + if (inputChannelMode != QProcess::ForwardedInputChannel) + qt_safe_dup2(stdinChannel.pipe[0], STDIN_FILENO, 0); + + // copy the stdout and stderr if asked to + if (processChannelMode != QProcess::ForwardedChannels) { + if (processChannelMode != QProcess::ForwardedOutputChannel) + qt_safe_dup2(stdoutChannel.pipe[1], STDOUT_FILENO, 0); + if (processChannelMode != QProcess::ForwardedErrorChannel) + qt_safe_dup2(stderrChannel.pipe[1], STDERR_FILENO, 0); + } + if (!encodedWorkingDirectory.isEmpty()) { if (QT_CHDIR(encodedWorkingDirectory.constData()) == -1) qWarning("QProcessPrivate::startDetached: failed to chdir to %s", encodedWorkingDirectory.constData()); @@ -992,6 +1015,9 @@ bool QProcessPrivate::startDetached(qint64 *pid) ::_exit(1); } + closeChannel(&stdinChannel); + closeChannel(&stdoutChannel); + closeChannel(&stderrChannel); qt_safe_close(startedPipe[1]); qt_safe_close(pidPipe[1]); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index fc4d3b225d..0f6a61496d 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -462,10 +462,24 @@ bool QProcessPrivate::callCreateProcess(QProcess::CreateProcessArguments *cpargs { if (modifyCreateProcessArgs) modifyCreateProcessArgs(cpargs); - return CreateProcess(cpargs->applicationName, cpargs->arguments, cpargs->processAttributes, - cpargs->threadAttributes, cpargs->inheritHandles, cpargs->flags, - cpargs->environment, cpargs->currentDirectory, cpargs->startupInfo, - cpargs->processInformation); + bool success = CreateProcess(cpargs->applicationName, cpargs->arguments, + cpargs->processAttributes, cpargs->threadAttributes, + cpargs->inheritHandles, cpargs->flags, cpargs->environment, + cpargs->currentDirectory, cpargs->startupInfo, + cpargs->processInformation); + if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { + CloseHandle(stdinChannel.pipe[0]); + stdinChannel.pipe[0] = INVALID_Q_PIPE; + } + if (stdoutChannel.pipe[1] != INVALID_Q_PIPE) { + CloseHandle(stdoutChannel.pipe[1]); + stdoutChannel.pipe[1] = INVALID_Q_PIPE; + } + if (stderrChannel.pipe[1] != INVALID_Q_PIPE) { + CloseHandle(stderrChannel.pipe[1]); + stderrChannel.pipe[1] = INVALID_Q_PIPE; + } + return success; } void QProcessPrivate::startProcess() @@ -535,19 +549,6 @@ void QProcessPrivate::startProcess() errorString = QProcess::tr("Process failed to start: %1").arg(qt_error_string()); } - if (stdinChannel.pipe[0] != INVALID_Q_PIPE) { - CloseHandle(stdinChannel.pipe[0]); - stdinChannel.pipe[0] = INVALID_Q_PIPE; - } - if (stdoutChannel.pipe[1] != INVALID_Q_PIPE) { - CloseHandle(stdoutChannel.pipe[1]); - stdoutChannel.pipe[1] = INVALID_Q_PIPE; - } - if (stderrChannel.pipe[1] != INVALID_Q_PIPE) { - CloseHandle(stderrChannel.pipe[1]); - stderrChannel.pipe[1] = INVALID_Q_PIPE; - } - if (!success) { cleanup(); setErrorAndEmit(QProcess::FailedToStart, errorString); @@ -874,6 +875,15 @@ bool QProcessPrivate::startDetached(qint64 *pid) { static const DWORD errorElevationRequired = 740; + if ((stdinChannel.type == Channel::Redirect && !openChannel(stdinChannel)) + || (stdoutChannel.type == Channel::Redirect && !openChannel(stdoutChannel)) + || (stderrChannel.type == Channel::Redirect && !openChannel(stderrChannel))) { + closeChannel(&stdinChannel); + closeChannel(&stdoutChannel); + closeChannel(&stderrChannel); + return false; + } + QString args = qt_create_commandline(program, arguments, nativeArguments); bool success = false; PROCESS_INFORMATION pinfo; @@ -890,11 +900,18 @@ bool QProcessPrivate::startDetached(qint64 *pid) STARTUPINFOW startupInfo = { sizeof( STARTUPINFO ), 0, 0, 0, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, + STARTF_USESTDHANDLES, + 0, 0, 0, + stdinChannel.pipe[0], stdoutChannel.pipe[1], stderrChannel.pipe[1] }; + + const bool inheritHandles = stdinChannel.type == Channel::Redirect + || stdoutChannel.type == Channel::Redirect + || stderrChannel.type == Channel::Redirect; QProcess::CreateProcessArguments cpargs = { nullptr, reinterpret_cast<wchar_t *>(const_cast<ushort *>(args.utf16())), - nullptr, nullptr, false, dwCreationFlags, envPtr, + nullptr, nullptr, inheritHandles, dwCreationFlags, envPtr, workingDirectory.isEmpty() ? nullptr : reinterpret_cast<const wchar_t *>(workingDirectory.utf16()), &startupInfo, &pinfo @@ -909,10 +926,17 @@ bool QProcessPrivate::startDetached(qint64 *pid) } else if (GetLastError() == errorElevationRequired) { if (envPtr) qWarning("QProcess: custom environment will be ignored for detached elevated process."); + if (!stdinChannel.file.isEmpty() || !stdoutChannel.file.isEmpty() + || !stderrChannel.file.isEmpty()) { + qWarning("QProcess: file redirection is unsupported for detached elevated processes."); + } success = startDetachedUacPrompt(program, arguments, nativeArguments, workingDirectory, pid); } + closeChannel(&stdinChannel); + closeChannel(&stdoutChannel); + closeChannel(&stderrChannel); return success; } |