summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qprocess_win.cpp
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2017-05-30 13:53:33 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2017-06-13 16:49:38 +0000
commit7ad55ca65f42351e231f31f7a9253ae6eaf1ebb3 (patch)
tree580e4f422f13456c5019449e342b664e917e3afd /src/corelib/io/qprocess_win.cpp
parent424d9e9e56314bae09a0dcbf09be0e3c0c9e0ac6 (diff)
Support standard channel redirection in QProcess::startDetached
[ChangeLog][QtCore][QProcess] Added support for standard channel redirection using setStandard{Input|Output|Error}File to QProcess::startDetached. Task-number: QTBUG-2058 Task-number: QTBUG-37656 Change-Id: Iafb9bd7899f752d0305e3410ad4dcb7ef598dc79 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qprocess_win.cpp')
-rw-r--r--src/corelib/io/qprocess_win.cpp62
1 files changed, 43 insertions, 19 deletions
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;
}