Skip to content

Instantly share code, notes, and snippets.

@igorzi
Created February 8, 2012 20:05
Show Gist options
  • Save igorzi/1772895 to your computer and use it in GitHub Desktop.
Save igorzi/1772895 to your computer and use it in GitHub Desktop.
From 8f7634cc77d8d1b49ba090f3c68baac7069af7ac Mon Sep 17 00:00:00 2001
From: Igor Zinkovsky <igorzi@microsoft.com>
Date: Wed, 8 Feb 2012 12:01:33 -0800
Subject: [PATCH] windows: allow client connections to half-duplex pipes
---
src/win/pipe.c | 68 ++++++++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/src/win/pipe.c b/src/win/pipe.c
index 5c20fe4..5ff4f9d 100644
--- a/src/win/pipe.c
+++ b/src/win/pipe.c
@@ -98,6 +98,58 @@ static void uv_pipe_connection_init(uv_pipe_t* handle) {
}
+static HANDLE connect_named_pipe(const wchar_t* name) {
+ HANDLE pipe_handle;
+
+ /*
+ * Assume that we have a duplex pipe first, so attempt to
+ * connect with GENERIC_READ | GENERIC_WRITE.
+ */
+ pipe_handle = CreateFileW(name,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (pipe_handle != INVALID_HANDLE_VALUE) {
+ return pipe_handle;
+ }
+
+ /*
+ * If the pipe is not duplex CreateFileW fails with
+ * ERROR_ACCESS_DENIED. In that case try to connect
+ * as a read-only or write-only.
+ */
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ pipe_handle = CreateFileW(name,
+ GENERIC_READ | FILE_WRITE_ATTRIBUTES,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+
+ if (pipe_handle != INVALID_HANDLE_VALUE) {
+ return pipe_handle;
+ }
+ }
+
+ if (GetLastError() == ERROR_ACCESS_DENIED) {
+ pipe_handle = CreateFileW(name,
+ GENERIC_WRITE | FILE_READ_ATTRIBUTES,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED,
+ NULL);
+ }
+
+ return pipe_handle;
+}
+
+
int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access,
char* name, size_t nameSize) {
HANDLE pipeHandle;
@@ -437,13 +489,7 @@ static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
/* We wait for the pipe to become available with WaitNamedPipe. */
while (WaitNamedPipeW(handle->name, 30000)) {
/* The pipe is now available, try to connect. */
- pipeHandle = CreateFileW(handle->name,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL);
+ pipeHandle = connect_named_pipe(handle->name);
if (pipeHandle != INVALID_HANDLE_VALUE) {
break;
@@ -492,13 +538,7 @@ void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
goto error;
}
- pipeHandle = CreateFileW(handle->name,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL);
+ pipeHandle = connect_named_pipe(handle->name);
if (pipeHandle == INVALID_HANDLE_VALUE) {
if (GetLastError() == ERROR_PIPE_BUSY) {
--
1.7.4.msysgit.0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment