コード例 #1
0
ファイル: pipe.c プロジェクト: diffidentDude/node
/* Starts listening for connections for the given pipe. */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
  int i, errno;
  uv_pipe_accept_t* req;
  HANDLE pipeHandle;

  if (handle->flags & UV_HANDLE_BIND_ERROR) {
    uv_set_error(UV_EINVAL, 0);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_BOUND) && 
      !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
    uv_set_error(UV_EINVAL, 0);
    return -1;
  }

  if (handle->flags & UV_HANDLE_LISTENING ||
      handle->flags & UV_HANDLE_READING) {
    uv_set_error(UV_EALREADY, 0);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_PIPESERVER) && 
      !(handle->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
    uv_set_error(UV_ENOTSUP, 0);
    return -1;
  }

  handle->flags |= UV_HANDLE_LISTENING;
  handle->connection_cb = cb;

  if (handle->flags & UV_HANDLE_GIVEN_OS_HANDLE) {
    handle->flags |= UV_HANDLE_PIPESERVER;
    pipeHandle = handle->handle;
    assert(pipeHandle != INVALID_HANDLE_VALUE);
    req = &handle->accept_reqs[0];
    uv_req_init((uv_req_t*) req);
    req->pipeHandle = pipeHandle;
    req->type = UV_ACCEPT;
    req->data = handle;
    req->next_pending = NULL;

    if (uv_set_pipe_handle(handle, pipeHandle)) {
      uv_set_sys_error(GetLastError());
      return -1;
    }

    uv_pipe_queue_accept(handle, req, TRUE);
  } else {
    /* First pipe handle should have already been created in uv_pipe_bind */
    assert(handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE);

    for (i = 0; i < COUNTOF(handle->accept_reqs); i++) {
      uv_pipe_queue_accept(handle, &handle->accept_reqs[i], i == 0);
    }
  }

  return 0;
}
コード例 #2
0
ファイル: pipe.c プロジェクト: diffidentDude/node
static void uv_pipe_queue_accept(uv_pipe_t* handle, uv_pipe_accept_t* req, BOOL firstInstance) {
  assert(handle->flags & UV_HANDLE_LISTENING);

  if (!firstInstance) {
    assert(req->pipeHandle == INVALID_HANDLE_VALUE);

    req->pipeHandle = CreateNamedPipeW(handle->name,
                                       PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
                                       PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                                       PIPE_UNLIMITED_INSTANCES,
                                       65536,
                                       65536,
                                       0,
                                       NULL);

    if (req->pipeHandle == INVALID_HANDLE_VALUE) {
      req->error = uv_new_sys_error(GetLastError());
      uv_insert_pending_req((uv_req_t*) req);
      handle->reqs_pending++;
      return;
    }

    if (uv_set_pipe_handle(handle, req->pipeHandle)) {
      CloseHandle(req->pipeHandle);
      req->pipeHandle = INVALID_HANDLE_VALUE;
      req->error = uv_new_sys_error(GetLastError());
      uv_insert_pending_req((uv_req_t*) req);
      handle->reqs_pending++;
      return;
    }
  }

  assert(req->pipeHandle != INVALID_HANDLE_VALUE);

  /* Prepare the overlapped structure. */
  memset(&(req->overlapped), 0, sizeof(req->overlapped));

  if (!ConnectNamedPipe(req->pipeHandle, &req->overlapped) && GetLastError() != ERROR_IO_PENDING) {
    if (GetLastError() == ERROR_PIPE_CONNECTED) {
      req->error = uv_ok_;
    } else {
      CloseHandle(req->pipeHandle);
      req->pipeHandle = INVALID_HANDLE_VALUE;
      /* Make this req pending reporting an error. */
      req->error = uv_new_sys_error(GetLastError());
    }
    uv_insert_pending_req((uv_req_t*) req);
    handle->reqs_pending++;
    return;
  }

  handle->reqs_pending++;
}
コード例 #3
0
ファイル: pipe.c プロジェクト: diffidentDude/node
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  int errno;
  uv_pipe_t* handle;
  uv_connect_t* req;

  req = (uv_connect_t*)parameter;
  assert(req);
  handle = (uv_pipe_t*)req->handle;
  assert(handle);

  /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY.  We wait for the pipe to become available with WaitNamedPipe. */
  while (WaitNamedPipeW(handle->name, 30000)) {
    /* The pipe is now available, try to connect. */
    pipeHandle = CreateFileW(handle->name,
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED,
                            NULL);

    if (pipeHandle != INVALID_HANDLE_VALUE) {
      break;
    }
  }

  if (pipeHandle != INVALID_HANDLE_VALUE && !uv_set_pipe_handle(handle, pipeHandle)) {
    handle->handle = pipeHandle;
    req->error = uv_ok_;
  } else {
    req->error = uv_new_sys_error(GetLastError());
  }

  memset(&req->overlapped, 0, sizeof(req->overlapped));

  /* Post completed */
  if (!PostQueuedCompletionStatus(LOOP->iocp,
                                0,
                                0,
                                &req->overlapped)) {
    uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus");
  }

  return 0;
}
コード例 #4
0
ファイル: pipe.c プロジェクト: MikeKulick/node
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  int errno;
  uv_loop_t* loop;
  uv_pipe_t* handle;
  uv_connect_t* req;

  req = (uv_connect_t*) parameter;
  assert(req);
  handle = (uv_pipe_t*) req->handle;
  assert(handle);
  loop = handle->loop;
  assert(loop);

  /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
  /* We wait for the pipe to become available with WaitNamedPipe. */
  while (WaitNamedPipeW(handle->name, 30000)) {
    /* The pipe is now available, try to connect. */
    pipeHandle = CreateFileW(handle->name,
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            FILE_FLAG_OVERLAPPED,
                            NULL);

    if (pipeHandle != INVALID_HANDLE_VALUE) {
      break;
    }

    SwitchToThread();
  }

  if (pipeHandle != INVALID_HANDLE_VALUE &&
      !uv_set_pipe_handle(loop, handle, pipeHandle)) {
    handle->handle = pipeHandle;
    SET_REQ_SUCCESS(req);
  } else {
    SET_REQ_ERROR(req, GetLastError());
  }

  /* Post completed */
  POST_COMPLETION_FOR_REQ(loop, req);

  return 0;
}
コード例 #5
0
ファイル: pipe.c プロジェクト: MikeKulick/node
void uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
  HANDLE os_handle = (HANDLE)_get_osfhandle(file);

  if (os_handle == INVALID_HANDLE_VALUE ||
      uv_set_pipe_handle(pipe->loop, pipe, os_handle) == -1) {
    return;
  }

  uv_pipe_connection_init(pipe);
  pipe->handle = os_handle;

  if (pipe->ipc) {
    assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
    pipe->ipc_pid = uv_parent_pid();
    assert(pipe->ipc_pid != -1);
  }
}
コード例 #6
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
int uv_pipe_open(uv_pipe_t* pipe, uv_file file) {
  HANDLE os_handle = (HANDLE)_get_osfhandle(file);

  if (os_handle == INVALID_HANDLE_VALUE ||
      uv_set_pipe_handle(pipe->loop, pipe, os_handle, 0) == -1) {
    uv__set_sys_error(pipe->loop, WSAEINVAL);
    return -1;
  }

  uv_pipe_connection_init(pipe);
  pipe->handle = os_handle;
  pipe->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE;

  if (pipe->ipc) {
    assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE));
    pipe->ipc_pid = uv_parent_pid();
    assert(pipe->ipc_pid != -1);
  }
  return 0;
}
コード例 #7
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
static DWORD WINAPI pipe_connect_thread_proc(void* parameter) {
  uv_loop_t* loop;
  uv_pipe_t* handle;
  uv_connect_t* req;
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  DWORD duplex_flags;

  req = (uv_connect_t*) parameter;
  assert(req);
  handle = (uv_pipe_t*) req->handle;
  assert(handle);
  loop = handle->loop;
  assert(loop);

  /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */
  /* We wait for the pipe to become available with WaitNamedPipe. */
  while (WaitNamedPipeW(handle->name, 30000)) {
    /* The pipe is now available, try to connect. */
    pipeHandle = open_named_pipe(handle->name, &duplex_flags);
    if (pipeHandle != INVALID_HANDLE_VALUE) {
      break;
    }

    SwitchToThread();
  }

  if (pipeHandle != INVALID_HANDLE_VALUE &&
      !uv_set_pipe_handle(loop, handle, pipeHandle, duplex_flags)) {
    SET_REQ_SUCCESS(req);
  } else {
    SET_REQ_ERROR(req, GetLastError());
  }

  /* Post completed */
  POST_COMPLETION_FOR_REQ(loop, req);

  return 0;
}
コード例 #8
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int errorno, nameSize;
  HANDLE pipeHandle = INVALID_HANDLE_VALUE;
  DWORD duplex_flags;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
  handle->name = (WCHAR*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
    errorno = GetLastError();
    goto error;
  }

  pipeHandle = open_named_pipe(handle->name, &duplex_flags);
  if (pipeHandle == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
                             req,
                             WT_EXECUTELONGFUNCTION)) {
        errorno = GetLastError();
        goto error;
      }

      REGISTER_HANDLE_REQ(loop, handle, req);
      handle->reqs_pending++;

      return;
    }

    errorno = GetLastError();
    goto error;
  }

  assert(pipeHandle != INVALID_HANDLE_VALUE);

  if (uv_set_pipe_handle(loop,
                         (uv_pipe_t*) req->handle,
                         pipeHandle,
                         duplex_flags)) {
    errorno = GetLastError();
    goto error;
  }

  SET_REQ_SUCCESS(req);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }

  /* Make this req pending reporting an error. */
  SET_REQ_ERROR(req, errorno);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  REGISTER_HANDLE_REQ(loop, handle, req);
  return;
}
コード例 #9
0
ファイル: pipe.c プロジェクト: Cycle-Applications/node
/* Creates a pipe server. */
int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
  uv_loop_t* loop = handle->loop;
  int i, errorno, nameSize;
  uv_pipe_accept_t* req;

  if (handle->flags & UV_HANDLE_BOUND) {
    uv__set_sys_error(loop, WSAEINVAL);
    return -1;
  }

  if (!name) {
    uv__set_sys_error(loop, WSAEINVAL);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_PIPESERVER)) {
    handle->pending_instances = default_pending_pipe_instances;
  }

  handle->accept_reqs = (uv_pipe_accept_t*)
    malloc(sizeof(uv_pipe_accept_t) * handle->pending_instances);
  if (!handle->accept_reqs) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  for (i = 0; i < handle->pending_instances; i++) {
    req = &handle->accept_reqs[i];
    uv_req_init(loop, (uv_req_t*) req);
    req->type = UV_ACCEPT;
    req->data = handle;
    req->pipeHandle = INVALID_HANDLE_VALUE;
    req->next_pending = NULL;
  }

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(WCHAR);
  handle->name = (WCHAR*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(WCHAR))) {
    uv__set_sys_error(loop, GetLastError());
    return -1;
  }

  /*
   * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE.
   * If this fails then there's already a pipe server for the given pipe name.
   */
  handle->accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name,
      PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
      FILE_FLAG_FIRST_PIPE_INSTANCE,
      PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
      PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);

  if (handle->accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) {
    errorno = GetLastError();
    if (errorno == ERROR_ACCESS_DENIED) {
      uv__set_error(loop, UV_EADDRINUSE, errorno);
    } else if (errorno == ERROR_PATH_NOT_FOUND || errorno == ERROR_INVALID_NAME) {
      uv__set_error(loop, UV_EACCES, errorno);
    } else {
      uv__set_sys_error(loop, errorno);
    }
    goto error;
  }

  if (uv_set_pipe_handle(loop, handle, handle->accept_reqs[0].pipeHandle, 0)) {
    uv__set_sys_error(loop, GetLastError());
    goto error;
  }

  handle->pending_accepts = NULL;
  handle->flags |= UV_HANDLE_PIPESERVER;
  handle->flags |= UV_HANDLE_BOUND;

  return 0;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (handle->accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->accept_reqs[0].pipeHandle);
    handle->accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE;
  }

  return -1;
}
コード例 #10
0
ファイル: pipe.c プロジェクト: diffidentDude/node
int uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  int errno, nameSize;
  HANDLE pipeHandle;

  handle->handle = INVALID_HANDLE_VALUE;

  uv_req_init((uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
  handle->name = (wchar_t*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
    errno = GetLastError();
    goto error;
  }

  pipeHandle = CreateFileW(handle->name,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          FILE_FLAG_OVERLAPPED,
                          NULL);

  if (pipeHandle == INVALID_HANDLE_VALUE) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
        errno = GetLastError();
        goto error;
      }

      return 0;
    }

    errno = GetLastError();
    goto error;
  }

  if (uv_set_pipe_handle((uv_pipe_t*)req->handle, pipeHandle)) {
    errno = GetLastError();
    goto error;
  }

  handle->handle = pipeHandle;

  req->error = uv_ok_;
  uv_insert_pending_req((uv_req_t*) req);
  handle->reqs_pending++;
  return 0;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }
  uv_set_sys_error(errno);
  return -1;
}
コード例 #11
0
ファイル: pipe.c プロジェクト: 337240552/node
void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle,
    const char* name, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int errno, nameSize;

  handle->handle = INVALID_HANDLE_VALUE;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;

  /* Convert name to UTF16. */
  nameSize = uv_utf8_to_utf16(name, NULL, 0) * sizeof(wchar_t);
  handle->name = (wchar_t*)malloc(nameSize);
  if (!handle->name) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  if (!uv_utf8_to_utf16(name, handle->name, nameSize / sizeof(wchar_t))) {
    errno = GetLastError();
    goto error;
  }

  if (open_named_pipe(handle) != 0) {
    if (GetLastError() == ERROR_PIPE_BUSY) {
      /* Wait for the server to make a pipe instance available. */
      if (!QueueUserWorkItem(&pipe_connect_thread_proc,
                             req,
                             WT_EXECUTELONGFUNCTION)) {
        errno = GetLastError();
        goto error;
      }

      handle->reqs_pending++;

      return;
    }

    errno = GetLastError();
    goto error;
  }

  assert(handle->handle != INVALID_HANDLE_VALUE);

  /* Ensure that what we just opened is actually a pipe */
  if (!GetNamedPipeInfo(handle->handle, NULL, NULL, NULL, NULL)) {
    errno = WSAENOTSOCK;
    goto error;
  }

  if (uv_set_pipe_handle(loop, (uv_pipe_t*)req->handle, handle->handle)) {
    errno = GetLastError();
    goto error;
  }

  SET_REQ_SUCCESS(req);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  return;

error:
  if (handle->name) {
    free(handle->name);
    handle->name = NULL;
  }

  if (handle->handle != INVALID_HANDLE_VALUE) {
    CloseHandle(handle->handle);
    handle->handle = INVALID_HANDLE_VALUE;
  }

  /* Make this req pending reporting an error. */
  SET_REQ_ERROR(req, errno);
  uv_insert_pending_req(loop, (uv_req_t*) req);
  handle->reqs_pending++;
  return;
}