Rizin
unix-like reverse engineering framework and cli tools
pipe.c File Reference
#include <assert.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "handle-inl.h"
#include "internal.h"
#include "req-inl.h"
#include "stream-inl.h"
#include "uv-common.h"
#include "uv.h"
#include <aclapi.h>
#include <accctrl.h>

Go to the source code of this file.

Classes

struct  uv__ipc_xfer_queue_item_t
 
struct  uv__ipc_frame_header_t
 
struct  uv__coalesced_write_t
 

Enumerations

enum  {
  UV__IPC_FRAME_HAS_DATA = 0x01 , UV__IPC_FRAME_HAS_SOCKET_XFER = 0x02 , UV__IPC_FRAME_XFER_IS_TCP_CONNECTION = 0x04 , UV__IPC_FRAME_XFER_FLAGS = 0x06 ,
  UV__IPC_FRAME_VALID_FLAGS = 0x07
}
 

Functions

 STATIC_ASSERT (sizeof(uv__ipc_frame_header_t)==16)
 
 STATIC_ASSERT (sizeof(uv__ipc_socket_xfer_info_t)==632)
 
static void eof_timer_init (uv_pipe_t *pipe)
 
static void eof_timer_start (uv_pipe_t *pipe)
 
static void eof_timer_stop (uv_pipe_t *pipe)
 
static void eof_timer_cb (uv_timer_t *timer)
 
static void eof_timer_destroy (uv_pipe_t *pipe)
 
static void eof_timer_close_cb (uv_handle_t *handle)
 
static void uv_unique_pipe_name (char *ptr, char *name, size_t size)
 
int uv_pipe_init (uv_loop_t *loop, uv_pipe_t *handle, int ipc)
 
static void uv_pipe_connection_init (uv_pipe_t *handle)
 
static HANDLE open_named_pipe (const WCHAR *name, DWORD *duplex_flags)
 
static void close_pipe (uv_pipe_t *pipe)
 
int uv_stdio_pipe_server (uv_loop_t *loop, uv_pipe_t *handle, DWORD access, char *name, size_t nameSize)
 
static int uv_set_pipe_handle (uv_loop_t *loop, uv_pipe_t *handle, HANDLE pipeHandle, int fd, DWORD duplex_flags)
 
static int pipe_alloc_accept (uv_loop_t *loop, uv_pipe_t *handle, uv_pipe_accept_t *req, BOOL firstInstance)
 
static DWORD WINAPI pipe_shutdown_thread_proc (void *parameter)
 
void uv_pipe_endgame (uv_loop_t *loop, uv_pipe_t *handle)
 
void uv_pipe_pending_instances (uv_pipe_t *handle, int count)
 
int uv_pipe_bind (uv_pipe_t *handle, const char *name)
 
static DWORD WINAPI pipe_connect_thread_proc (void *parameter)
 
void uv_pipe_connect (uv_connect_t *req, uv_pipe_t *handle, const char *name, uv_connect_cb cb)
 
void uv__pipe_interrupt_read (uv_pipe_t *handle)
 
void uv__pipe_read_stop (uv_pipe_t *handle)
 
void uv_pipe_cleanup (uv_loop_t *loop, uv_pipe_t *handle)
 
void uv_pipe_close (uv_loop_t *loop, uv_pipe_t *handle)
 
static void uv_pipe_queue_accept (uv_loop_t *loop, uv_pipe_t *handle, uv_pipe_accept_t *req, BOOL firstInstance)
 
int uv_pipe_accept (uv_pipe_t *server, uv_stream_t *client)
 
int uv_pipe_listen (uv_pipe_t *handle, int backlog, uv_connection_cb cb)
 
static DWORD WINAPI uv_pipe_zero_readfile_thread_proc (void *arg)
 
static DWORD WINAPI uv_pipe_writefile_thread_proc (void *parameter)
 
static void CALLBACK post_completion_read_wait (void *context, BOOLEAN timed_out)
 
static void CALLBACK post_completion_write_wait (void *context, BOOLEAN timed_out)
 
static void uv_pipe_queue_read (uv_loop_t *loop, uv_pipe_t *handle)
 
int uv_pipe_read_start (uv_pipe_t *handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb)
 
static void uv_insert_non_overlapped_write_req (uv_pipe_t *handle, uv_write_t *req)
 
static uv_write_tuv_remove_non_overlapped_write_req (uv_pipe_t *handle)
 
static void uv_queue_non_overlapped_write (uv_pipe_t *handle)
 
static int uv__build_coalesced_write_req (uv_write_t *user_req, const uv_buf_t bufs[], size_t nbufs, uv_write_t **req_out, uv_buf_t *write_buf_out)
 
static int uv__pipe_write_data (uv_loop_t *loop, uv_write_t *req, uv_pipe_t *handle, const uv_buf_t bufs[], size_t nbufs, uv_write_cb cb, int copy_always)
 
static DWORD uv__pipe_get_ipc_remote_pid (uv_pipe_t *handle)
 
int uv__pipe_write_ipc (uv_loop_t *loop, uv_write_t *req, uv_pipe_t *handle, const uv_buf_t data_bufs[], size_t data_buf_count, uv_stream_t *send_handle, uv_write_cb cb)
 
int uv__pipe_write (uv_loop_t *loop, uv_write_t *req, uv_pipe_t *handle, const uv_buf_t bufs[], size_t nbufs, uv_stream_t *send_handle, uv_write_cb cb)
 
static void uv_pipe_read_eof (uv_loop_t *loop, uv_pipe_t *handle, uv_buf_t buf)
 
static void uv_pipe_read_error (uv_loop_t *loop, uv_pipe_t *handle, int error, uv_buf_t buf)
 
static void uv_pipe_read_error_or_eof (uv_loop_t *loop, uv_pipe_t *handle, int error, uv_buf_t buf)
 
static void uv__pipe_queue_ipc_xfer_info (uv_pipe_t *handle, uv__ipc_socket_xfer_type_t xfer_type, uv__ipc_socket_xfer_info_t *xfer_info)
 
static int uv__pipe_read_exactly (HANDLE h, void *buffer, DWORD count)
 
static DWORD uv__pipe_read_data (uv_loop_t *loop, uv_pipe_t *handle, DWORD suggested_bytes, DWORD max_bytes)
 
static DWORD uv__pipe_read_ipc (uv_loop_t *loop, uv_pipe_t *handle)
 
void uv_process_pipe_read_req (uv_loop_t *loop, uv_pipe_t *handle, uv_req_t *req)
 
void uv_process_pipe_write_req (uv_loop_t *loop, uv_pipe_t *handle, uv_write_t *req)
 
void uv_process_pipe_accept_req (uv_loop_t *loop, uv_pipe_t *handle, uv_req_t *raw_req)
 
void uv_process_pipe_connect_req (uv_loop_t *loop, uv_pipe_t *handle, uv_connect_t *req)
 
void uv_process_pipe_shutdown_req (uv_loop_t *loop, uv_pipe_t *handle, uv_shutdown_t *req)
 
int uv_pipe_open (uv_pipe_t *pipe, uv_file file)
 
static int uv__pipe_getname (const uv_pipe_t *handle, char *buffer, size_t *size)
 
int uv_pipe_pending_count (uv_pipe_t *handle)
 
int uv_pipe_getsockname (const uv_pipe_t *handle, char *buffer, size_t *size)
 
int uv_pipe_getpeername (const uv_pipe_t *handle, char *buffer, size_t *size)
 
uv_handle_type uv_pipe_pending_type (uv_pipe_t *handle)
 
int uv_pipe_chmod (uv_pipe_t *handle, int mode)
 

Variables

static char uv_zero_ [] = ""
 
static const uv_buf_t uv_null_buf_ = { 0, NULL }
 
static const int64_t eof_timeout = 50
 
static const int default_pending_pipe_instances = 4
 
static char pipe_prefix [] = "\\\\?\\pipe"
 
static const int pipe_prefix_len = sizeof(pipe_prefix) - 1
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
UV__IPC_FRAME_HAS_DATA 
UV__IPC_FRAME_HAS_SOCKET_XFER 
UV__IPC_FRAME_XFER_IS_TCP_CONNECTION 
UV__IPC_FRAME_XFER_FLAGS 
UV__IPC_FRAME_VALID_FLAGS 

Definition at line 63 of file pipe.c.

63  {
67  /* These are combinations of the flags above. */
70 };
@ UV__IPC_FRAME_VALID_FLAGS
Definition: pipe.c:69
@ UV__IPC_FRAME_HAS_SOCKET_XFER
Definition: pipe.c:65
@ UV__IPC_FRAME_XFER_FLAGS
Definition: pipe.c:68
@ UV__IPC_FRAME_XFER_IS_TCP_CONNECTION
Definition: pipe.c:66
@ UV__IPC_FRAME_HAS_DATA
Definition: pipe.c:64

Function Documentation

◆ close_pipe()

static void close_pipe ( uv_pipe_t pipe)
static

Definition at line 193 of file pipe.c.

193  {
194  assert(pipe->u.fd == -1 || pipe->u.fd > 2);
195  if (pipe->u.fd == -1)
196  CloseHandle(pipe->handle);
197  else
198  close(pipe->u.fd);
199 
200  pipe->u.fd = -1;
201  pipe->handle = INVALID_HANDLE_VALUE;
202 }
static static fork const void static count close
Definition: sflib.h:33
#define INVALID_HANDLE_VALUE
Definition: iowin32.c:21
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause const char static mode static sync const char const char static newpath const char static pathname pipe
Definition: sflib.h:73
assert(limit<=UINT32_MAX/2)

References assert(), close, INVALID_HANDLE_VALUE, and pipe.

Referenced by eof_timer_cb(), uv_pipe_cleanup(), and uv_process_pipe_shutdown_req().

◆ eof_timer_cb()

static void eof_timer_cb ( uv_timer_t timer)
static

Definition at line 2031 of file pipe.c.

2031  {
2032  uv_pipe_t* pipe = (uv_pipe_t*) timer->data;
2033  uv_loop_t* loop = timer->loop;
2034 
2035  assert(pipe->type == UV_NAMED_PIPE);
2036 
2037  /* This should always be true, since we start the timer only in
2038  * uv_pipe_queue_read after successfully calling ReadFile, or in
2039  * uv_process_pipe_shutdown_req if a read is pending, and we always
2040  * immediately stop the timer in uv_process_pipe_read_req. */
2042 
2043  /* If there are many packets coming off the iocp then the timer callback may
2044  * be called before the read request is coming off the queue. Therefore we
2045  * check here if the read request has completed but will be processed later.
2046  */
2047  if ((pipe->flags & UV_HANDLE_READ_PENDING) &&
2048  HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
2049  return;
2050  }
2051 
2052  /* Force both ends off the pipe. */
2053  close_pipe(pipe);
2054 
2055  /* Stop reading, so the pending read that is going to fail will not be
2056  * reported to the user. */
2058 
2059  /* Report the eof and update flags. This will get reported even if the user
2060  * stopped reading in the meantime. TODO: is that okay? */
2062 }
Definition: uv.h:1780
Definition: uv.h:767
uv_loop_t * loop
Definition: main.c:7
static void uv_pipe_read_eof(uv_loop_t *loop, uv_pipe_t *handle, uv_buf_t buf)
Definition: pipe.c:1596
static void close_pipe(uv_pipe_t *pipe)
Definition: pipe.c:193
static const uv_buf_t uv_null_buf_
Definition: pipe.c:42
@ UV_HANDLE_READ_PENDING
Definition: uv-common.h:94
UV_EXTERN int uv_read_stop(uv_stream_t *)
Definition: stream.c:1590

References assert(), close_pipe(), loop, pipe, UV_HANDLE_READ_PENDING, uv_null_buf_, uv_pipe_read_eof(), and uv_read_stop().

Referenced by eof_timer_start().

◆ eof_timer_close_cb()

static void eof_timer_close_cb ( uv_handle_t handle)
static

Definition at line 2075 of file pipe.c.

2075  {
2076  assert(handle->type == UV_TIMER);
2077  uv__free(handle);
2078 }
static mcore_handle handle
Definition: asm_mcore.c:8
void uv__free(void *ptr)
Definition: uv-common.c:81

References assert(), handle, and uv__free().

Referenced by eof_timer_destroy().

◆ eof_timer_destroy()

static void eof_timer_destroy ( uv_pipe_t pipe)
static

Definition at line 2065 of file pipe.c.

2065  {
2066  assert(pipe->flags & UV_HANDLE_CONNECTION);
2067 
2068  if (pipe->pipe.conn.eof_timer) {
2069  uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb);
2070  pipe->pipe.conn.eof_timer = NULL;
2071  }
2072 }
#define NULL
Definition: cris-opc.c:27
static void eof_timer_close_cb(uv_handle_t *handle)
Definition: pipe.c:2075
@ UV_HANDLE_CONNECTION
Definition: uv-common.h:83
UV_EXTERN void uv_close(uv_handle_t *handle, uv_close_cb close_cb)
Definition: core.c:108

References assert(), eof_timer_close_cb(), NULL, pipe, uv_close(), and UV_HANDLE_CONNECTION.

Referenced by uv_pipe_cleanup(), uv_pipe_read_eof(), and uv_pipe_read_error().

◆ eof_timer_init()

static void eof_timer_init ( uv_pipe_t pipe)
static

Definition at line 1998 of file pipe.c.

1998  {
1999  int r;
2000 
2001  assert(pipe->pipe.conn.eof_timer == NULL);
2002  assert(pipe->flags & UV_HANDLE_CONNECTION);
2003 
2004  pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer);
2005 
2006  r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer);
2007  assert(r == 0); /* timers can't fail */
2008  pipe->pipe.conn.eof_timer->data = pipe;
2009  uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer);
2010 }
#define r
Definition: crypto_rc6.c:12
Definition: uv.h:860
void * uv__malloc(size_t size)
Definition: uv-common.c:75
UV_EXTERN int uv_timer_init(uv_loop_t *, uv_timer_t *handle)
Definition: timer.c:58
UV_EXTERN void uv_unref(uv_handle_t *)
Definition: uv-common.c:552

References assert(), NULL, pipe, r, uv__malloc(), UV_HANDLE_CONNECTION, uv_timer_init(), and uv_unref().

Referenced by uv_process_pipe_shutdown_req().

◆ eof_timer_start()

static void eof_timer_start ( uv_pipe_t pipe)
static

Definition at line 2013 of file pipe.c.

2013  {
2014  assert(pipe->flags & UV_HANDLE_CONNECTION);
2015 
2016  if (pipe->pipe.conn.eof_timer != NULL) {
2017  uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0);
2018  }
2019 }
static void eof_timer_cb(uv_timer_t *timer)
Definition: pipe.c:2031
static const int64_t eof_timeout
Definition: pipe.c:46
UV_EXTERN int uv_timer_start(uv_timer_t *handle, uv_timer_cb cb, uint64_t timeout, uint64_t repeat)
Definition: timer.c:66

References assert(), eof_timeout, eof_timer_cb(), NULL, pipe, UV_HANDLE_CONNECTION, and uv_timer_start().

Referenced by uv_pipe_queue_read(), and uv_process_pipe_shutdown_req().

◆ eof_timer_stop()

static void eof_timer_stop ( uv_pipe_t pipe)
static

Definition at line 2022 of file pipe.c.

2022  {
2023  assert(pipe->flags & UV_HANDLE_CONNECTION);
2024 
2025  if (pipe->pipe.conn.eof_timer != NULL) {
2026  uv_timer_stop(pipe->pipe.conn.eof_timer);
2027  }
2028 }
UV_EXTERN int uv_timer_stop(uv_timer_t *handle)
Definition: timer.c:97

References assert(), NULL, pipe, UV_HANDLE_CONNECTION, and uv_timer_stop().

Referenced by uv_process_pipe_read_req().

◆ open_named_pipe()

static HANDLE open_named_pipe ( const WCHAR *  name,
DWORD duplex_flags 
)
static

Definition at line 135 of file pipe.c.

135  {
136  HANDLE pipeHandle;
137 
138  /*
139  * Assume that we have a duplex pipe first, so attempt to
140  * connect with GENERIC_READ | GENERIC_WRITE.
141  */
142  pipeHandle = CreateFileW(name,
143  GENERIC_READ | GENERIC_WRITE,
144  0,
145  NULL,
146  OPEN_EXISTING,
147  FILE_FLAG_OVERLAPPED,
148  NULL);
149  if (pipeHandle != INVALID_HANDLE_VALUE) {
150  *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
151  return pipeHandle;
152  }
153 
154  /*
155  * If the pipe is not duplex CreateFileW fails with
156  * ERROR_ACCESS_DENIED. In that case try to connect
157  * as a read-only or write-only.
158  */
159  if (GetLastError() == ERROR_ACCESS_DENIED) {
160  pipeHandle = CreateFileW(name,
161  GENERIC_READ | FILE_WRITE_ATTRIBUTES,
162  0,
163  NULL,
164  OPEN_EXISTING,
165  FILE_FLAG_OVERLAPPED,
166  NULL);
167 
168  if (pipeHandle != INVALID_HANDLE_VALUE) {
169  *duplex_flags = UV_HANDLE_READABLE;
170  return pipeHandle;
171  }
172  }
173 
174  if (GetLastError() == ERROR_ACCESS_DENIED) {
175  pipeHandle = CreateFileW(name,
176  GENERIC_WRITE | FILE_READ_ATTRIBUTES,
177  0,
178  NULL,
179  OPEN_EXISTING,
180  FILE_FLAG_OVERLAPPED,
181  NULL);
182 
183  if (pipeHandle != INVALID_HANDLE_VALUE) {
184  *duplex_flags = UV_HANDLE_WRITABLE;
185  return pipeHandle;
186  }
187  }
188 
189  return INVALID_HANDLE_VALUE;
190 }
Definition: z80asm.h:102
@ UV_HANDLE_WRITABLE
Definition: uv-common.h:93
@ UV_HANDLE_READABLE
Definition: uv-common.h:92
DWORD * HANDLE

References HANDLE, INVALID_HANDLE_VALUE, NULL, UV_HANDLE_READABLE, and UV_HANDLE_WRITABLE.

Referenced by pipe_connect_thread_proc(), and uv_pipe_connect().

◆ pipe_alloc_accept()

static int pipe_alloc_accept ( uv_loop_t loop,
uv_pipe_t handle,
uv_pipe_accept_t *  req,
BOOL  firstInstance 
)
static

Definition at line 329 of file pipe.c.

330  {
331  assert(req->pipeHandle == INVALID_HANDLE_VALUE);
332 
333  req->pipeHandle =
334  CreateNamedPipeW(handle->name,
335  PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC |
336  (firstInstance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
337  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
338  PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
339 
340  if (req->pipeHandle == INVALID_HANDLE_VALUE) {
341  return 0;
342  }
343 
344  /* Associate it with IOCP so we can get events. */
345  if (CreateIoCompletionPort(req->pipeHandle,
346  loop->iocp,
347  (ULONG_PTR) handle,
348  0) == NULL) {
349  uv_fatal_error(GetLastError(), "CreateIoCompletionPort");
350  }
351 
352  /* Stash a handle in the server object for use from places such as
353  * getsockname and chmod. As we transfer ownership of these to client
354  * objects, we'll allocate new ones here. */
355  handle->handle = req->pipeHandle;
356 
357  return 1;
358 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec req
Definition: sflib.h:128
void uv_fatal_error(const int errorno, const char *syscall)
Definition: error.c:35

References assert(), handle, INVALID_HANDLE_VALUE, loop, NULL, req, and uv_fatal_error().

Referenced by uv_pipe_bind(), and uv_pipe_queue_accept().

◆ pipe_connect_thread_proc()

static DWORD WINAPI pipe_connect_thread_proc ( void *  parameter)
static

Definition at line 604 of file pipe.c.

604  {
605  uv_loop_t* loop;
606  uv_pipe_t* handle;
607  uv_connect_t* req;
608  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
609  DWORD duplex_flags;
610 
611  req = (uv_connect_t*) parameter;
612  assert(req);
613  handle = (uv_pipe_t*) req->handle;
614  assert(handle);
615  loop = handle->loop;
616  assert(loop);
617 
618  /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. We wait
619  * for the pipe to become available with WaitNamedPipe. */
620  while (WaitNamedPipeW(handle->name, 30000)) {
621  /* The pipe is now available, try to connect. */
622  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
623  if (pipeHandle != INVALID_HANDLE_VALUE)
624  break;
625 
626  SwitchToThread();
627  }
628 
629  if (pipeHandle != INVALID_HANDLE_VALUE &&
630  !uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) {
632  } else {
633  SET_REQ_ERROR(req, GetLastError());
634  }
635 
636  /* Post completed */
638 
639  return 0;
640 }
#define SET_REQ_SUCCESS(req)
Definition: req-inl.h:40
#define POST_COMPLETION_FOR_REQ(loop, req)
Definition: req-inl.h:76
#define SET_REQ_ERROR(req, error)
Definition: req-inl.h:34
static int uv_set_pipe_handle(uv_loop_t *loop, uv_pipe_t *handle, HANDLE pipeHandle, int fd, DWORD duplex_flags)
Definition: pipe.c:254
static HANDLE open_named_pipe(const WCHAR *name, DWORD *duplex_flags)
Definition: pipe.c:135
DWORD

References assert(), DWORD, handle, HANDLE, INVALID_HANDLE_VALUE, loop, open_named_pipe(), POST_COMPLETION_FOR_REQ, req, SET_REQ_ERROR, SET_REQ_SUCCESS, and uv_set_pipe_handle().

Referenced by uv_pipe_connect().

◆ pipe_shutdown_thread_proc()

static DWORD WINAPI pipe_shutdown_thread_proc ( void *  parameter)
static

Definition at line 361 of file pipe.c.

361  {
362  uv_loop_t* loop;
363  uv_pipe_t* handle;
365 
366  req = (uv_shutdown_t*) parameter;
367  assert(req);
368  handle = (uv_pipe_t*) req->handle;
369  assert(handle);
370  loop = handle->loop;
371  assert(loop);
372 
373  FlushFileBuffers(handle->handle);
374 
375  /* Post completed */
377 
378  return 0;
379 }

References assert(), handle, loop, POST_COMPLETION_FOR_REQ, and req.

Referenced by uv_pipe_endgame().

◆ post_completion_read_wait()

static void CALLBACK post_completion_read_wait ( void *  context,
BOOLEAN  timed_out 
)
static

Definition at line 1074 of file pipe.c.

1074  {
1075  uv_read_t* req;
1076  uv_tcp_t* handle;
1077 
1078  req = (uv_read_t*) context;
1079  assert(req != NULL);
1080  handle = (uv_tcp_t*)req->data;
1081  assert(handle != NULL);
1082  assert(!timed_out);
1083 
1084  if (!PostQueuedCompletionStatus(handle->loop->iocp,
1085  req->u.io.overlapped.InternalHigh,
1086  0,
1087  &req->u.io.overlapped)) {
1088  uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
1089  }
1090 }
Definition: uv.h:547

References assert(), handle, NULL, req, and uv_fatal_error().

Referenced by uv_pipe_queue_read().

◆ post_completion_write_wait()

static void CALLBACK post_completion_write_wait ( void *  context,
BOOLEAN  timed_out 
)
static

Definition at line 1093 of file pipe.c.

1093  {
1094  uv_write_t* req;
1095  uv_tcp_t* handle;
1096 
1097  req = (uv_write_t*) context;
1098  assert(req != NULL);
1099  handle = (uv_tcp_t*)req->handle;
1100  assert(handle != NULL);
1101  assert(!timed_out);
1102 
1103  if (!PostQueuedCompletionStatus(handle->loop->iocp,
1104  req->u.io.overlapped.InternalHigh,
1105  0,
1106  &req->u.io.overlapped)) {
1107  uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
1108  }
1109 }
Definition: uv.h:525

References assert(), handle, NULL, req, and uv_fatal_error().

Referenced by uv__pipe_write_data().

◆ STATIC_ASSERT() [1/2]

STATIC_ASSERT ( sizeof(uv__ipc_frame_header_t = =16)

◆ STATIC_ASSERT() [2/2]

STATIC_ASSERT ( sizeof(uv__ipc_socket_xfer_info_t = =632)

◆ uv__build_coalesced_write_req()

static int uv__build_coalesced_write_req ( uv_write_t user_req,
const uv_buf_t  bufs[],
size_t  nbufs,
uv_write_t **  req_out,
uv_buf_t write_buf_out 
)
static

Definition at line 1252 of file pipe.c.

1256  {
1257  /* Pack into a single heap-allocated buffer:
1258  * (a) a uv_write_t structure where libuv stores the actual state.
1259  * (b) a pointer to the original uv_write_t.
1260  * (c) data from all `bufs` entries.
1261  */
1262  char* heap_buffer;
1263  size_t heap_buffer_length, heap_buffer_offset;
1264  uv__coalesced_write_t* coalesced_write_req; /* (a) + (b) */
1265  char* data_start; /* (c) */
1266  size_t data_length;
1267  unsigned int i;
1268 
1269  /* Compute combined size of all combined buffers from `bufs`. */
1270  data_length = 0;
1271  for (i = 0; i < nbufs; i++)
1272  data_length += bufs[i].len;
1273 
1274  /* The total combined size of data buffers should not exceed UINT32_MAX,
1275  * because WriteFile() won't accept buffers larger than that. */
1276  if (data_length > UINT32_MAX)
1277  return WSAENOBUFS; /* Maps to UV_ENOBUFS. */
1278 
1279  /* Compute heap buffer size. */
1280  heap_buffer_length = sizeof *coalesced_write_req + /* (a) + (b) */
1281  data_length; /* (c) */
1282 
1283  /* Allocate buffer. */
1284  heap_buffer = uv__malloc(heap_buffer_length);
1285  if (heap_buffer == NULL)
1286  return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
1287 
1288  /* Copy uv_write_t information to the buffer. */
1289  coalesced_write_req = (uv__coalesced_write_t*) heap_buffer;
1290  coalesced_write_req->req = *user_req; /* copy (a) */
1291  coalesced_write_req->req.coalesced = 1;
1292  coalesced_write_req->user_req = user_req; /* copy (b) */
1293  heap_buffer_offset = sizeof *coalesced_write_req; /* offset (a) + (b) */
1294 
1295  /* Copy data buffers to the heap buffer. */
1296  data_start = &heap_buffer[heap_buffer_offset];
1297  for (i = 0; i < nbufs; i++) {
1298  memcpy(&heap_buffer[heap_buffer_offset],
1299  bufs[i].base,
1300  bufs[i].len); /* copy (c) */
1301  heap_buffer_offset += bufs[i].len; /* offset (c) */
1302  }
1303  assert(heap_buffer_offset == heap_buffer_length);
1304 
1305  /* Set out arguments and return. */
1306  *req_out = &coalesced_write_req->req;
1307  *write_buf_out = uv_buf_init(data_start, (unsigned int) data_length);
1308  return 0;
1309 }
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define UINT32_MAX
uv_write_t * user_req
Definition: pipe.c:89
uv_write_t req
Definition: pipe.c:88
static char bufs[4][128]
Buffers for uint64_to_str() and uint64_to_nicestr()
Definition: util.c:18
UV_EXTERN uv_buf_t uv_buf_init(char *base, unsigned int len)
Definition: uv-common.c:157

References assert(), bufs, i, len, memcpy(), NULL, uv__coalesced_write_t::req, UINT32_MAX, uv__coalesced_write_t::user_req, uv__malloc(), and uv_buf_init().

Referenced by uv__pipe_write_data().

◆ uv__pipe_get_ipc_remote_pid()

static DWORD uv__pipe_get_ipc_remote_pid ( uv_pipe_t handle)
static

Definition at line 1463 of file pipe.c.

1463  {
1464  DWORD* pid = &handle->pipe.conn.ipc_remote_pid;
1465 
1466  /* If the both ends of the IPC pipe are owned by the same process,
1467  * the remote end pid may not yet be set. If so, do it here.
1468  * TODO: this is weird; it'd probably better to use a handshake. */
1469  if (*pid == 0)
1470  *pid = GetCurrentProcessId();
1471 
1472  return *pid;
1473 }
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64

References DWORD, handle, and pid.

Referenced by uv__pipe_write_ipc().

◆ uv__pipe_getname()

static int uv__pipe_getname ( const uv_pipe_t handle,
char *  buffer,
size_t size 
)
static

Definition at line 2154 of file pipe.c.

2154  {
2155  NTSTATUS nt_status;
2156  IO_STATUS_BLOCK io_status;
2157  FILE_NAME_INFORMATION tmp_name_info;
2158  FILE_NAME_INFORMATION* name_info;
2159  WCHAR* name_buf;
2160  unsigned int addrlen;
2161  unsigned int name_size;
2162  unsigned int name_len;
2163  int err;
2164 
2165  uv__once_init();
2166  name_info = NULL;
2167 
2168  if (handle->handle == INVALID_HANDLE_VALUE) {
2169  *size = 0;
2170  return UV_EINVAL;
2171  }
2172 
2173  /* NtQueryInformationFile will block if another thread is performing a
2174  * blocking operation on the queried handle. If the pipe handle is
2175  * synchronous, there may be a worker thread currently calling ReadFile() on
2176  * the pipe handle, which could cause a deadlock. To avoid this, interrupt
2177  * the read. */
2178  if (handle->flags & UV_HANDLE_CONNECTION &&
2180  uv__pipe_interrupt_read((uv_pipe_t*) handle); /* cast away const warning */
2181  }
2182 
2183  nt_status = pNtQueryInformationFile(handle->handle,
2184  &io_status,
2185  &tmp_name_info,
2186  sizeof tmp_name_info,
2188  if (nt_status == STATUS_BUFFER_OVERFLOW) {
2189  name_size = sizeof(*name_info) + tmp_name_info.FileNameLength;
2190  name_info = uv__malloc(name_size);
2191  if (!name_info) {
2192  *size = 0;
2193  err = UV_ENOMEM;
2194  goto cleanup;
2195  }
2196 
2197  nt_status = pNtQueryInformationFile(handle->handle,
2198  &io_status,
2199  name_info,
2200  name_size,
2202  }
2203 
2204  if (nt_status != STATUS_SUCCESS) {
2205  *size = 0;
2207  goto error;
2208  }
2209 
2210  if (!name_info) {
2211  /* the struct on stack was used */
2212  name_buf = tmp_name_info.FileName;
2213  name_len = tmp_name_info.FileNameLength;
2214  } else {
2215  name_buf = name_info->FileName;
2216  name_len = name_info->FileNameLength;
2217  }
2218 
2219  if (name_len == 0) {
2220  *size = 0;
2221  err = 0;
2222  goto error;
2223  }
2224 
2225  name_len /= sizeof(WCHAR);
2226 
2227  /* check how much space we need */
2228  addrlen = WideCharToMultiByte(CP_UTF8,
2229  0,
2230  name_buf,
2231  name_len,
2232  NULL,
2233  0,
2234  NULL,
2235  NULL);
2236  if (!addrlen) {
2237  *size = 0;
2238  err = uv_translate_sys_error(GetLastError());
2239  goto error;
2240  } else if (pipe_prefix_len + addrlen >= *size) {
2241  /* "\\\\.\\pipe" + name */
2242  *size = pipe_prefix_len + addrlen + 1;
2243  err = UV_ENOBUFS;
2244  goto error;
2245  }
2246 
2248  addrlen = WideCharToMultiByte(CP_UTF8,
2249  0,
2250  name_buf,
2251  name_len,
2254  NULL,
2255  NULL);
2256  if (!addrlen) {
2257  *size = 0;
2258  err = uv_translate_sys_error(GetLastError());
2259  goto error;
2260  }
2261 
2263  *size = addrlen;
2264  buffer[addrlen] = '\0';
2265 
2266  err = 0;
2267 
2268 error:
2269  uv__free(name_info);
2270 
2271 cleanup:
2272  return err;
2273 }
static bool err
Definition: armass.c:435
void cleanup(void)
Definition: enough.c:244
voidpf void uLong size
Definition: ioapi.h:138
static const void static count static fd struct stat static buf struct pollfd unsigned static timeout void static offset void static length char static len const struct iovec static count unsigned long static filedes static sched_yield static flags static oldfd static pause unsigned static seconds static protocol struct sockaddr addrlen
Definition: sflib.h:75
Definition: buffer.h:15
void uv__once_init(void)
Definition: core.c:329
static const int pipe_prefix_len
Definition: pipe.c:52
void uv__pipe_interrupt_read(uv_pipe_t *handle)
Definition: pipe.c:728
static char pipe_prefix[]
Definition: pipe.c:51
void error(const char *msg)
Definition: untgz.c:593
@ UV_HANDLE_NON_OVERLAPPED_PIPE
Definition: uv-common.h:118
UV_EXTERN int uv_translate_sys_error(int sys_errno)
Definition: core.c:1249
LONG NTSTATUS
Definition: win.h:198
sNtQueryInformationFile pNtQueryInformationFile
Definition: winapi.c:32
sRtlNtStatusToDosError pRtlNtStatusToDosError
Definition: winapi.c:30
@ FileNameInformation
Definition: winapi.h:4180
#define STATUS_BUFFER_OVERFLOW
Definition: winapi.h:520
#define STATUS_SUCCESS
Definition: winapi.h:68

References addrlen, cleanup(), err, error(), _FILE_NAME_INFORMATION::FileName, FileNameInformation, _FILE_NAME_INFORMATION::FileNameLength, handle, INVALID_HANDLE_VALUE, memcpy(), NULL, pipe_prefix, pipe_prefix_len, pNtQueryInformationFile, pRtlNtStatusToDosError, STATUS_BUFFER_OVERFLOW, STATUS_SUCCESS, uv__free(), uv__malloc(), uv__once_init(), uv__pipe_interrupt_read(), UV_HANDLE_CONNECTION, UV_HANDLE_NON_OVERLAPPED_PIPE, and uv_translate_sys_error().

Referenced by uv_pipe_getpeername(), and uv_pipe_getsockname().

◆ uv__pipe_interrupt_read()

void uv__pipe_interrupt_read ( uv_pipe_t handle)

Definition at line 728 of file pipe.c.

728  {
729  BOOL r;
730 
731  if (!(handle->flags & UV_HANDLE_READ_PENDING))
732  return; /* No pending reads. */
734  return; /* Already cancelled. */
735  if (handle->handle == INVALID_HANDLE_VALUE)
736  return; /* Pipe handle closed. */
737 
738  if (!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)) {
739  /* Cancel asynchronous read. */
740  r = CancelIoEx(handle->handle, &handle->read_req.u.io.overlapped);
741  assert(r || GetLastError() == ERROR_NOT_FOUND);
742 
743  } else {
744  /* Cancel synchronous read (which is happening in the thread pool). */
745  HANDLE thread;
746  volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle;
747 
748  EnterCriticalSection(&handle->pipe.conn.readfile_thread_lock);
749 
750  thread = *thread_ptr;
751  if (thread == NULL) {
752  /* The thread pool thread has not yet reached the point of blocking, we
753  * can pre-empt it by setting thread_handle to INVALID_HANDLE_VALUE. */
754  *thread_ptr = INVALID_HANDLE_VALUE;
755 
756  } else {
757  /* Spin until the thread has acknowledged (by setting the thread to
758  * INVALID_HANDLE_VALUE) that it is past the point of blocking. */
759  while (thread != INVALID_HANDLE_VALUE) {
760  r = CancelSynchronousIo(thread);
761  assert(r || GetLastError() == ERROR_NOT_FOUND);
762  SwitchToThread(); /* Yield thread. */
763  thread = *thread_ptr;
764  }
765  }
766 
767  LeaveCriticalSection(&handle->pipe.conn.readfile_thread_lock);
768  }
769 
770  /* Set flag to indicate that read has been cancelled. */
772 }
@ UV_HANDLE_CANCELLATION_PENDING
Definition: uv-common.h:99

References assert(), handle, HANDLE, INVALID_HANDLE_VALUE, NULL, r, UV_HANDLE_CANCELLATION_PENDING, UV_HANDLE_NON_OVERLAPPED_PIPE, and UV_HANDLE_READ_PENDING.

Referenced by uv__pipe_getname(), uv__pipe_read_stop(), and uv_pipe_cleanup().

◆ uv__pipe_queue_ipc_xfer_info()

static void uv__pipe_queue_ipc_xfer_info ( uv_pipe_t handle,
uv__ipc_socket_xfer_type_t  xfer_type,
uv__ipc_socket_xfer_info_t xfer_info 
)
static

Definition at line 1631 of file pipe.c.

1634  {
1636 
1637  item = (uv__ipc_xfer_queue_item_t*) uv__malloc(sizeof(*item));
1638  if (item == NULL)
1639  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
1640 
1641  item->xfer_type = xfer_type;
1642  item->xfer_info = *xfer_info;
1643 
1644  QUEUE_INSERT_TAIL(&handle->pipe.conn.ipc_xfer_queue, &item->member);
1645  handle->pipe.conn.ipc_xfer_queue_length++;
1646 }
#define QUEUE_INSERT_TAIL(h, q)
Definition: queue.h:92
uv__ipc_socket_xfer_info_t xfer_info
Definition: pipe.c:57
uv__ipc_socket_xfer_type_t xfer_type
Definition: pipe.c:56

References handle, uv__ipc_xfer_queue_item_t::member, NULL, QUEUE_INSERT_TAIL, uv__malloc(), uv_fatal_error(), uv__ipc_xfer_queue_item_t::xfer_info, and uv__ipc_xfer_queue_item_t::xfer_type.

Referenced by uv__pipe_read_ipc().

◆ uv__pipe_read_data()

static DWORD uv__pipe_read_data ( uv_loop_t loop,
uv_pipe_t handle,
DWORD  suggested_bytes,
DWORD  max_bytes 
)
static

Definition at line 1673 of file pipe.c.

1676  {
1677  DWORD bytes_read;
1678  uv_buf_t buf;
1679 
1680  /* Ask the user for a buffer to read data into. */
1681  buf = uv_buf_init(NULL, 0);
1682  handle->alloc_cb((uv_handle_t*) handle, suggested_bytes, &buf);
1683  if (buf.base == NULL || buf.len == 0) {
1684  handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf);
1685  return 0; /* Break out of read loop. */
1686  }
1687 
1688  /* Ensure we read at most the smaller of:
1689  * (a) the length of the user-allocated buffer.
1690  * (b) the maximum data length as specified by the `max_bytes` argument.
1691  */
1692  if (max_bytes > buf.len)
1693  max_bytes = buf.len;
1694 
1695  /* Read into the user buffer. */
1696  if (!ReadFile(handle->handle, buf.base, max_bytes, &bytes_read, NULL)) {
1697  uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf);
1698  return 0; /* Break out of read loop. */
1699  }
1700 
1701  /* Call the read callback. */
1702  handle->read_cb((uv_stream_t*) handle, bytes_read, &buf);
1703 
1704  return bytes_read;
1705 }
voidpf void * buf
Definition: ioapi.h:138
Definition: unix.h:123
static void uv_pipe_read_error_or_eof(uv_loop_t *loop, uv_pipe_t *handle, int error, uv_buf_t buf)
Definition: pipe.c:1621

References DWORD, handle, loop, NULL, uv_buf_init(), and uv_pipe_read_error_or_eof().

Referenced by uv__pipe_read_ipc(), and uv_process_pipe_read_req().

◆ uv__pipe_read_exactly()

static int uv__pipe_read_exactly ( HANDLE  h,
void *  buffer,
DWORD  count 
)
static

Definition at line 1652 of file pipe.c.

1652  {
1653  DWORD bytes_read, bytes_read_now;
1654 
1655  bytes_read = 0;
1656  while (bytes_read < count) {
1657  if (!ReadFile(h,
1658  (char*) buffer + bytes_read,
1659  count - bytes_read,
1660  &bytes_read_now,
1661  NULL)) {
1662  return GetLastError();
1663  }
1664 
1665  bytes_read += bytes_read_now;
1666  }
1667 
1668  assert(bytes_read == count);
1669  return 0;
1670 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
#define h(i)
Definition: sha256.c:48

References assert(), count, DWORD, h, and NULL.

Referenced by uv__pipe_read_ipc().

◆ uv__pipe_read_ipc()

static DWORD uv__pipe_read_ipc ( uv_loop_t loop,
uv_pipe_t handle 
)
static

Definition at line 1708 of file pipe.c.

1708  {
1709  uint32_t* data_remaining = &handle->pipe.conn.ipc_data_frame.payload_remaining;
1710  int err;
1711 
1712  if (*data_remaining > 0) {
1713  /* Read frame data payload. */
1714  DWORD bytes_read =
1715  uv__pipe_read_data(loop, handle, *data_remaining, *data_remaining);
1716  *data_remaining -= bytes_read;
1717  return bytes_read;
1718 
1719  } else {
1720  /* Start of a new IPC frame. */
1721  uv__ipc_frame_header_t frame_header;
1722  uint32_t xfer_flags;
1723  uv__ipc_socket_xfer_type_t xfer_type;
1724  uv__ipc_socket_xfer_info_t xfer_info;
1725 
1726  /* Read the IPC frame header. */
1728  handle->handle, &frame_header, sizeof frame_header);
1729  if (err)
1730  goto error;
1731 
1732  /* Validate that flags are valid. */
1733  if ((frame_header.flags & ~UV__IPC_FRAME_VALID_FLAGS) != 0)
1734  goto invalid;
1735  /* Validate that reserved2 is zero. */
1736  if (frame_header.reserved2 != 0)
1737  goto invalid;
1738 
1739  /* Parse xfer flags. */
1740  xfer_flags = frame_header.flags & UV__IPC_FRAME_XFER_FLAGS;
1741  if (xfer_flags & UV__IPC_FRAME_HAS_SOCKET_XFER) {
1742  /* Socket coming -- determine the type. */
1743  xfer_type = xfer_flags & UV__IPC_FRAME_XFER_IS_TCP_CONNECTION
1746  } else if (xfer_flags == 0) {
1747  /* No socket. */
1748  xfer_type = UV__IPC_SOCKET_XFER_NONE;
1749  } else {
1750  /* Invalid flags. */
1751  goto invalid;
1752  }
1753 
1754  /* Parse data frame information. */
1755  if (frame_header.flags & UV__IPC_FRAME_HAS_DATA) {
1756  *data_remaining = frame_header.data_length;
1757  } else if (frame_header.data_length != 0) {
1758  /* Data length greater than zero but data flag not set -- invalid. */
1759  goto invalid;
1760  }
1761 
1762  /* If no socket xfer info follows, return here. Data will be read in a
1763  * subsequent invocation of uv__pipe_read_ipc(). */
1764  if (xfer_type == UV__IPC_SOCKET_XFER_NONE)
1765  return sizeof frame_header; /* Number of bytes read. */
1766 
1767  /* Read transferred socket information. */
1768  err = uv__pipe_read_exactly(handle->handle, &xfer_info, sizeof xfer_info);
1769  if (err)
1770  goto error;
1771 
1772  /* Store the pending socket info. */
1773  uv__pipe_queue_ipc_xfer_info(handle, xfer_type, &xfer_info);
1774 
1775  /* Return number of bytes read. */
1776  return sizeof frame_header + sizeof xfer_info;
1777  }
1778 
1779 invalid:
1780  /* Invalid frame. */
1781  err = WSAECONNABORTED; /* Maps to UV_ECONNABORTED. */
1782 
1783 error:
1785  return 0; /* Break out of read loop. */
1786 }
unsigned int uint32_t
Definition: sftypes.h:29
uint32_t flags
Definition: pipe.c:75
uint32_t reserved2
Definition: pipe.c:78
uint32_t data_length
Definition: pipe.c:77
uv__ipc_socket_xfer_type_t
Definition: internal.h:64
@ UV__IPC_SOCKET_XFER_NONE
Definition: internal.h:65
@ UV__IPC_SOCKET_XFER_TCP_CONNECTION
Definition: internal.h:66
@ UV__IPC_SOCKET_XFER_TCP_SERVER
Definition: internal.h:67
static int uv__pipe_read_exactly(HANDLE h, void *buffer, DWORD count)
Definition: pipe.c:1652
static DWORD uv__pipe_read_data(uv_loop_t *loop, uv_pipe_t *handle, DWORD suggested_bytes, DWORD max_bytes)
Definition: pipe.c:1673
static void uv__pipe_queue_ipc_xfer_info(uv_pipe_t *handle, uv__ipc_socket_xfer_type_t xfer_type, uv__ipc_socket_xfer_info_t *xfer_info)
Definition: pipe.c:1631

References uv__ipc_frame_header_t::data_length, DWORD, err, error(), uv__ipc_frame_header_t::flags, handle, loop, uv__ipc_frame_header_t::reserved2, UV__IPC_FRAME_HAS_DATA, UV__IPC_FRAME_HAS_SOCKET_XFER, UV__IPC_FRAME_VALID_FLAGS, UV__IPC_FRAME_XFER_FLAGS, UV__IPC_FRAME_XFER_IS_TCP_CONNECTION, UV__IPC_SOCKET_XFER_NONE, UV__IPC_SOCKET_XFER_TCP_CONNECTION, UV__IPC_SOCKET_XFER_TCP_SERVER, uv__pipe_queue_ipc_xfer_info(), uv__pipe_read_data(), uv__pipe_read_exactly(), uv_null_buf_, and uv_pipe_read_error_or_eof().

Referenced by uv_process_pipe_read_req().

◆ uv__pipe_read_stop()

void uv__pipe_read_stop ( uv_pipe_t handle)

Definition at line 775 of file pipe.c.

775  {
776  handle->flags &= ~UV_HANDLE_READING;
778 
780 }
#define DECREASE_ACTIVE_COUNT(loop, handle)
Definition: handle-inl.h:32
@ UV_HANDLE_READING
Definition: uv-common.h:90

References DECREASE_ACTIVE_COUNT, handle, uv__pipe_interrupt_read(), and UV_HANDLE_READING.

Referenced by uv_read_stop().

◆ uv__pipe_write()

int uv__pipe_write ( uv_loop_t loop,
uv_write_t req,
uv_pipe_t handle,
const uv_buf_t  bufs[],
size_t  nbufs,
uv_stream_t send_handle,
uv_write_cb  cb 
)

Definition at line 1578 of file pipe.c.

1584  {
1585  if (handle->ipc) {
1586  /* IPC pipe write: use framing protocol. */
1587  return uv__pipe_write_ipc(loop, req, handle, bufs, nbufs, send_handle, cb);
1588  } else {
1589  /* Non-IPC pipe write: put data on the wire directly. */
1590  assert(send_handle == NULL);
1591  return uv__pipe_write_data(loop, req, handle, bufs, nbufs, cb, 0);
1592  }
1593 }
static int uv__pipe_write_data(uv_loop_t *loop, uv_write_t *req, uv_pipe_t *handle, const uv_buf_t bufs[], size_t nbufs, uv_write_cb cb, int copy_always)
Definition: pipe.c:1312
int uv__pipe_write_ipc(uv_loop_t *loop, uv_write_t *req, uv_pipe_t *handle, const uv_buf_t data_bufs[], size_t data_buf_count, uv_stream_t *send_handle, uv_write_cb cb)
Definition: pipe.c:1476
static const char * cb[]
Definition: z80_tab.h:176

References assert(), bufs, cb, handle, loop, NULL, req, uv__pipe_write_data(), and uv__pipe_write_ipc().

Referenced by uv_write(), and uv_write2().

◆ uv__pipe_write_data()

static int uv__pipe_write_data ( uv_loop_t loop,
uv_write_t req,
uv_pipe_t handle,
const uv_buf_t  bufs[],
size_t  nbufs,
uv_write_cb  cb,
int  copy_always 
)
static

Definition at line 1312 of file pipe.c.

1318  {
1319  int err;
1320  int result;
1321  uv_buf_t write_buf;
1322 
1323  assert(handle->handle != INVALID_HANDLE_VALUE);
1324 
1325  UV_REQ_INIT(req, UV_WRITE);
1326  req->handle = (uv_stream_t*) handle;
1327  req->send_handle = NULL;
1328  req->cb = cb;
1329  /* Private fields. */
1330  req->coalesced = 0;
1331  req->event_handle = NULL;
1332  req->wait_handle = INVALID_HANDLE_VALUE;
1333 
1334  /* Prepare the overlapped structure. */
1335  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
1337  req->event_handle = CreateEvent(NULL, 0, 0, NULL);
1338  if (req->event_handle == NULL) {
1339  uv_fatal_error(GetLastError(), "CreateEvent");
1340  }
1341  req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
1342  }
1343  req->write_buffer = uv_null_buf_;
1344 
1345  if (nbufs == 0) {
1346  /* Write empty buffer. */
1347  write_buf = uv_null_buf_;
1348  } else if (nbufs == 1 && !copy_always) {
1349  /* Write directly from bufs[0]. */
1350  write_buf = bufs[0];
1351  } else {
1352  /* Coalesce all `bufs` into one big buffer. This also creates a new
1353  * write-request structure that replaces the old one. */
1354  err = uv__build_coalesced_write_req(req, bufs, nbufs, &req, &write_buf);
1355  if (err != 0)
1356  return err;
1357  }
1358 
1359  if ((handle->flags &
1362  DWORD bytes;
1363  result =
1364  WriteFile(handle->handle, write_buf.base, write_buf.len, &bytes, NULL);
1365 
1366  if (!result) {
1367  err = GetLastError();
1368  return err;
1369  } else {
1370  /* Request completed immediately. */
1371  req->u.io.queued_bytes = 0;
1372  }
1373 
1375  handle->reqs_pending++;
1376  handle->stream.conn.write_reqs_pending++;
1378  return 0;
1379  } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
1380  req->write_buffer = write_buf;
1382  if (handle->stream.conn.write_reqs_pending == 0) {
1384  }
1385 
1386  /* Request queued by the kernel. */
1387  req->u.io.queued_bytes = write_buf.len;
1388  handle->write_queue_size += req->u.io.queued_bytes;
1389  } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) {
1390  /* Using overlapped IO, but wait for completion before returning */
1391  result = WriteFile(handle->handle,
1392  write_buf.base,
1393  write_buf.len,
1394  NULL,
1395  &req->u.io.overlapped);
1396 
1397  if (!result && GetLastError() != ERROR_IO_PENDING) {
1398  err = GetLastError();
1399  CloseHandle(req->event_handle);
1400  req->event_handle = NULL;
1401  return err;
1402  }
1403 
1404  if (result) {
1405  /* Request completed immediately. */
1406  req->u.io.queued_bytes = 0;
1407  } else {
1408  /* Request queued by the kernel. */
1409  req->u.io.queued_bytes = write_buf.len;
1410  handle->write_queue_size += req->u.io.queued_bytes;
1411  if (WaitForSingleObject(req->event_handle, INFINITE) !=
1412  WAIT_OBJECT_0) {
1413  err = GetLastError();
1414  CloseHandle(req->event_handle);
1415  req->event_handle = NULL;
1416  return err;
1417  }
1418  }
1419  CloseHandle(req->event_handle);
1420  req->event_handle = NULL;
1421 
1423  handle->reqs_pending++;
1424  handle->stream.conn.write_reqs_pending++;
1425  return 0;
1426  } else {
1427  result = WriteFile(handle->handle,
1428  write_buf.base,
1429  write_buf.len,
1430  NULL,
1431  &req->u.io.overlapped);
1432 
1433  if (!result && GetLastError() != ERROR_IO_PENDING) {
1434  return GetLastError();
1435  }
1436 
1437  if (result) {
1438  /* Request completed immediately. */
1439  req->u.io.queued_bytes = 0;
1440  } else {
1441  /* Request queued by the kernel. */
1442  req->u.io.queued_bytes = write_buf.len;
1443  handle->write_queue_size += req->u.io.queued_bytes;
1444  }
1445 
1446  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
1447  if (!RegisterWaitForSingleObject(&req->wait_handle,
1448  req->event_handle, post_completion_write_wait, (void*) req,
1449  INFINITE, WT_EXECUTEINWAITTHREAD)) {
1450  return GetLastError();
1451  }
1452  }
1453  }
1454 
1456  handle->reqs_pending++;
1457  handle->stream.conn.write_reqs_pending++;
1458 
1459  return 0;
1460 }
static ut8 bytes[32]
Definition: asm_arc.c:23
return memset(p, 0, total)
#define REGISTER_HANDLE_REQ(loop, handle, req)
Definition: req-inl.h:56
_W64 unsigned int uintptr_t
size_t len
Definition: unix.h:125
char * base
Definition: unix.h:124
static void CALLBACK post_completion_write_wait(void *context, BOOLEAN timed_out)
Definition: pipe.c:1093
static int uv__build_coalesced_write_req(uv_write_t *user_req, const uv_buf_t bufs[], size_t nbufs, uv_write_t **req_out, uv_buf_t *write_buf_out)
Definition: pipe.c:1252
static void uv_insert_non_overlapped_write_req(uv_pipe_t *handle, uv_write_t *req)
Definition: pipe.c:1204
static void uv_queue_non_overlapped_write(uv_pipe_t *handle)
Definition: pipe.c:1240
@ UV_HANDLE_BLOCKING_WRITES
Definition: uv-common.h:98
@ UV_HANDLE_EMULATE_IOCP
Definition: uv-common.h:97
#define UV_REQ_INIT(req, typ)
Definition: uv-common.h:322

References assert(), uv_buf_t::base, bufs, bytes, cb, DWORD, err, handle, HANDLE, INVALID_HANDLE_VALUE, uv_buf_t::len, loop, memset(), NULL, POST_COMPLETION_FOR_REQ, post_completion_write_wait(), REGISTER_HANDLE_REQ, req, uv__build_coalesced_write_req(), uv_fatal_error(), UV_HANDLE_BLOCKING_WRITES, UV_HANDLE_EMULATE_IOCP, UV_HANDLE_NON_OVERLAPPED_PIPE, uv_insert_non_overlapped_write_req(), uv_null_buf_, uv_queue_non_overlapped_write(), and UV_REQ_INIT.

Referenced by uv__pipe_write(), and uv__pipe_write_ipc().

◆ uv__pipe_write_ipc()

int uv__pipe_write_ipc ( uv_loop_t loop,
uv_write_t req,
uv_pipe_t handle,
const uv_buf_t  data_bufs[],
size_t  data_buf_count,
uv_stream_t send_handle,
uv_write_cb  cb 
)

Definition at line 1476 of file pipe.c.

1482  {
1483  uv_buf_t stack_bufs[6];
1484  uv_buf_t* bufs;
1485  size_t buf_count, buf_index;
1486  uv__ipc_frame_header_t frame_header;
1488  uv__ipc_socket_xfer_info_t xfer_info;
1489  uint64_t data_length;
1490  size_t i;
1491  int err;
1492 
1493  /* Compute the combined size of data buffers. */
1494  data_length = 0;
1495  for (i = 0; i < data_buf_count; i++)
1496  data_length += data_bufs[i].len;
1497  if (data_length > UINT32_MAX)
1498  return WSAENOBUFS; /* Maps to UV_ENOBUFS. */
1499 
1500  /* Prepare the frame's socket xfer payload. */
1501  if (send_handle != NULL) {
1502  uv_tcp_t* send_tcp_handle = (uv_tcp_t*) send_handle;
1503 
1504  /* Verify that `send_handle` it is indeed a tcp handle. */
1505  if (send_tcp_handle->type != UV_TCP)
1506  return ERROR_NOT_SUPPORTED;
1507 
1508  /* Export the tcp handle. */
1509  err = uv__tcp_xfer_export(send_tcp_handle,
1511  &xfer_type,
1512  &xfer_info);
1513  if (err != 0)
1514  return err;
1515  }
1516 
1517  /* Compute the number of uv_buf_t's required. */
1518  buf_count = 1 + data_buf_count; /* Frame header and data buffers. */
1519  if (send_handle != NULL)
1520  buf_count += 1; /* One extra for the socket xfer information. */
1521 
1522  /* Use the on-stack buffer array if it is big enough; otherwise allocate
1523  * space for it on the heap. */
1524  if (buf_count < ARRAY_SIZE(stack_bufs)) {
1525  /* Use on-stack buffer array. */
1526  bufs = stack_bufs;
1527  } else {
1528  /* Use heap-allocated buffer array. */
1529  bufs = uv__calloc(buf_count, sizeof(uv_buf_t));
1530  if (bufs == NULL)
1531  return ERROR_NOT_ENOUGH_MEMORY; /* Maps to UV_ENOMEM. */
1532  }
1533  buf_index = 0;
1534 
1535  /* Initialize frame header and add it to the buffers list. */
1536  memset(&frame_header, 0, sizeof frame_header);
1537  bufs[buf_index++] = uv_buf_init((char*) &frame_header, sizeof frame_header);
1538 
1539  if (send_handle != NULL) {
1540  /* Add frame header flags. */
1541  switch (xfer_type) {
1543  frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER |
1545  break;
1547  frame_header.flags |= UV__IPC_FRAME_HAS_SOCKET_XFER;
1548  break;
1549  default:
1550  assert(0); /* Unreachable. */
1551  }
1552  /* Add xfer info buffer. */
1553  bufs[buf_index++] = uv_buf_init((char*) &xfer_info, sizeof xfer_info);
1554  }
1555 
1556  if (data_length > 0) {
1557  /* Update frame header. */
1558  frame_header.flags |= UV__IPC_FRAME_HAS_DATA;
1559  frame_header.data_length = (uint32_t) data_length;
1560  /* Add data buffers to buffers list. */
1561  for (i = 0; i < data_buf_count; i++)
1562  bufs[buf_index++] = data_bufs[i];
1563  }
1564 
1565  /* Write buffers. We set the `always_copy` flag, so it is not a problem that
1566  * some of the written data lives on the stack. */
1567  err = uv__pipe_write_data(loop, req, handle, bufs, buf_count, cb, 1);
1568 
1569  /* If we had to heap-allocate the bufs array, free it now. */
1570  if (bufs != stack_bufs) {
1571  uv__free(bufs);
1572  }
1573 
1574  return err;
1575 }
#define ARRAY_SIZE(a)
unsigned long uint64_t
Definition: sftypes.h:28
int uv__tcp_xfer_export(uv_tcp_t *handle, int pid, uv__ipc_socket_xfer_type_t *xfer_type, uv__ipc_socket_xfer_info_t *xfer_info)
Definition: tcp.c:1242
static DWORD uv__pipe_get_ipc_remote_pid(uv_pipe_t *handle)
Definition: pipe.c:1463
void * uv__calloc(size_t count, size_t size)
Definition: uv-common.c:92

References ARRAY_SIZE, assert(), bufs, cb, uv__ipc_frame_header_t::data_length, err, uv__ipc_frame_header_t::flags, handle, i, len, loop, memset(), NULL, req, UINT32_MAX, uv__calloc(), uv__free(), UV__IPC_FRAME_HAS_DATA, UV__IPC_FRAME_HAS_SOCKET_XFER, UV__IPC_FRAME_XFER_IS_TCP_CONNECTION, UV__IPC_SOCKET_XFER_NONE, UV__IPC_SOCKET_XFER_TCP_CONNECTION, UV__IPC_SOCKET_XFER_TCP_SERVER, uv__pipe_get_ipc_remote_pid(), uv__pipe_write_data(), uv__tcp_xfer_export(), and uv_buf_init().

Referenced by uv__pipe_write().

◆ uv_insert_non_overlapped_write_req()

static void uv_insert_non_overlapped_write_req ( uv_pipe_t handle,
uv_write_t req 
)
static

Definition at line 1204 of file pipe.c.

1205  {
1206  req->next_req = NULL;
1207  if (handle->pipe.conn.non_overlapped_writes_tail) {
1208  req->next_req =
1209  handle->pipe.conn.non_overlapped_writes_tail->next_req;
1210  handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req;
1211  handle->pipe.conn.non_overlapped_writes_tail = req;
1212  } else {
1213  req->next_req = (uv_req_t*)req;
1214  handle->pipe.conn.non_overlapped_writes_tail = req;
1215  }
1216 }
Definition: uv.h:407

References handle, NULL, and req.

Referenced by uv__pipe_write_data().

◆ uv_pipe_accept()

int uv_pipe_accept ( uv_pipe_t server,
uv_stream_t client 
)

Definition at line 876 of file pipe.c.

876  {
877  uv_loop_t* loop = server->loop;
878  uv_pipe_t* pipe_client;
879  uv_pipe_accept_t* req;
880  QUEUE* q;
882  int err;
883 
884  if (server->ipc) {
885  if (QUEUE_EMPTY(&server->pipe.conn.ipc_xfer_queue)) {
886  /* No valid pending sockets. */
887  return WSAEWOULDBLOCK;
888  }
889 
890  q = QUEUE_HEAD(&server->pipe.conn.ipc_xfer_queue);
891  QUEUE_REMOVE(q);
892  server->pipe.conn.ipc_xfer_queue_length--;
893  item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member);
894 
896  (uv_tcp_t*) client, item->xfer_type, &item->xfer_info);
897  if (err != 0)
898  return err;
899 
900  uv__free(item);
901 
902  } else {
903  pipe_client = (uv_pipe_t*) client;
904 
905  /* Find a connection instance that has been connected, but not yet
906  * accepted. */
907  req = server->pipe.serv.pending_accepts;
908 
909  if (!req) {
910  /* No valid connections found, so we error out. */
911  return WSAEWOULDBLOCK;
912  }
913 
914  /* Initialize the client handle and copy the pipeHandle to the client */
915  uv_pipe_connection_init(pipe_client);
916  pipe_client->handle = req->pipeHandle;
917  pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;
918 
919  /* Prepare the req to pick up a new connection */
920  server->pipe.serv.pending_accepts = req->next_pending;
921  req->next_pending = NULL;
922  req->pipeHandle = INVALID_HANDLE_VALUE;
923 
924  server->handle = INVALID_HANDLE_VALUE;
925  if (!(server->flags & UV_HANDLE_CLOSING)) {
926  uv_pipe_queue_accept(loop, server, req, FALSE);
927  }
928  }
929 
930  return 0;
931 }
#define FALSE
Definition: mybfd.h:102
#define QUEUE_DATA(ptr, type, field)
Definition: queue.h:30
#define QUEUE_EMPTY(q)
Definition: queue.h:39
#define QUEUE_HEAD(q)
Definition: queue.h:42
void * QUEUE[2]
Definition: queue.h:21
#define QUEUE_REMOVE(q)
Definition: queue.h:101
UV_HANDLE_FIELDS UV_STREAM_FIELDS int ipc
Definition: uv.h:770
int uv__tcp_xfer_import(uv_tcp_t *tcp, uv__ipc_socket_xfer_type_t xfer_type, uv__ipc_socket_xfer_info_t *xfer_info)
Definition: tcp.c:1277
static void uv_pipe_queue_accept(uv_loop_t *loop, uv_pipe_t *handle, uv_pipe_accept_t *req, BOOL firstInstance)
Definition: pipe.c:840
static void uv_pipe_connection_init(uv_pipe_t *handle)
Definition: pipe.c:123
@ UV_HANDLE_CLOSING
Definition: uv-common.h:74

References err, FALSE, INVALID_HANDLE_VALUE, uv_pipe_s::ipc, loop, NULL, QUEUE_DATA, QUEUE_EMPTY, QUEUE_HEAD, QUEUE_REMOVE, req, uv__free(), uv__tcp_xfer_import(), UV_HANDLE_CLOSING, UV_HANDLE_READABLE, UV_HANDLE_WRITABLE, uv_pipe_connection_init(), uv_pipe_queue_accept(), uv__ipc_xfer_queue_item_t::xfer_info, and uv__ipc_xfer_queue_item_t::xfer_type.

Referenced by uv_accept().

◆ uv_pipe_bind()

int uv_pipe_bind ( uv_pipe_t handle,
const char *  name 
)

Definition at line 523 of file pipe.c.

523  {
524  uv_loop_t* loop = handle->loop;
525  int i, err, nameSize;
526  uv_pipe_accept_t* req;
527 
528  if (handle->flags & UV_HANDLE_BOUND) {
529  return UV_EINVAL;
530  }
531 
532  if (!name) {
533  return UV_EINVAL;
534  }
535 
536  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
537  handle->pipe.serv.pending_instances = default_pending_pipe_instances;
538  }
539 
540  handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
541  uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances);
542  if (!handle->pipe.serv.accept_reqs) {
543  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
544  }
545 
546  for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
547  req = &handle->pipe.serv.accept_reqs[i];
548  UV_REQ_INIT(req, UV_ACCEPT);
549  req->data = handle;
550  req->pipeHandle = INVALID_HANDLE_VALUE;
551  req->next_pending = NULL;
552  }
553 
554  /* Convert name to UTF16. */
555  nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
556  handle->name = uv__malloc(nameSize);
557  if (!handle->name) {
558  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
559  }
560 
561  if (!MultiByteToWideChar(CP_UTF8,
562  0,
563  name,
564  -1,
565  handle->name,
566  nameSize / sizeof(WCHAR))) {
567  err = GetLastError();
568  goto error;
569  }
570 
571  /*
572  * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
573  * If this fails then there's already a pipe server for the given pipe name.
574  */
575  if (!pipe_alloc_accept(loop,
576  handle,
577  &handle->pipe.serv.accept_reqs[0],
578  TRUE)) {
579  err = GetLastError();
580  if (err == ERROR_ACCESS_DENIED) {
581  err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */
582  } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) {
583  err = WSAEACCES; /* Translates to UV_EACCES. */
584  }
585  goto error;
586  }
587 
588  handle->pipe.serv.pending_accepts = NULL;
589  handle->flags |= UV_HANDLE_PIPESERVER;
590  handle->flags |= UV_HANDLE_BOUND;
591 
592  return 0;
593 
594 error:
595  if (handle->name) {
596  uv__free(handle->name);
597  handle->name = NULL;
598  }
599 
600  return uv_translate_sys_error(err);
601 }
#define TRUE
Definition: mybfd.h:103
static int pipe_alloc_accept(uv_loop_t *loop, uv_pipe_t *handle, uv_pipe_accept_t *req, BOOL firstInstance)
Definition: pipe.c:329
static const int default_pending_pipe_instances
Definition: pipe.c:48
@ UV_HANDLE_PIPESERVER
Definition: uv-common.h:119
@ UV_HANDLE_BOUND
Definition: uv-common.h:91

References AF_UNIX, bind, default_pending_pipe_instances, err, error(), handle, i, INVALID_HANDLE_VALUE, loop, memset(), NULL, pipe_alloc_accept(), req, SOCK_STREAM, sockfd, sockaddr_un::sun_path, TRUE, uv__close(), UV__ERR, uv__free(), uv__malloc(), uv__socket(), uv__strdup(), uv__stream_fd, uv__strscpy(), uv_fatal_error(), UV_HANDLE_BOUND, UV_HANDLE_PIPESERVER, UV_REQ_INIT, and uv_translate_sys_error().

Referenced by main().

◆ uv_pipe_chmod()

int uv_pipe_chmod ( uv_pipe_t handle,
int  mode 
)

Definition at line 2318 of file pipe.c.

2318  {
2319  SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY };
2320  PACL old_dacl, new_dacl;
2321  PSECURITY_DESCRIPTOR sd;
2322  EXPLICIT_ACCESS ea;
2323  PSID everyone;
2324  int error;
2325 
2326  if (handle == NULL || handle->handle == INVALID_HANDLE_VALUE)
2327  return UV_EBADF;
2328 
2329  if (mode != UV_READABLE &&
2330  mode != UV_WRITABLE &&
2331  mode != (UV_WRITABLE | UV_READABLE))
2332  return UV_EINVAL;
2333 
2334  if (!AllocateAndInitializeSid(&sid_world,
2335  1,
2336  SECURITY_WORLD_RID,
2337  0, 0, 0, 0, 0, 0, 0,
2338  &everyone)) {
2339  error = GetLastError();
2340  goto done;
2341  }
2342 
2343  if (GetSecurityInfo(handle->handle,
2344  SE_KERNEL_OBJECT,
2345  DACL_SECURITY_INFORMATION,
2346  NULL,
2347  NULL,
2348  &old_dacl,
2349  NULL,
2350  &sd)) {
2351  error = GetLastError();
2352  goto clean_sid;
2353  }
2354 
2355  memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
2356  if (mode & UV_READABLE)
2357  ea.grfAccessPermissions |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
2358  if (mode & UV_WRITABLE)
2359  ea.grfAccessPermissions |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
2360  ea.grfAccessPermissions |= SYNCHRONIZE;
2361  ea.grfAccessMode = SET_ACCESS;
2362  ea.grfInheritance = NO_INHERITANCE;
2363  ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
2364  ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
2365  ea.Trustee.ptstrName = (LPTSTR)everyone;
2366 
2367  if (SetEntriesInAcl(1, &ea, old_dacl, &new_dacl)) {
2368  error = GetLastError();
2369  goto clean_sd;
2370  }
2371 
2372  if (SetSecurityInfo(handle->handle,
2373  SE_KERNEL_OBJECT,
2374  DACL_SECURITY_INFORMATION,
2375  NULL,
2376  NULL,
2377  new_dacl,
2378  NULL)) {
2379  error = GetLastError();
2380  goto clean_dacl;
2381  }
2382 
2383  error = 0;
2384 
2385 clean_dacl:
2386  LocalFree((HLOCAL) new_dacl);
2387 clean_sd:
2388  LocalFree((HLOCAL) sd);
2389 clean_sid:
2390  FreeSid(everyone);
2391 done:
2392  return uv_translate_sys_error(error);
2393 }
struct tab * done
Definition: enough.c:233
const char int mode
Definition: ioapi.h:137
@ UV_WRITABLE
Definition: uv.h:801
@ UV_READABLE
Definition: uv.h:800

References chmod, done, error(), handle, INVALID_HANDLE_VALUE, memset(), NULL, r, stat, UV__ERR, uv__free(), uv__malloc(), uv__stream_fd, uv_pipe_getsockname(), UV_READABLE, uv_translate_sys_error(), and UV_WRITABLE.

◆ uv_pipe_cleanup()

void uv_pipe_cleanup ( uv_loop_t loop,
uv_pipe_t handle 
)

Definition at line 785 of file pipe.c.

785  {
786  int i;
787  HANDLE pipeHandle;
788 
790 
791  if (handle->name) {
792  uv__free(handle->name);
793  handle->name = NULL;
794  }
795 
796  if (handle->flags & UV_HANDLE_PIPESERVER) {
797  for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
798  pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle;
799  if (pipeHandle != INVALID_HANDLE_VALUE) {
800  CloseHandle(pipeHandle);
801  handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE;
802  }
803  }
804  handle->handle = INVALID_HANDLE_VALUE;
805  }
806 
807  if (handle->flags & UV_HANDLE_CONNECTION) {
808  handle->flags &= ~UV_HANDLE_WRITABLE;
810  }
811 
812  if ((handle->flags & UV_HANDLE_CONNECTION)
813  && handle->handle != INVALID_HANDLE_VALUE)
815 }
static void eof_timer_destroy(uv_pipe_t *pipe)
Definition: pipe.c:2065

References close_pipe(), eof_timer_destroy(), handle, HANDLE, i, INVALID_HANDLE_VALUE, NULL, uv__free(), uv__pipe_interrupt_read(), UV_HANDLE_CONNECTION, UV_HANDLE_PIPESERVER, and UV_HANDLE_WRITABLE.

Referenced by uv__create_stdio_pipe_pair(), and uv_pipe_close().

◆ uv_pipe_close()

void uv_pipe_close ( uv_loop_t loop,
uv_pipe_t handle 
)

Definition at line 818 of file pipe.c.

818  {
819  if (handle->flags & UV_HANDLE_READING) {
820  handle->flags &= ~UV_HANDLE_READING;
822  }
823 
824  if (handle->flags & UV_HANDLE_LISTENING) {
825  handle->flags &= ~UV_HANDLE_LISTENING;
827  }
828 
830 
831  if (handle->reqs_pending == 0) {
833  }
834 
837 }
static INLINE void uv_want_endgame(uv_loop_t *loop, uv_handle_t *handle)
Definition: handle-inl.h:88
#define uv__handle_closing(handle)
Definition: handle-inl.h:63
void uv_pipe_cleanup(uv_loop_t *loop, uv_pipe_t *handle)
Definition: pipe.c:785
@ UV_HANDLE_LISTENING
Definition: uv-common.h:82

References DECREASE_ACTIVE_COUNT, handle, loop, uv__handle_closing, UV_HANDLE_LISTENING, UV_HANDLE_READABLE, UV_HANDLE_READING, UV_HANDLE_WRITABLE, uv_pipe_cleanup(), and uv_want_endgame().

Referenced by uv_close().

◆ uv_pipe_connect()

void uv_pipe_connect ( uv_connect_t req,
uv_pipe_t handle,
const char *  name,
uv_connect_cb  cb 
)

Definition at line 643 of file pipe.c.

644  {
645  uv_loop_t* loop = handle->loop;
646  int err, nameSize;
647  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
648  DWORD duplex_flags;
649 
650  UV_REQ_INIT(req, UV_CONNECT);
651  req->handle = (uv_stream_t*) handle;
652  req->cb = cb;
653 
654  /* Convert name to UTF16. */
655  nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR);
656  handle->name = uv__malloc(nameSize);
657  if (!handle->name) {
658  uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc");
659  }
660 
661  if (!MultiByteToWideChar(CP_UTF8,
662  0,
663  name,
664  -1,
665  handle->name,
666  nameSize / sizeof(WCHAR))) {
667  err = GetLastError();
668  goto error;
669  }
670 
671  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
672  if (pipeHandle == INVALID_HANDLE_VALUE) {
673  if (GetLastError() == ERROR_PIPE_BUSY) {
674  /* Wait for the server to make a pipe instance available. */
675  if (!QueueUserWorkItem(&pipe_connect_thread_proc,
676  req,
677  WT_EXECUTELONGFUNCTION)) {
678  err = GetLastError();
679  goto error;
680  }
681 
683  handle->reqs_pending++;
684 
685  return;
686  }
687 
688  err = GetLastError();
689  goto error;
690  }
691 
692  assert(pipeHandle != INVALID_HANDLE_VALUE);
693 
695  (uv_pipe_t*) req->handle,
696  pipeHandle,
697  -1,
698  duplex_flags)) {
699  err = GetLastError();
700  goto error;
701  }
702 
705  handle->reqs_pending++;
707  return;
708 
709 error:
710  if (handle->name) {
711  uv__free(handle->name);
712  handle->name = NULL;
713  }
714 
715  if (pipeHandle != INVALID_HANDLE_VALUE) {
716  CloseHandle(pipeHandle);
717  }
718 
719  /* Make this req pending reporting an error. */
722  handle->reqs_pending++;
724  return;
725 }
static INLINE void uv_insert_pending_req(uv_loop_t *loop, uv_req_t *req)
Definition: req-inl.h:90
static DWORD WINAPI pipe_connect_thread_proc(void *parameter)
Definition: pipe.c:604

References AF_UNIX, assert(), cb, DWORD, EINPROGRESS, EINTR, err, error(), handle, HANDLE, INVALID_HANDLE_VALUE, loop, memset(), NULL, open_named_pipe(), out, pipe_connect_thread_proc(), QUEUE_INIT, r, REGISTER_HANDLE_REQ, req, SET_REQ_ERROR, SET_REQ_SUCCESS, SOCK_STREAM, sockaddr_un::sun_path, UV__ERR, uv__free(), uv__io_feed(), uv__io_start(), uv__malloc(), uv__req_init, uv__socket(), uv__stream_fd, uv__stream_open(), uv__strscpy(), uv_fatal_error(), UV_HANDLE_READABLE, UV_HANDLE_WRITABLE, uv_insert_pending_req(), UV_REQ_INIT, and uv_set_pipe_handle().

◆ uv_pipe_connection_init()

static void uv_pipe_connection_init ( uv_pipe_t handle)
static

Definition at line 123 of file pipe.c.

123  {
125  handle->read_req.data = handle;
126  handle->pipe.conn.eof_timer = NULL;
127  assert(!(handle->flags & UV_HANDLE_PIPESERVER));
128  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
129  handle->pipe.conn.readfile_thread_handle = NULL;
130  InitializeCriticalSection(&handle->pipe.conn.readfile_thread_lock);
131  }
132 }
static INLINE void uv_connection_init(uv_stream_t *handle)
Definition: stream-inl.h:49

References assert(), handle, NULL, uv_connection_init(), UV_HANDLE_NON_OVERLAPPED_PIPE, and UV_HANDLE_PIPESERVER.

Referenced by uv_pipe_accept(), uv_pipe_open(), uv_process_pipe_connect_req(), and uv_stdio_pipe_server().

◆ uv_pipe_endgame()

void uv_pipe_endgame ( uv_loop_t loop,
uv_pipe_t handle 
)

Definition at line 382 of file pipe.c.

382  {
383  int err;
384  DWORD result;
386  NTSTATUS nt_status;
387  IO_STATUS_BLOCK io_status;
388  FILE_PIPE_LOCAL_INFORMATION pipe_info;
389  uv__ipc_xfer_queue_item_t* xfer_queue_item;
390 
391  if ((handle->flags & UV_HANDLE_CONNECTION) &&
392  handle->stream.conn.shutdown_req != NULL &&
393  handle->stream.conn.write_reqs_pending == 0) {
394  req = handle->stream.conn.shutdown_req;
395 
396  /* Clear the shutdown_req field so we don't go here again. */
397  handle->stream.conn.shutdown_req = NULL;
398 
399  if (handle->flags & UV_HANDLE_CLOSING) {
401 
402  /* Already closing. Cancel the shutdown. */
403  if (req->cb) {
404  req->cb(req, UV_ECANCELED);
405  }
406 
408  return;
409  }
410 
411  /* Try to avoid flushing the pipe buffer in the thread pool. */
412  nt_status = pNtQueryInformationFile(handle->handle,
413  &io_status,
414  &pipe_info,
415  sizeof pipe_info,
417 
418  if (nt_status != STATUS_SUCCESS) {
419  /* Failure */
421 
422  handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
423  if (req->cb) {
424  err = pRtlNtStatusToDosError(nt_status);
426  }
427 
429  return;
430  }
431 
432  if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) {
433  /* Short-circuit, no need to call FlushFileBuffers. */
435  return;
436  }
437 
438  /* Run FlushFileBuffers in the thread pool. */
439  result = QueueUserWorkItem(pipe_shutdown_thread_proc,
440  req,
441  WT_EXECUTELONGFUNCTION);
442  if (result) {
443  return;
444 
445  } else {
446  /* Failure. */
448 
449  handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */
450  if (req->cb) {
451  err = GetLastError();
453  }
454 
456  return;
457  }
458  }
459 
460  if (handle->flags & UV_HANDLE_CLOSING &&
461  handle->reqs_pending == 0) {
462  assert(!(handle->flags & UV_HANDLE_CLOSED));
463 
464  if (handle->flags & UV_HANDLE_CONNECTION) {
465  /* Free pending sockets */
466  while (!QUEUE_EMPTY(&handle->pipe.conn.ipc_xfer_queue)) {
467  QUEUE* q;
468  SOCKET socket;
469 
470  q = QUEUE_HEAD(&handle->pipe.conn.ipc_xfer_queue);
471  QUEUE_REMOVE(q);
472  xfer_queue_item = QUEUE_DATA(q, uv__ipc_xfer_queue_item_t, member);
473 
474  /* Materialize socket and close it */
475  socket = WSASocketW(FROM_PROTOCOL_INFO,
476  FROM_PROTOCOL_INFO,
477  FROM_PROTOCOL_INFO,
478  &xfer_queue_item->xfer_info.socket_info,
479  0,
480  WSA_FLAG_OVERLAPPED);
481  uv__free(xfer_queue_item);
482 
483  if (socket != INVALID_SOCKET)
484  closesocket(socket);
485  }
486  handle->pipe.conn.ipc_xfer_queue_length = 0;
487 
488  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
489  if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) {
490  UnregisterWait(handle->read_req.wait_handle);
491  handle->read_req.wait_handle = INVALID_HANDLE_VALUE;
492  }
493  if (handle->read_req.event_handle != NULL) {
494  CloseHandle(handle->read_req.event_handle);
495  handle->read_req.event_handle = NULL;
496  }
497  }
498 
500  DeleteCriticalSection(&handle->pipe.conn.readfile_thread_lock);
501  }
502 
503  if (handle->flags & UV_HANDLE_PIPESERVER) {
504  assert(handle->pipe.serv.accept_reqs);
505  uv__free(handle->pipe.serv.accept_reqs);
506  handle->pipe.serv.accept_reqs = NULL;
507  }
508 
510  }
511 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd socket
Definition: sflib.h:79
#define uv__handle_close(handle)
Definition: handle-inl.h:76
#define DECREASE_PENDING_REQ_COUNT(handle)
Definition: handle-inl.h:51
#define UNREGISTER_HANDLE_REQ(loop, handle, req)
Definition: req-inl.h:62
WSAPROTOCOL_INFOW socket_info
Definition: internal.h:71
static DWORD WINAPI pipe_shutdown_thread_proc(void *parameter)
Definition: pipe.c:361
@ UV_HANDLE_CLOSED
Definition: uv-common.h:75
@ FilePipeLocalInformation
Definition: winapi.h:4195

References assert(), DECREASE_PENDING_REQ_COUNT, DWORD, err, FilePipeLocalInformation, handle, INVALID_HANDLE_VALUE, loop, NULL, _FILE_PIPE_LOCAL_INFORMATION::OutboundQuota, pipe_shutdown_thread_proc(), pNtQueryInformationFile, pRtlNtStatusToDosError, QUEUE_DATA, QUEUE_EMPTY, QUEUE_HEAD, QUEUE_REMOVE, req, socket, uv__ipc_socket_xfer_info_t::socket_info, STATUS_SUCCESS, UNREGISTER_HANDLE_REQ, uv__free(), uv__handle_close, UV_HANDLE_CLOSED, UV_HANDLE_CLOSING, UV_HANDLE_CONNECTION, UV_HANDLE_EMULATE_IOCP, UV_HANDLE_NON_OVERLAPPED_PIPE, UV_HANDLE_PIPESERVER, UV_HANDLE_WRITABLE, uv_insert_pending_req(), uv_translate_sys_error(), _FILE_PIPE_LOCAL_INFORMATION::WriteQuotaAvailable, and uv__ipc_xfer_queue_item_t::xfer_info.

Referenced by uv_process_endgames().

◆ uv_pipe_getpeername()

int uv_pipe_getpeername ( const uv_pipe_t handle,
char *  buffer,
size_t size 
)

Definition at line 2297 of file pipe.c.

2297  {
2298  /* emulate unix behaviour */
2299  if (handle->flags & UV_HANDLE_BOUND)
2300  return UV_ENOTCONN;
2301 
2302  if (handle->handle != INVALID_HANDLE_VALUE)
2303  return uv__pipe_getname(handle, buffer, size);
2304 
2305  return UV_EBADF;
2306 }
static int uv__pipe_getname(const uv_pipe_t *handle, char *buffer, size_t *size)
Definition: pipe.c:2154

References handle, INVALID_HANDLE_VALUE, uv__pipe_getname(), uv__pipe_getsockpeername(), and UV_HANDLE_BOUND.

◆ uv_pipe_getsockname()

int uv_pipe_getsockname ( const uv_pipe_t handle,
char *  buffer,
size_t size 
)

Definition at line 2283 of file pipe.c.

2283  {
2284  if (handle->flags & UV_HANDLE_BOUND)
2285  return uv__pipe_getname(handle, buffer, size);
2286 
2287  if (handle->flags & UV_HANDLE_CONNECTION ||
2288  handle->handle != INVALID_HANDLE_VALUE) {
2289  *size = 0;
2290  return 0;
2291  }
2292 
2293  return UV_EBADF;
2294 }

References handle, INVALID_HANDLE_VALUE, uv__pipe_getname(), uv__pipe_getsockpeername(), UV_HANDLE_BOUND, and UV_HANDLE_CONNECTION.

◆ uv_pipe_init()

int uv_pipe_init ( uv_loop_t loop,
uv_pipe_t handle,
int  ipc 
)

Definition at line 106 of file pipe.c.

106  {
107  uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE);
108 
109  handle->reqs_pending = 0;
110  handle->handle = INVALID_HANDLE_VALUE;
111  handle->name = NULL;
112  handle->pipe.conn.ipc_remote_pid = 0;
113  handle->pipe.conn.ipc_data_frame.payload_remaining = 0;
114  QUEUE_INIT(&handle->pipe.conn.ipc_xfer_queue);
115  handle->pipe.conn.ipc_xfer_queue_length = 0;
116  handle->ipc = ipc;
117  handle->pipe.conn.non_overlapped_writes_tail = NULL;
118 
119  return 0;
120 }
#define QUEUE_INIT(q)
Definition: queue.h:45
static INLINE void uv_stream_init(uv_loop_t *loop, uv_stream_t *handle, uv_handle_type type)
Definition: stream-inl.h:33

References handle, INVALID_HANDLE_VALUE, loop, NULL, QUEUE_INIT, uv__stream_init(), and uv_stream_init().

Referenced by main(), on_new_connection(), and setup_workers().

◆ uv_pipe_listen()

int uv_pipe_listen ( uv_pipe_t handle,
int  backlog,
uv_connection_cb  cb 
)

Definition at line 935 of file pipe.c.

935  {
936  uv_loop_t* loop = handle->loop;
937  int i;
938 
939  if (handle->flags & UV_HANDLE_LISTENING) {
940  handle->stream.serv.connection_cb = cb;
941  }
942 
943  if (!(handle->flags & UV_HANDLE_BOUND)) {
944  return WSAEINVAL;
945  }
946 
947  if (handle->flags & UV_HANDLE_READING) {
948  return WSAEISCONN;
949  }
950 
951  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
952  return ERROR_NOT_SUPPORTED;
953  }
954 
955  if (handle->ipc) {
956  return WSAEINVAL;
957  }
958 
959  handle->flags |= UV_HANDLE_LISTENING;
961  handle->stream.serv.connection_cb = cb;
962 
963  /* First pipe handle should have already been created in uv_pipe_bind */
964  assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);
965 
966  for (i = 0; i < handle->pipe.serv.pending_instances; i++) {
967  uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0);
968  }
969 
970  return 0;
971 }
#define INCREASE_ACTIVE_COUNT(loop, handle)
Definition: handle-inl.h:42

References assert(), cb, handle, i, INCREASE_ACTIVE_COUNT, INVALID_HANDLE_VALUE, listen, loop, UV__ERR, uv__io_start(), uv__server_io(), uv__stream_fd, UV_HANDLE_BOUND, UV_HANDLE_LISTENING, UV_HANDLE_PIPESERVER, UV_HANDLE_READING, and uv_pipe_queue_accept().

Referenced by uv_listen().

◆ uv_pipe_open()

int uv_pipe_open ( uv_pipe_t pipe,
uv_file  file 
)

Definition at line 2081 of file pipe.c.

2081  {
2082  HANDLE os_handle = uv__get_osfhandle(file);
2083  NTSTATUS nt_status;
2084  IO_STATUS_BLOCK io_status;
2086  DWORD duplex_flags = 0;
2087 
2088  if (os_handle == INVALID_HANDLE_VALUE)
2089  return UV_EBADF;
2090 
2091  uv__once_init();
2092  /* In order to avoid closing a stdio file descriptor 0-2, duplicate the
2093  * underlying OS handle and forget about the original fd.
2094  * We could also opt to use the original OS handle and just never close it,
2095  * but then there would be no reliable way to cancel pending read operations
2096  * upon close.
2097  */
2098  if (file <= 2) {
2099  if (!DuplicateHandle(INVALID_HANDLE_VALUE,
2100  os_handle,
2102  &os_handle,
2103  0,
2104  FALSE,
2105  DUPLICATE_SAME_ACCESS))
2106  return uv_translate_sys_error(GetLastError());
2107  file = -1;
2108  }
2109 
2110  /* Determine what kind of permissions we have on this handle.
2111  * Cygwin opens the pipe in message mode, but we can support it,
2112  * just query the access flags and set the stream flags accordingly.
2113  */
2114  nt_status = pNtQueryInformationFile(os_handle,
2115  &io_status,
2116  &access,
2117  sizeof(access),
2119  if (nt_status != STATUS_SUCCESS)
2120  return UV_EINVAL;
2121 
2122  if (pipe->ipc) {
2123  if (!(access.AccessFlags & FILE_WRITE_DATA) ||
2124  !(access.AccessFlags & FILE_READ_DATA)) {
2125  return UV_EINVAL;
2126  }
2127  }
2128 
2129  if (access.AccessFlags & FILE_WRITE_DATA)
2130  duplex_flags |= UV_HANDLE_WRITABLE;
2131  if (access.AccessFlags & FILE_READ_DATA)
2132  duplex_flags |= UV_HANDLE_READABLE;
2133 
2134  if (os_handle == INVALID_HANDLE_VALUE ||
2135  uv_set_pipe_handle(pipe->loop,
2136  pipe,
2137  os_handle,
2138  file,
2139  duplex_flags) == -1) {
2140  return UV_EINVAL;
2141  }
2142 
2144 
2145  if (pipe->ipc) {
2147  pipe->pipe.conn.ipc_remote_pid = uv_os_getppid();
2148  assert(pipe->pipe.conn.ipc_remote_pid != (DWORD)(uv_pid_t) -1);
2149  }
2150  return 0;
2151 }
static INLINE HANDLE uv__get_osfhandle(int fd)
Definition: handle-inl.h:166
static static fork const void static count static fd const char static mode const char static pathname const char static path const char static dev const char static group static getpid static getuid void void static data static pause access
Definition: sflib.h:64
Definition: gzappend.c:170
pid_t uv_pid_t
Definition: unix.h:131
UV_EXTERN uv_pid_t uv_os_getppid(void)
Definition: core.c:1402
@ FileAccessInformation
Definition: winapi.h:4179

References access, assert(), DWORD, EINTR, err, F_GETFL, FALSE, fcntl, fd, FileAccessInformation, flags, handle, HANDLE, INVALID_HANDLE_VALUE, O_ACCMODE, O_RDONLY, O_WRONLY, pipe, pNtQueryInformationFile, STATUS_SUCCESS, UV__ERR, uv__fd_exists(), uv__get_osfhandle(), uv__nonblock, uv__once_init(), uv__stream_open(), UV_HANDLE_NON_OVERLAPPED_PIPE, UV_HANDLE_READABLE, UV_HANDLE_WRITABLE, uv_os_getppid(), uv_pipe_connection_init(), uv_set_pipe_handle(), and uv_translate_sys_error().

Referenced by main().

◆ uv_pipe_pending_count()

int uv_pipe_pending_count ( uv_pipe_t handle)

Definition at line 2276 of file pipe.c.

2276  {
2277  if (!handle->ipc)
2278  return 0;
2279  return handle->pipe.conn.ipc_xfer_queue_length;
2280 }

References handle, NULL, and uv__stream_queued_fds_s::offset.

Referenced by on_new_connection().

◆ uv_pipe_pending_instances()

void uv_pipe_pending_instances ( uv_pipe_t handle,
int  count 
)

Definition at line 514 of file pipe.c.

514  {
515  if (handle->flags & UV_HANDLE_BOUND)
516  return;
517  handle->pipe.serv.pending_instances = count;
518  handle->flags |= UV_HANDLE_PIPESERVER;
519 }

References count, handle, UV_HANDLE_BOUND, and UV_HANDLE_PIPESERVER.

◆ uv_pipe_pending_type()

uv_handle_type uv_pipe_pending_type ( uv_pipe_t handle)

Definition at line 2309 of file pipe.c.

2309  {
2310  if (!handle->ipc)
2311  return UV_UNKNOWN_HANDLE;
2312  if (handle->pipe.conn.ipc_xfer_queue_length == 0)
2313  return UV_UNKNOWN_HANDLE;
2314  else
2315  return UV_TCP;
2316 }
@ UV_UNKNOWN_HANDLE
Definition: uv.h:190

References handle, uv__handle_type(), and UV_UNKNOWN_HANDLE.

Referenced by on_new_connection().

◆ uv_pipe_queue_accept()

static void uv_pipe_queue_accept ( uv_loop_t loop,
uv_pipe_t handle,
uv_pipe_accept_t *  req,
BOOL  firstInstance 
)
static

Definition at line 840 of file pipe.c.

841  {
843 
844  if (!firstInstance && !pipe_alloc_accept(loop, handle, req, FALSE)) {
845  SET_REQ_ERROR(req, GetLastError());
847  handle->reqs_pending++;
848  return;
849  }
850 
851  assert(req->pipeHandle != INVALID_HANDLE_VALUE);
852 
853  /* Prepare the overlapped structure. */
854  memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped));
855 
856  if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) &&
857  GetLastError() != ERROR_IO_PENDING) {
858  if (GetLastError() == ERROR_PIPE_CONNECTED) {
860  } else {
861  CloseHandle(req->pipeHandle);
862  req->pipeHandle = INVALID_HANDLE_VALUE;
863  /* Make this req pending reporting an error. */
864  SET_REQ_ERROR(req, GetLastError());
865  }
867  handle->reqs_pending++;
868  return;
869  }
870 
871  /* Wait for completion via IOCP */
872  handle->reqs_pending++;
873 }

References assert(), FALSE, handle, INVALID_HANDLE_VALUE, loop, memset(), pipe_alloc_accept(), req, SET_REQ_ERROR, SET_REQ_SUCCESS, UV_HANDLE_LISTENING, and uv_insert_pending_req().

Referenced by uv_pipe_accept(), uv_pipe_listen(), and uv_process_pipe_accept_req().

◆ uv_pipe_queue_read()

static void uv_pipe_queue_read ( uv_loop_t loop,
uv_pipe_t handle 
)
static

Definition at line 1112 of file pipe.c.

1112  {
1113  uv_read_t* req;
1114  int result;
1115 
1116  assert(handle->flags & UV_HANDLE_READING);
1117  assert(!(handle->flags & UV_HANDLE_READ_PENDING));
1118 
1119  assert(handle->handle != INVALID_HANDLE_VALUE);
1120 
1121  req = &handle->read_req;
1122 
1123  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) {
1124  handle->pipe.conn.readfile_thread_handle = NULL; /* Reset cancellation. */
1125  if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc,
1126  req,
1127  WT_EXECUTELONGFUNCTION)) {
1128  /* Make this req pending reporting an error. */
1129  SET_REQ_ERROR(req, GetLastError());
1130  goto error;
1131  }
1132  } else {
1133  memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped));
1134  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
1135  assert(req->event_handle != NULL);
1136  req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1);
1137  }
1138 
1139  /* Do 0-read */
1140  result = ReadFile(handle->handle,
1141  &uv_zero_,
1142  0,
1143  NULL,
1144  &req->u.io.overlapped);
1145 
1146  if (!result && GetLastError() != ERROR_IO_PENDING) {
1147  /* Make this req pending reporting an error. */
1148  SET_REQ_ERROR(req, GetLastError());
1149  goto error;
1150  }
1151 
1152  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
1153  if (req->wait_handle == INVALID_HANDLE_VALUE) {
1154  if (!RegisterWaitForSingleObject(&req->wait_handle,
1155  req->event_handle, post_completion_read_wait, (void*) req,
1156  INFINITE, WT_EXECUTEINWAITTHREAD)) {
1157  SET_REQ_ERROR(req, GetLastError());
1158  goto error;
1159  }
1160  }
1161  }
1162  }
1163 
1164  /* Start the eof timer if there is one */
1166  handle->flags |= UV_HANDLE_READ_PENDING;
1167  handle->reqs_pending++;
1168  return;
1169 
1170 error:
1172  handle->flags |= UV_HANDLE_READ_PENDING;
1173  handle->reqs_pending++;
1174 }
static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void *arg)
Definition: pipe.c:974
static void eof_timer_start(uv_pipe_t *pipe)
Definition: pipe.c:2013
static void CALLBACK post_completion_read_wait(void *context, BOOLEAN timed_out)
Definition: pipe.c:1074
static char uv_zero_[]
Definition: pipe.c:39

References assert(), eof_timer_start(), error(), handle, HANDLE, INVALID_HANDLE_VALUE, loop, memset(), NULL, post_completion_read_wait(), req, SET_REQ_ERROR, UV_HANDLE_EMULATE_IOCP, UV_HANDLE_NON_OVERLAPPED_PIPE, UV_HANDLE_READ_PENDING, UV_HANDLE_READING, uv_insert_pending_req(), uv_pipe_zero_readfile_thread_proc(), and uv_zero_.

Referenced by uv_pipe_read_start(), and uv_process_pipe_read_req().

◆ uv_pipe_read_eof()

static void uv_pipe_read_eof ( uv_loop_t loop,
uv_pipe_t handle,
uv_buf_t  buf 
)
static

Definition at line 1596 of file pipe.c.

1597  {
1598  /* If there is an eof timer running, we don't need it any more, so discard
1599  * it. */
1601 
1602  handle->flags &= ~UV_HANDLE_READABLE;
1604 
1605  handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf);
1606 }

References eof_timer_destroy(), handle, UV_HANDLE_READABLE, and uv_read_stop().

Referenced by eof_timer_cb(), and uv_pipe_read_error_or_eof().

◆ uv_pipe_read_error()

static void uv_pipe_read_error ( uv_loop_t loop,
uv_pipe_t handle,
int  error,
uv_buf_t  buf 
)
static

Definition at line 1609 of file pipe.c.

1610  {
1611  /* If there is an eof timer running, we don't need it any more, so discard
1612  * it. */
1614 
1616 
1618 }

References eof_timer_destroy(), error(), handle, uv_read_stop(), and uv_translate_sys_error().

Referenced by uv_pipe_read_error_or_eof().

◆ uv_pipe_read_error_or_eof()

static void uv_pipe_read_error_or_eof ( uv_loop_t loop,
uv_pipe_t handle,
int  error,
uv_buf_t  buf 
)
static

Definition at line 1621 of file pipe.c.

1622  {
1623  if (error == ERROR_BROKEN_PIPE) {
1625  } else {
1627  }
1628 }
static void uv_pipe_read_error(uv_loop_t *loop, uv_pipe_t *handle, int error, uv_buf_t buf)
Definition: pipe.c:1609

References error(), handle, loop, uv_pipe_read_eof(), and uv_pipe_read_error().

Referenced by uv__pipe_read_data(), uv__pipe_read_ipc(), and uv_process_pipe_read_req().

◆ uv_pipe_read_start()

int uv_pipe_read_start ( uv_pipe_t handle,
uv_alloc_cb  alloc_cb,
uv_read_cb  read_cb 
)

Definition at line 1177 of file pipe.c.

1179  {
1180  uv_loop_t* loop = handle->loop;
1181 
1182  handle->flags |= UV_HANDLE_READING;
1184  handle->read_cb = read_cb;
1185  handle->alloc_cb = alloc_cb;
1186 
1187  /* If reading was stopped and then started again, there could still be a read
1188  * request pending. */
1189  if (!(handle->flags & UV_HANDLE_READ_PENDING)) {
1190  if (handle->flags & UV_HANDLE_EMULATE_IOCP &&
1191  handle->read_req.event_handle == NULL) {
1192  handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
1193  if (handle->read_req.event_handle == NULL) {
1194  uv_fatal_error(GetLastError(), "CreateEvent");
1195  }
1196  }
1198  }
1199 
1200  return 0;
1201 }
static void uv_pipe_queue_read(uv_loop_t *loop, uv_pipe_t *handle)
Definition: pipe.c:1112

References handle, INCREASE_ACTIVE_COUNT, loop, NULL, uv_fatal_error(), UV_HANDLE_EMULATE_IOCP, UV_HANDLE_READ_PENDING, UV_HANDLE_READING, and uv_pipe_queue_read().

Referenced by uv_read_start().

◆ uv_pipe_writefile_thread_proc()

static DWORD WINAPI uv_pipe_writefile_thread_proc ( void *  parameter)
static

Definition at line 1047 of file pipe.c.

1047  {
1048  int result;
1049  DWORD bytes;
1050  uv_write_t* req = (uv_write_t*) parameter;
1051  uv_pipe_t* handle = (uv_pipe_t*) req->handle;
1052  uv_loop_t* loop = handle->loop;
1053 
1054  assert(req != NULL);
1055  assert(req->type == UV_WRITE);
1056  assert(handle->type == UV_NAMED_PIPE);
1057  assert(req->write_buffer.base);
1058 
1059  result = WriteFile(handle->handle,
1060  req->write_buffer.base,
1061  req->write_buffer.len,
1062  &bytes,
1063  NULL);
1064 
1065  if (!result) {
1066  SET_REQ_ERROR(req, GetLastError());
1067  }
1068 
1070  return 0;
1071 }

References assert(), bytes, DWORD, handle, loop, NULL, POST_COMPLETION_FOR_REQ, req, and SET_REQ_ERROR.

Referenced by uv_queue_non_overlapped_write().

◆ uv_pipe_zero_readfile_thread_proc()

static DWORD WINAPI uv_pipe_zero_readfile_thread_proc ( void *  arg)
static

Definition at line 974 of file pipe.c.

974  {
975  uv_read_t* req = (uv_read_t*) arg;
976  uv_pipe_t* handle = (uv_pipe_t*) req->data;
977  uv_loop_t* loop = handle->loop;
978  volatile HANDLE* thread_ptr = &handle->pipe.conn.readfile_thread_handle;
979  CRITICAL_SECTION* lock = &handle->pipe.conn.readfile_thread_lock;
980  HANDLE thread;
981  DWORD bytes;
982  DWORD err;
983 
984  assert(req->type == UV_READ);
985  assert(handle->type == UV_NAMED_PIPE);
986 
987  err = 0;
988 
989  /* Create a handle to the current thread. */
990  if (!DuplicateHandle(GetCurrentProcess(),
991  GetCurrentThread(),
992  GetCurrentProcess(),
993  &thread,
994  0,
995  FALSE,
996  DUPLICATE_SAME_ACCESS)) {
997  err = GetLastError();
998  goto out1;
999  }
1000 
1001  /* The lock needs to be held when thread handle is modified. */
1002  EnterCriticalSection(lock);
1003  if (*thread_ptr == INVALID_HANDLE_VALUE) {
1004  /* uv__pipe_interrupt_read() cancelled reading before we got here. */
1005  err = ERROR_OPERATION_ABORTED;
1006  } else {
1007  /* Let main thread know which worker thread is doing the blocking read. */
1008  assert(*thread_ptr == NULL);
1009  *thread_ptr = thread;
1010  }
1011  LeaveCriticalSection(lock);
1012 
1013  if (err)
1014  goto out2;
1015 
1016  /* Block the thread until data is available on the pipe, or the read is
1017  * cancelled. */
1018  if (!ReadFile(handle->handle, &uv_zero_, 0, &bytes, NULL))
1019  err = GetLastError();
1020 
1021  /* Let the main thread know the worker is past the point of blocking. */
1022  assert(thread == *thread_ptr);
1023  *thread_ptr = INVALID_HANDLE_VALUE;
1024 
1025  /* Briefly acquire the mutex. Since the main thread holds the lock while it
1026  * is spinning trying to cancel this thread's I/O, we will block here until
1027  * it stops doing that. */
1028  EnterCriticalSection(lock);
1029  LeaveCriticalSection(lock);
1030 
1031 out2:
1032  /* Close the handle to the current thread. */
1033  CloseHandle(thread);
1034 
1035 out1:
1036  /* Set request status and post a completion record to the IOCP. */
1037  if (err)
1038  SET_REQ_ERROR(req, err);
1039  else
1042 
1043  return 0;
1044 }
static void lock(volatile int *lk)
Definition: malloc.c:61

References assert(), bytes, DWORD, err, FALSE, handle, HANDLE, INVALID_HANDLE_VALUE, lock(), loop, NULL, POST_COMPLETION_FOR_REQ, req, SET_REQ_ERROR, SET_REQ_SUCCESS, and uv_zero_.

Referenced by uv_pipe_queue_read().

◆ uv_process_pipe_accept_req()

void uv_process_pipe_accept_req ( uv_loop_t loop,
uv_pipe_t handle,
uv_req_t raw_req 
)

Definition at line 1910 of file pipe.c.

1911  {
1912  uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req;
1913 
1914  assert(handle->type == UV_NAMED_PIPE);
1915 
1916  if (handle->flags & UV_HANDLE_CLOSING) {
1917  /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */
1918  assert(req->pipeHandle == INVALID_HANDLE_VALUE);
1920  return;
1921  }
1922 
1923  if (REQ_SUCCESS(req)) {
1924  assert(req->pipeHandle != INVALID_HANDLE_VALUE);
1925  req->next_pending = handle->pipe.serv.pending_accepts;
1926  handle->pipe.serv.pending_accepts = req;
1927 
1928  if (handle->stream.serv.connection_cb) {
1929  handle->stream.serv.connection_cb((uv_stream_t*)handle, 0);
1930  }
1931  } else {
1932  if (req->pipeHandle != INVALID_HANDLE_VALUE) {
1933  CloseHandle(req->pipeHandle);
1934  req->pipeHandle = INVALID_HANDLE_VALUE;
1935  }
1936  if (!(handle->flags & UV_HANDLE_CLOSING)) {
1938  }
1939  }
1940 
1942 }
#define REQ_SUCCESS(req)
Definition: req-inl.h:46

References assert(), DECREASE_PENDING_REQ_COUNT, FALSE, handle, INVALID_HANDLE_VALUE, loop, req, REQ_SUCCESS, UV_HANDLE_CLOSING, and uv_pipe_queue_accept().

◆ uv_process_pipe_connect_req()

void uv_process_pipe_connect_req ( uv_loop_t loop,
uv_pipe_t handle,
uv_connect_t req 
)

Definition at line 1945 of file pipe.c.

1946  {
1947  int err;
1948 
1949  assert(handle->type == UV_NAMED_PIPE);
1950 
1952 
1953  if (req->cb) {
1954  err = 0;
1955  if (REQ_SUCCESS(req)) {
1957  } else {
1958  err = GET_REQ_ERROR(req);
1959  }
1961  }
1962 
1964 }
#define GET_REQ_ERROR(req)
Definition: req-inl.h:49

References assert(), DECREASE_PENDING_REQ_COUNT, err, GET_REQ_ERROR, handle, loop, req, REQ_SUCCESS, UNREGISTER_HANDLE_REQ, uv_pipe_connection_init(), and uv_translate_sys_error().

◆ uv_process_pipe_read_req()

void uv_process_pipe_read_req ( uv_loop_t loop,
uv_pipe_t handle,
uv_req_t req 
)

Definition at line 1789 of file pipe.c.

1791  {
1792  assert(handle->type == UV_NAMED_PIPE);
1793 
1797 
1798  /* At this point, we're done with bookkeeping. If the user has stopped
1799  * reading the pipe in the meantime, there is nothing left to do, since there
1800  * is no callback that we can call. */
1801  if (!(handle->flags & UV_HANDLE_READING))
1802  return;
1803 
1804  if (!REQ_SUCCESS(req)) {
1805  /* An error occurred doing the zero-read. */
1807 
1808  /* If the read was cancelled by uv__pipe_interrupt_read(), the request may
1809  * indicate an ERROR_OPERATION_ABORTED error. This error isn't relevant to
1810  * the user; we'll start a new zero-read at the end of this function. */
1811  if (err != ERROR_OPERATION_ABORTED)
1813 
1814  } else {
1815  /* The zero-read completed without error, indicating there is data
1816  * available in the kernel buffer. */
1817  DWORD avail;
1818 
1819  /* Get the number of bytes available. */
1820  avail = 0;
1821  if (!PeekNamedPipe(handle->handle, NULL, 0, NULL, &avail, NULL))
1823 
1824  /* Read until we've either read all the bytes available, or the 'reading'
1825  * flag is cleared. */
1826  while (avail > 0 && handle->flags & UV_HANDLE_READING) {
1827  /* Depending on the type of pipe, read either IPC frames or raw data. */
1828  DWORD bytes_read =
1830  : uv__pipe_read_data(loop, handle, avail, (DWORD) -1);
1831 
1832  /* If no bytes were read, treat this as an indication that an error
1833  * occurred, and break out of the read loop. */
1834  if (bytes_read == 0)
1835  break;
1836 
1837  /* It is possible that more bytes were read than we thought were
1838  * available. To prevent `avail` from underflowing, break out of the loop
1839  * if this is the case. */
1840  if (bytes_read > avail)
1841  break;
1842 
1843  /* Recompute the number of bytes available. */
1844  avail -= bytes_read;
1845  }
1846  }
1847 
1848  /* Start another zero-read request if necessary. */
1849  if ((handle->flags & UV_HANDLE_READING) &&
1850  !(handle->flags & UV_HANDLE_READ_PENDING)) {
1852  }
1853 }
static void eof_timer_stop(uv_pipe_t *pipe)
Definition: pipe.c:2022
static DWORD uv__pipe_read_ipc(uv_loop_t *loop, uv_pipe_t *handle)
Definition: pipe.c:1708

References assert(), DECREASE_PENDING_REQ_COUNT, DWORD, eof_timer_stop(), err, GET_REQ_ERROR, handle, loop, NULL, req, REQ_SUCCESS, uv__pipe_read_data(), uv__pipe_read_ipc(), UV_HANDLE_CANCELLATION_PENDING, UV_HANDLE_READ_PENDING, UV_HANDLE_READING, uv_null_buf_, uv_pipe_queue_read(), and uv_pipe_read_error_or_eof().

◆ uv_process_pipe_shutdown_req()

void uv_process_pipe_shutdown_req ( uv_loop_t loop,
uv_pipe_t handle,
uv_shutdown_t req 
)

Definition at line 1967 of file pipe.c.

1968  {
1969  assert(handle->type == UV_NAMED_PIPE);
1970 
1972 
1973  if (handle->flags & UV_HANDLE_READABLE) {
1974  /* Initialize and optionally start the eof timer. Only do this if the pipe
1975  * is readable and we haven't seen EOF come in ourselves. */
1977 
1978  /* If reading start the timer right now. Otherwise uv_pipe_queue_read will
1979  * start it. */
1980  if (handle->flags & UV_HANDLE_READ_PENDING) {
1982  }
1983 
1984  } else {
1985  /* This pipe is not readable. We can just close it to let the other end
1986  * know that we're done writing. */
1987  close_pipe(handle);
1988  }
1989 
1990  if (req->cb) {
1991  req->cb(req, 0);
1992  }
1993 
1995 }
static void eof_timer_init(uv_pipe_t *pipe)
Definition: pipe.c:1998

References assert(), close_pipe(), DECREASE_PENDING_REQ_COUNT, eof_timer_init(), eof_timer_start(), handle, loop, req, UNREGISTER_HANDLE_REQ, UV_HANDLE_READ_PENDING, and UV_HANDLE_READABLE.

Referenced by uv_process_reqs().

◆ uv_process_pipe_write_req()

void uv_process_pipe_write_req ( uv_loop_t loop,
uv_pipe_t handle,
uv_write_t req 
)

Definition at line 1856 of file pipe.c.

1857  {
1858  int err;
1859 
1860  assert(handle->type == UV_NAMED_PIPE);
1861 
1862  assert(handle->write_queue_size >= req->u.io.queued_bytes);
1863  handle->write_queue_size -= req->u.io.queued_bytes;
1864 
1866 
1867  if (handle->flags & UV_HANDLE_EMULATE_IOCP) {
1868  if (req->wait_handle != INVALID_HANDLE_VALUE) {
1869  UnregisterWait(req->wait_handle);
1870  req->wait_handle = INVALID_HANDLE_VALUE;
1871  }
1872  if (req->event_handle) {
1873  CloseHandle(req->event_handle);
1874  req->event_handle = NULL;
1875  }
1876  }
1877 
1878  err = GET_REQ_ERROR(req);
1879 
1880  /* If this was a coalesced write, extract pointer to the user_provided
1881  * uv_write_t structure so we can pass the expected pointer to the callback,
1882  * then free the heap-allocated write req. */
1883  if (req->coalesced) {
1884  uv__coalesced_write_t* coalesced_write =
1886  req = coalesced_write->user_req;
1887  uv__free(coalesced_write);
1888  }
1889  if (req->cb) {
1891  }
1892 
1893  handle->stream.conn.write_reqs_pending--;
1894 
1895  if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE &&
1896  handle->pipe.conn.non_overlapped_writes_tail) {
1897  assert(handle->stream.conn.write_reqs_pending > 0);
1899  }
1900 
1901  if (handle->stream.conn.shutdown_req != NULL &&
1902  handle->stream.conn.write_reqs_pending == 0) {
1904  }
1905 
1907 }
#define container_of(ptr, type, member)
Definition: rz_types.h:650

References assert(), container_of, DECREASE_PENDING_REQ_COUNT, err, GET_REQ_ERROR, handle, INVALID_HANDLE_VALUE, loop, NULL, req, UNREGISTER_HANDLE_REQ, uv__coalesced_write_t::user_req, uv__free(), UV_HANDLE_EMULATE_IOCP, UV_HANDLE_NON_OVERLAPPED_PIPE, uv_queue_non_overlapped_write(), uv_translate_sys_error(), and uv_want_endgame().

◆ uv_queue_non_overlapped_write()

static void uv_queue_non_overlapped_write ( uv_pipe_t handle)
static

Definition at line 1240 of file pipe.c.

1240  {
1242  if (req) {
1243  if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc,
1244  req,
1245  WT_EXECUTELONGFUNCTION)) {
1246  uv_fatal_error(GetLastError(), "QueueUserWorkItem");
1247  }
1248  }
1249 }
static DWORD WINAPI uv_pipe_writefile_thread_proc(void *parameter)
Definition: pipe.c:1047
static uv_write_t * uv_remove_non_overlapped_write_req(uv_pipe_t *handle)
Definition: pipe.c:1219

References handle, req, uv_fatal_error(), uv_pipe_writefile_thread_proc(), and uv_remove_non_overlapped_write_req().

Referenced by uv__pipe_write_data(), and uv_process_pipe_write_req().

◆ uv_remove_non_overlapped_write_req()

static uv_write_t* uv_remove_non_overlapped_write_req ( uv_pipe_t handle)
static

Definition at line 1219 of file pipe.c.

1219  {
1220  uv_write_t* req;
1221 
1222  if (handle->pipe.conn.non_overlapped_writes_tail) {
1223  req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req;
1224 
1225  if (req == handle->pipe.conn.non_overlapped_writes_tail) {
1226  handle->pipe.conn.non_overlapped_writes_tail = NULL;
1227  } else {
1228  handle->pipe.conn.non_overlapped_writes_tail->next_req =
1229  req->next_req;
1230  }
1231 
1232  return req;
1233  } else {
1234  /* queue empty */
1235  return NULL;
1236  }
1237 }
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References handle, if(), NULL, and req.

Referenced by uv_queue_non_overlapped_write().

◆ uv_set_pipe_handle()

static int uv_set_pipe_handle ( uv_loop_t loop,
uv_pipe_t handle,
HANDLE  pipeHandle,
int  fd,
DWORD  duplex_flags 
)
static

Definition at line 254 of file pipe.c.

258  {
259  NTSTATUS nt_status;
260  IO_STATUS_BLOCK io_status;
261  FILE_MODE_INFORMATION mode_info;
262  DWORD mode = PIPE_READMODE_BYTE | PIPE_WAIT;
263  DWORD current_mode = 0;
264  DWORD err = 0;
265 
266  if (handle->flags & UV_HANDLE_PIPESERVER)
267  return UV_EINVAL;
268  if (handle->handle != INVALID_HANDLE_VALUE)
269  return UV_EBUSY;
270 
271  if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
272  err = GetLastError();
273  if (err == ERROR_ACCESS_DENIED) {
274  /*
275  * SetNamedPipeHandleState can fail if the handle doesn't have either
276  * GENERIC_WRITE or FILE_WRITE_ATTRIBUTES.
277  * But if the handle already has the desired wait and blocking modes
278  * we can continue.
279  */
280  if (!GetNamedPipeHandleState(pipeHandle, &current_mode, NULL, NULL,
281  NULL, NULL, 0)) {
282  return -1;
283  } else if (current_mode & PIPE_NOWAIT) {
284  SetLastError(ERROR_ACCESS_DENIED);
285  return -1;
286  }
287  } else {
288  /* If this returns ERROR_INVALID_PARAMETER we probably opened
289  * something that is not a pipe. */
290  if (err == ERROR_INVALID_PARAMETER) {
291  SetLastError(WSAENOTSOCK);
292  }
293  return -1;
294  }
295  }
296 
297  /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */
298  nt_status = pNtQueryInformationFile(pipeHandle,
299  &io_status,
300  &mode_info,
301  sizeof(mode_info),
303  if (nt_status != STATUS_SUCCESS) {
304  return -1;
305  }
306 
307  if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT ||
308  mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) {
309  /* Non-overlapped pipe. */
311  } else {
312  /* Overlapped pipe. Try to associate with IOCP. */
313  if (CreateIoCompletionPort(pipeHandle,
314  loop->iocp,
315  (ULONG_PTR) handle,
316  0) == NULL) {
317  handle->flags |= UV_HANDLE_EMULATE_IOCP;
318  }
319  }
320 
321  handle->handle = pipeHandle;
322  handle->u.fd = fd;
323  handle->flags |= duplex_flags;
324 
325  return 0;
326 }
@ FileModeInformation
Definition: winapi.h:4187
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: winapi.h:4340
#define FILE_SYNCHRONOUS_IO_ALERT
Definition: winapi.h:4339
static const z80_opcode fd[]
Definition: z80_tab.h:997

References DWORD, err, fd, FILE_SYNCHRONOUS_IO_ALERT, FILE_SYNCHRONOUS_IO_NONALERT, FileModeInformation, handle, INVALID_HANDLE_VALUE, loop, _FILE_MODE_INFORMATION::Mode, NULL, pNtQueryInformationFile, STATUS_SUCCESS, UV_HANDLE_EMULATE_IOCP, UV_HANDLE_NON_OVERLAPPED_PIPE, and UV_HANDLE_PIPESERVER.

Referenced by pipe_connect_thread_proc(), uv_pipe_connect(), and uv_pipe_open().

◆ uv_stdio_pipe_server()

int uv_stdio_pipe_server ( uv_loop_t loop,
uv_pipe_t handle,
DWORD  access,
char *  name,
size_t  nameSize 
)

Definition at line 205 of file pipe.c.

206  {
207  HANDLE pipeHandle;
208  int err;
209  char* ptr = (char*)handle;
210 
211  for (;;) {
212  uv_unique_pipe_name(ptr, name, nameSize);
213 
214  pipeHandle = CreateNamedPipeA(name,
215  access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
216  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
217  NULL);
218 
219  if (pipeHandle != INVALID_HANDLE_VALUE) {
220  /* No name collisions. We're done. */
221  break;
222  }
223 
224  err = GetLastError();
225  if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) {
226  goto error;
227  }
228 
229  /* Pipe name collision. Increment the pointer and try again. */
230  ptr++;
231  }
232 
233  if (CreateIoCompletionPort(pipeHandle,
234  loop->iocp,
235  (ULONG_PTR)handle,
236  0) == NULL) {
237  err = GetLastError();
238  goto error;
239  }
240 
242  handle->handle = pipeHandle;
243 
244  return 0;
245 
246  error:
247  if (pipeHandle != INVALID_HANDLE_VALUE)
248  CloseHandle(pipeHandle);
249 
250  return err;
251 }
static void uv_unique_pipe_name(char *ptr, char *name, size_t size)
Definition: pipe.c:101

References access, err, error(), handle, HANDLE, INVALID_HANDLE_VALUE, loop, NULL, uv_pipe_connection_init(), and uv_unique_pipe_name().

Referenced by uv__create_stdio_pipe_pair().

◆ uv_unique_pipe_name()

static void uv_unique_pipe_name ( char *  ptr,
char *  name,
size_t  size 
)
static

Definition at line 101 of file pipe.c.

101  {
102  snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId());
103 }
snprintf
Definition: kernel.h:364

References snprintf.

Referenced by uv_stdio_pipe_server().

Variable Documentation

◆ default_pending_pipe_instances

const int default_pending_pipe_instances = 4
static

Definition at line 48 of file pipe.c.

Referenced by uv_pipe_bind().

◆ eof_timeout

const int64_t eof_timeout = 50
static

Definition at line 46 of file pipe.c.

Referenced by eof_timer_start().

◆ pipe_prefix

char pipe_prefix[] = "\\\\?\\pipe"
static

Definition at line 51 of file pipe.c.

Referenced by uv__pipe_getname().

◆ pipe_prefix_len

const int pipe_prefix_len = sizeof(pipe_prefix) - 1
static

Definition at line 52 of file pipe.c.

Referenced by uv__pipe_getname().

◆ uv_null_buf_

const uv_buf_t uv_null_buf_ = { 0, NULL }
static

◆ uv_zero_

char uv_zero_[] = ""
static

Definition at line 39 of file pipe.c.

Referenced by uv_pipe_queue_read(), and uv_pipe_zero_readfile_thread_proc().