summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qprocess_win.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io/qprocess_win.cpp')
-rw-r--r--src/corelib/io/qprocess_win.cpp123
1 files changed, 71 insertions, 52 deletions
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index 8c4e5b41b4..cb4b2f9f91 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -149,7 +149,26 @@ static void qt_create_pipe(Q_PIPE *pipe, bool isInputPipe)
}
// Wait until connection is in place.
- ConnectNamedPipe(hServer, NULL);
+ OVERLAPPED overlapped;
+ ZeroMemory(&overlapped, sizeof(overlapped));
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (ConnectNamedPipe(hServer, &overlapped) == 0) {
+ DWORD dwError = GetLastError();
+ switch (dwError) {
+ case ERROR_PIPE_CONNECTED:
+ break;
+ case ERROR_IO_PENDING:
+ WaitForSingleObject(overlapped.hEvent, INFINITE);
+ break;
+ default:
+ qErrnoWarning(dwError, "QProcess: ConnectNamedPipe failed.");
+ CloseHandle(overlapped.hEvent);
+ CloseHandle(hClient);
+ CloseHandle(hServer);
+ return;
+ }
+ }
+ CloseHandle(overlapped.hEvent);
if (isInputPipe) {
pipe[0] = hClient;
@@ -183,7 +202,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
&stderrChannel.pipe[1], 0, TRUE, DUPLICATE_SAME_ACCESS);
}
- if (channel.type == Channel::Normal) {
+ switch (channel.type) {
+ case Channel::Normal:
// we're piping this channel to our own process
if (&channel == &stdinChannel) {
if (inputChannelMode != QProcess::ForwardedInputChannel) {
@@ -223,9 +243,8 @@ bool QProcessPrivate::openChannel(Channel &channel)
channel.reader->startAsyncRead();
}
}
-
return true;
- } else if (channel.type == Channel::Redirect) {
+ case Channel::Redirect: {
// we're redirecting the channel to/from a file
SECURITY_ATTRIBUTES secAtt = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };
@@ -270,65 +289,65 @@ bool QProcessPrivate::openChannel(Channel &channel)
}
cleanup();
return false;
- } else {
+ }
+ case Channel::PipeSource: {
Q_ASSERT_X(channel.process, "QProcess::start", "Internal error");
+ // we are the source
+ Channel *source = &channel;
+ Channel *sink = &channel.process->stdinChannel;
+
+ if (source->pipe[1] != INVALID_Q_PIPE) {
+ // already constructed by the sink
+ // make it inheritable
+ HANDLE tmpHandle = source->pipe[1];
+ if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
+ GetCurrentProcess(), &source->pipe[1],
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ return false;
+ }
- Channel *source;
- Channel *sink;
+ CloseHandle(tmpHandle);
+ return true;
+ }
- if (channel.type == Channel::PipeSource) {
- // we are the source
- source = &channel;
- sink = &channel.process->stdinChannel;
+ Q_ASSERT(source == &stdoutChannel);
+ Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink);
- if (source->pipe[1] != INVALID_Q_PIPE) {
- // already constructed by the sink
- // make it inheritable
- HANDLE tmpHandle = source->pipe[1];
- if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
- GetCurrentProcess(), &source->pipe[1],
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- return false;
+ qt_create_pipe(source->pipe, /* in = */ false); // source is stdout
+ sink->pipe[0] = source->pipe[0];
+ source->pipe[0] = INVALID_Q_PIPE;
- CloseHandle(tmpHandle);
- return true;
+ return true;
+ }
+ case Channel::PipeSink: { // we are the sink;
+ Q_ASSERT_X(channel.process, "QProcess::start", "Internal error");
+ Channel *source = &channel.process->stdoutChannel;
+ Channel *sink = &channel;
+
+ if (sink->pipe[0] != INVALID_Q_PIPE) {
+ // already constructed by the source
+ // make it inheritable
+ HANDLE tmpHandle = sink->pipe[0];
+ if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
+ GetCurrentProcess(), &sink->pipe[0],
+ 0, TRUE, DUPLICATE_SAME_ACCESS)) {
+ return false;
}
- Q_ASSERT(source == &stdoutChannel);
- Q_ASSERT(sink->process == this && sink->type == Channel::PipeSink);
-
- qt_create_pipe(source->pipe, /* in = */ false); // source is stdout
- sink->pipe[0] = source->pipe[0];
- source->pipe[0] = INVALID_Q_PIPE;
-
+ CloseHandle(tmpHandle);
return true;
- } else {
- // we are the sink;
- source = &channel.process->stdoutChannel;
- sink = &channel;
-
- if (sink->pipe[0] != INVALID_Q_PIPE) {
- // already constructed by the source
- // make it inheritable
- HANDLE tmpHandle = sink->pipe[0];
- if (!DuplicateHandle(GetCurrentProcess(), tmpHandle,
- GetCurrentProcess(), &sink->pipe[0],
- 0, TRUE, DUPLICATE_SAME_ACCESS))
- return false;
-
- CloseHandle(tmpHandle);
- return true;
- }
- Q_ASSERT(sink == &stdinChannel);
- Q_ASSERT(source->process == this && source->type == Channel::PipeSource);
+ }
+ Q_ASSERT(sink == &stdinChannel);
+ Q_ASSERT(source->process == this && source->type == Channel::PipeSource);
- qt_create_pipe(sink->pipe, /* in = */ true); // sink is stdin
- source->pipe[1] = sink->pipe[1];
- sink->pipe[1] = INVALID_Q_PIPE;
+ qt_create_pipe(sink->pipe, /* in = */ true); // sink is stdin
+ source->pipe[1] = sink->pipe[1];
+ sink->pipe[1] = INVALID_Q_PIPE;
- return true;
- }
+ return true;
}
+ } // switch (channel.type)
+ return false;
}
void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])