예제 #1
0
파일: tcp.c 프로젝트: irca/libuv
int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
  if (!(handle->flags & UV_HANDLE_CONNECTION)) {
    uv_set_sys_error(WSAEINVAL);
    return -1;
  }

  if (handle->flags & UV_HANDLE_READING) {
    uv_set_sys_error(WSAEALREADY);
    return -1;
  }

  if (handle->flags & UV_HANDLE_EOF) {
    uv_set_sys_error(WSAESHUTDOWN);
    return -1;
  }

  handle->flags |= UV_HANDLE_READING;
  handle->read_cb = read_cb;
  handle->alloc_cb = alloc_cb;

  /* If reading was stopped and then started again, there could stell be a */
  /* read request pending. */
  if (!(handle->flags & UV_HANDLE_READ_PENDING))
    uv_tcp_queue_read(handle);

  return 0;
}
예제 #2
0
static int duplicate_std_handle(uv_loop_t* loop, DWORD id, HANDLE* dup) {
  HANDLE handle;
  HANDLE current_process = GetCurrentProcess();
  
  handle = GetStdHandle(id);

  if (handle == NULL) {
    *dup = NULL;
    return 0;
  } else if (handle == INVALID_HANDLE_VALUE) {
    *dup = INVALID_HANDLE_VALUE;
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  if (!DuplicateHandle(current_process,
                       handle,
                       current_process,
                       dup,
                       0,
                       TRUE,
                       DUPLICATE_SAME_ACCESS)) {
    *dup = INVALID_HANDLE_VALUE;
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  return 0;
}
예제 #3
0
파일: pipe.c 프로젝트: diffidentDude/node
int uv_stdio_pipe_server(uv_pipe_t* handle, DWORD access, char* name, size_t nameSize) {
  HANDLE pipeHandle;
  int errno;
  int err;
  char* ptr = (char*)handle;

  while (TRUE) {
    uv_unique_pipe_name(ptr, name, nameSize);

    pipeHandle = CreateNamedPipeA(name,
                                  access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE,
                                  PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
                                  1,
                                  65536,
                                  65536,
                                  0,
                                  NULL);

    if (pipeHandle != INVALID_HANDLE_VALUE) {
      /* No name collisions.  We're done. */
      break;
    }

    errno = GetLastError();
    if (errno != ERROR_PIPE_BUSY && errno != ERROR_ACCESS_DENIED) {
      uv_set_sys_error(errno);
      err = -1;
      goto done;
    }

    /* Pipe name collision.  Increment the pointer and try again. */
    ptr++;
  }

  if (CreateIoCompletionPort(pipeHandle,
                             LOOP->iocp,
                             (ULONG_PTR)handle,
                             0) == NULL) {
    uv_set_sys_error(GetLastError());
    err = -1;
    goto done;
  }

  uv_connection_init((uv_stream_t*)handle);
  handle->handle = pipeHandle;
  handle->flags |= UV_HANDLE_GIVEN_OS_HANDLE;
  err = 0;

done:
  if (err && pipeHandle != INVALID_HANDLE_VALUE) {
    CloseHandle(pipeHandle);
  }

  return err;
}
예제 #4
0
파일: udp.c 프로젝트: DrPizza/node
static int uv__bind(uv_udp_t* handle, int domain, struct sockaddr* addr,
    int addrsize, unsigned int flags) {
  uv_loop_t* loop = handle->loop;
  DWORD err;
  int r;
  SOCKET sock;

  if ((flags & UV_UDP_IPV6ONLY) && domain != AF_INET6) {
    /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */
    uv_set_sys_error(loop, UV_EINVAL);
  }

  if (handle->socket == INVALID_SOCKET) {
    sock = socket(domain, SOCK_DGRAM, 0);
    if (sock == INVALID_SOCKET) {
      uv_set_sys_error(loop, WSAGetLastError());
      return -1;
    }

    if (uv_udp_set_socket(loop, handle, sock) == -1) {
      closesocket(sock);
      return -1;
    }
  }

  if (domain == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) {
    DWORD off = 0;
    /* On windows IPV6ONLY is on by default. */
    /* If the user doesn't specify it libuv turns it off. */

    /* TODO: how to handle errors? This may fail if there is no ipv4 stack */
    /* available, or when run on XP/2003 which have no support for dualstack */
    /* sockets. For now we're silently ignoring the error. */
    setsockopt(sock,
               IPPROTO_IPV6,
               IPV6_V6ONLY,
               (const char*) &off,
               sizeof off);
  }

  r = bind(handle->socket, addr, addrsize);

  if (r == SOCKET_ERROR) {
    err = WSAGetLastError();
    uv_set_sys_error(loop, WSAGetLastError());
    return -1;
  }

  handle->flags |= UV_HANDLE_BOUND;

  return 0;
}
예제 #5
0
파일: tcp.c 프로젝트: DrPizza/node
int uv_tcp_connect6(uv_connect_t* req, uv_tcp_t* handle,
    struct sockaddr_in6 address, uv_connect_cb cb) {
  uv_loop_t* loop = handle->loop;
  int addrsize = sizeof(struct sockaddr_in6);
  BOOL success;
  DWORD bytes;

  if (!uv_allow_ipv6) {
    uv_new_sys_error(WSAEAFNOSUPPORT);
    return -1;
  }

  if (handle->flags & UV_HANDLE_BIND_ERROR) {
    loop->last_error = handle->bind_error;
    return -1;
  }

  if (address.sin6_family != AF_INET6) {
    uv_set_sys_error(loop, WSAEFAULT);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_BOUND) &&
      uv_tcp_bind6(handle, uv_addr_ip6_any_) < 0)
    return -1;

  uv_req_init(loop, (uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  success = pConnectEx6(handle->socket,
                       (struct sockaddr*) &address,
                       addrsize,
                       NULL,
                       0,
                       &bytes,
                       &req->overlapped);

  if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
    handle->reqs_pending++;
    uv_insert_pending_req(loop, (uv_req_t*)req);
  } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
    handle->reqs_pending++;
  } else {
    uv_set_sys_error(loop, WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #6
0
파일: tty.c 프로젝트: hghazal/node
int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd) {
  HANDLE win_handle;
  CONSOLE_SCREEN_BUFFER_INFO info;

  win_handle = (HANDLE) _get_osfhandle(fd);
  if (win_handle == INVALID_HANDLE_VALUE) {
    uv_set_sys_error(loop, ERROR_INVALID_HANDLE);
    return -1;
  }

  if (!GetConsoleMode(win_handle, &tty->original_console_mode)) {
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  /* Initialize virtual window size; if it fails, assume that this is stdin. */
  if (GetConsoleScreenBufferInfo(win_handle, &info)) {
    EnterCriticalSection(&uv_tty_output_lock);
    uv_tty_update_virtual_window(&info);
    LeaveCriticalSection(&uv_tty_output_lock);
  }

  uv_stream_init(loop, (uv_stream_t*) tty);
  uv_connection_init((uv_stream_t*) tty);

  tty->type = UV_TTY;
  tty->handle = win_handle;
  tty->read_line_handle = NULL;
  tty->read_line_buffer = uv_null_buf_;
  tty->read_raw_wait = NULL;
  tty->reqs_pending = 0;
  tty->flags |= UV_HANDLE_BOUND;

  /* Init keycode-to-vt100 mapper state. */
  tty->last_key_len = 0;
  tty->last_key_offset = 0;
  tty->last_utf16_high_surrogate = 0;
  memset(&tty->last_input_record, 0, sizeof tty->last_input_record);

  /* Init utf8-to-utf16 conversion state. */
  tty->utf8_bytes_left = 0;
  tty->utf8_codepoint = 0;

  /* Initialize eol conversion state */
  tty->previous_eol = 0;

  /* Init ANSI parser state. */
  tty->ansi_parser_state = ANSI_NORMAL;

  return 0;
}
예제 #7
0
파일: tcp.c 프로젝트: DrPizza/node
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
  uv_loop_t* loop = handle->loop;
  unsigned int i;
  uv_tcp_accept_t* req;

  assert(backlog > 0);

  if (handle->flags & UV_HANDLE_BIND_ERROR) {
    loop->last_error = handle->bind_error;
    return -1;
  }

  if (handle->flags & UV_HANDLE_LISTENING ||
      handle->flags & UV_HANDLE_READING) {
    /* Already listening. */
    uv_set_sys_error(loop, WSAEALREADY);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_BOUND) &&
      uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
    return -1;

  if (listen(handle->socket, backlog) == SOCKET_ERROR) {
    uv_set_sys_error(loop, WSAGetLastError());
    return -1;
  }

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

  assert(!handle->accept_reqs);
  handle->accept_reqs = (uv_tcp_accept_t*)
    malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t));
  if (!handle->accept_reqs) {
    uv_fatal_error(ERROR_OUTOFMEMORY, "malloc");
  }

  for (i = 0; i < uv_simultaneous_server_accepts; i++) {
    req = &handle->accept_reqs[i];
    uv_req_init(loop, (uv_req_t*)req);
    req->type = UV_ACCEPT;
    req->accept_socket = INVALID_SOCKET;
    req->data = handle;
    uv_tcp_queue_accept(handle, req);
  }

  return 0;
}
예제 #8
0
파일: tcp.c 프로젝트: irca/libuv
int uv_tcp_write(uv_write_t* req, uv_tcp_t* handle, uv_buf_t bufs[], int bufcnt,
    uv_write_cb cb) {
  int result;
  DWORD bytes;

  if (!(handle->flags & UV_HANDLE_CONNECTION)) {
    uv_set_sys_error(WSAEINVAL);
    return -1;
  }

  if (handle->flags & UV_HANDLE_SHUTTING) {
    uv_set_sys_error(WSAESHUTDOWN);
    return -1;
  }

  uv_req_init((uv_req_t*) req);
  req->type = UV_WRITE;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  result = WSASend(handle->socket,
                   (WSABUF*)bufs,
                   bufcnt,
                   &bytes,
                   0,
                   &req->overlapped,
                   NULL);

  if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) {
    /* Request completed immediately. */
    req->queued_bytes = 0;
    handle->reqs_pending++;
    handle->write_reqs_pending++;
    uv_insert_pending_req((uv_req_t*)req);
  } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) {
    /* Request queued by the kernel. */
    req->queued_bytes = uv_count_bufs(bufs, bufcnt);
    handle->reqs_pending++;
    handle->write_reqs_pending++;
    handle->write_queue_size += req->queued_bytes;
  } else {
    /* Send failed due to an error. */
    uv_set_sys_error(WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #9
0
파일: tcp.c 프로젝트: irca/libuv
int uv_tcp_connect(uv_connect_t* req, uv_tcp_t* handle,
    struct sockaddr_in address, uv_connect_cb cb) {
  int addrsize = sizeof(struct sockaddr_in);
  BOOL success;
  DWORD bytes;

  if (handle->flags & UV_HANDLE_BIND_ERROR) {
    LOOP->last_error = handle->error;
    return -1;
  }

  if (address.sin_family != AF_INET) {
    uv_set_sys_error(WSAEFAULT);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_BOUND) &&
      uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
    return -1;

  uv_req_init((uv_req_t*) req);
  req->type = UV_CONNECT;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  success = pConnectEx(handle->socket,
                       (struct sockaddr*) &address,
                       addrsize,
                       NULL,
                       0,
                       &bytes,
                       &req->overlapped);

  if (UV_SUCCEEDED_WITHOUT_IOCP(success)) {
    /* Process the req without IOCP. */
    handle->reqs_pending++;
    uv_insert_pending_req((uv_req_t*)req);
  } else if (UV_SUCCEEDED_WITH_IOCP(success)) {
    /* The req will be processed with IOCP. */
    handle->reqs_pending++;
  } else {
    uv_set_sys_error(WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #10
0
파일: tcp.c 프로젝트: irca/libuv
void uv_process_tcp_connect_req(uv_tcp_t* handle, uv_connect_t* req) {
  assert(handle->type == UV_TCP);

  if (req->cb) {
    if (req->error.code == UV_OK) {
      if (setsockopt(handle->socket,
                      SOL_SOCKET,
                      SO_UPDATE_CONNECT_CONTEXT,
                      NULL,
                      0) == 0) {
        uv_connection_init((uv_stream_t*)handle);
        active_tcp_streams++;
        ((uv_connect_cb)req->cb)(req, 0);
      } else {
        uv_set_sys_error(WSAGetLastError());
        ((uv_connect_cb)req->cb)(req, -1);
      }
    } else {
      LOOP->last_error = req->error;
      ((uv_connect_cb)req->cb)(req, -1);
    }
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
예제 #11
0
파일: tcp.c 프로젝트: irca/libuv
int uv_getsockname(uv_tcp_t* handle, struct sockaddr* name, int* namelen) {
  int result;

  if (handle->flags & UV_HANDLE_SHUTTING) {
    uv_set_sys_error(WSAESHUTDOWN);
    return -1;
  }

  result = getsockname(handle->socket, name, namelen);
  if (result != 0) {
    uv_set_sys_error(WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #12
0
파일: udp.c 프로젝트: DrPizza/node
int uv_udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb,
    uv_udp_recv_cb recv_cb) {
  uv_loop_t* loop = handle->loop;

  if (handle->flags & UV_HANDLE_READING) {
    uv_set_sys_error(loop, WSAEALREADY);
    return -1;
  }

  if (!(handle->flags & UV_HANDLE_BOUND) &&
      uv_udp_bind(handle, uv_addr_ip4_any_, 0) < 0) {
    return -1;
  }

  handle->flags |= UV_HANDLE_READING;
  active_udp_streams++;

  handle->recv_cb = recv_cb;
  handle->alloc_cb = alloc_cb;

  /* If reading was stopped and then started again, there could stell be a */
  /* recv request pending. */
  if (!(handle->flags & UV_HANDLE_READ_PENDING))
    uv_udp_queue_recv(loop, handle);

  return 0;
}
예제 #13
0
파일: tcp.c 프로젝트: DrPizza/node
void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle,
    uv_connect_t* req) {
  assert(handle->type == UV_TCP);

  if (req->cb) {
    if (REQ_SUCCESS(req)) {
      if (setsockopt(handle->socket,
                      SOL_SOCKET,
                      SO_UPDATE_CONNECT_CONTEXT,
                      NULL,
                      0) == 0) {
        uv_connection_init((uv_stream_t*)handle);
        active_tcp_streams++;
        ((uv_connect_cb)req->cb)(req, 0);
      } else {
        uv_set_sys_error(loop, WSAGetLastError());
        ((uv_connect_cb)req->cb)(req, -1);
      }
    } else {
      loop->last_error = GET_REQ_UV_SOCK_ERROR(req);
      ((uv_connect_cb)req->cb)(req, -1);
    }
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
예제 #14
0
파일: tty.c 프로젝트: hghazal/node
int uv_tty_read_stop(uv_tty_t* handle) {
  handle->flags &= ~UV_HANDLE_READING;

  /* Cancel raw read */
  if ((handle->flags & UV_HANDLE_READ_PENDING) &&
      (handle->flags & UV_HANDLE_TTY_RAW)) {
    /* Write some bullshit event to force the console wait to return. */
    INPUT_RECORD record;
    DWORD written;
    memset(&record, 0, sizeof record);
    if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) {
      uv_set_sys_error(handle->loop, GetLastError());
      return -1;
    }
  }

  /* Cancel line-buffered read */
  if (handle->read_line_handle != NULL) {
    /* Closing this handle will cancel the ReadConsole operation */
    CloseHandle(handle->read_line_handle);
    handle->read_line_handle = NULL;
  }


  return 0;
}
예제 #15
0
파일: pipe.c 프로젝트: diffidentDude/node
int uv_pipe_accept(uv_pipe_t* server, uv_pipe_t* client) {
  /* Find a connection instance that has been connected, but not yet accepted. */
  uv_pipe_accept_t* req = server->pending_accepts;

  if (!req) {
    /* No valid connections found, so we error out. */
    uv_set_sys_error(WSAEWOULDBLOCK);
    return -1;
  }

  /* Initialize the client handle and copy the pipeHandle to the client */
  uv_connection_init((uv_stream_t*) client);
  client->handle = req->pipeHandle;

  /* Prepare the req to pick up a new connection */
  server->pending_accepts = req->next_pending;
  req->next_pending = NULL;
  req->pipeHandle = INVALID_HANDLE_VALUE;

  if (!(server->flags & UV_HANDLE_CLOSING) &&
      !(server->flags & UV_HANDLE_GIVEN_OS_HANDLE)) {
    uv_pipe_queue_accept(server, req, FALSE);
  }

  return 0;
}
예제 #16
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;
}
예제 #17
0
파일: tcp.c 프로젝트: irca/libuv
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
  if (addr.sin_family != AF_INET) {
    uv_set_sys_error(WSAEFAULT);
    return -1;
  }

  return uv__bind(handle, AF_INET, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
}
예제 #18
0
파일: pipe.c 프로젝트: dakatsuka/node
static void uv_pipe_read_error(uv_pipe_t* handle, int error, uv_buf_t buf) {
  /* If there is an eof timer running, we don't need it any more, */
  /* so discard it. */
  eof_timer_destroy(handle);

  uv_read_stop((uv_stream_t*) handle);

  uv_set_sys_error(error);
  handle->read_cb((uv_stream_t*)handle, -1, buf);
}
예제 #19
0
파일: tty.c 프로젝트: hghazal/node
void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle,
    uv_req_t* req) {
  uv_buf_t buf;

  assert(handle->type == UV_TTY);

  buf = handle->read_line_buffer;

  handle->flags &= ~UV_HANDLE_READ_PENDING;
  handle->read_line_buffer = uv_null_buf_;

  if (!REQ_SUCCESS(req)) {
    /* Read was not successful */
    if ((handle->flags & UV_HANDLE_READING) &&
        !(handle->flags & UV_HANDLE_TTY_RAW)) {
      /* Real error */
      handle->flags &= ~UV_HANDLE_READING;
      loop->last_error = GET_REQ_UV_ERROR(req);
      handle->read_cb((uv_stream_t*) handle, -1, buf);
    } else {
      /* The read was cancelled, or whatever we don't care */
      uv_set_sys_error(loop, WSAEWOULDBLOCK); /* maps to UV_EAGAIN */
      handle->read_cb((uv_stream_t*) handle, 0, buf);
    }

  } else {
    /* Read successful */
    /* TODO: read unicode, convert to utf-8 */
    DWORD bytes = req->overlapped.InternalHigh;
    if (bytes == 0) {
      uv_set_sys_error(loop, WSAEWOULDBLOCK); /* maps to UV_EAGAIN */
    }
    handle->read_cb((uv_stream_t*) handle, bytes, buf);
  }

  /* Wait for more input events. */
  if ((handle->flags & UV_HANDLE_READING) &&
      !(handle->flags & UV_HANDLE_READ_PENDING)) {
    uv_tty_queue_read(loop, handle);
  }

  DECREASE_PENDING_REQ_COUNT(handle);
}
예제 #20
0
파일: tcp.c 프로젝트: DrPizza/node
static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
    SOCKET socket) {
  DWORD yes = 1;

  assert(handle->socket == INVALID_SOCKET);

  /* Set the socket to nonblocking mode */
  if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {
    uv_set_sys_error(loop, WSAGetLastError());
    return -1;
  }

  /* Make the socket non-inheritable */
  if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) {
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  /* Associate it with the I/O completion port. */
  /* Use uv_handle_t pointer as completion key. */
  if (CreateIoCompletionPort((HANDLE)socket,
                             loop->iocp,
                             (ULONG_PTR)socket,
                             0) == NULL) {
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  if (pSetFileCompletionNotificationModes) {
    if (pSetFileCompletionNotificationModes((HANDLE) socket,
        FILE_SKIP_SET_EVENT_ON_HANDLE |
        FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) {
      handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP;
    } else if (GetLastError() != ERROR_INVALID_FUNCTION) {
      uv_set_sys_error(loop, GetLastError());
      return -1;
    }
  }

  handle->socket = socket;

  return 0;
}
예제 #21
0
파일: udp.c 프로젝트: dakatsuka/node
int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, int* namelen) {
  int result;

  result = getsockname(handle->socket, name, namelen);
  if (result != 0) {
    uv_set_sys_error(WSAGetLastError());
    return -1;
  }

  return 0;
}
예제 #22
0
int uv_queue_work(uv_loop_t* loop, uv_work_t* req, uv_work_cb work_cb,
    uv_after_work_cb after_work_cb) {
  uv_work_req_init(loop, req, work_cb, after_work_cb);

  if (!QueueUserWorkItem(&uv_work_thread_proc, req, WT_EXECUTELONGFUNCTION)) {
    uv_set_sys_error(loop, GetLastError());
    return -1;
  }

  uv_ref(loop);
  return 0;
}
예제 #23
0
파일: tcp.c 프로젝트: DrPizza/node
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
  uv_loop_t* loop = handle->loop;

  if (addr.sin6_family != AF_INET6) {
    uv_set_sys_error(loop, WSAEFAULT);
    return -1;
  }

  if (uv_allow_ipv6) {
    handle->flags |= UV_HANDLE_IPV6;
    return uv__bind(loop,
                    handle,
                    AF_INET6,
                    (struct sockaddr*)&addr,
                    sizeof(struct sockaddr_in6));

  } else {
    uv_set_sys_error(loop, WSAEAFNOSUPPORT);
    return -1;
  }
}
예제 #24
0
파일: tty.c 프로젝트: hghazal/node
int uv_tty_set_mode(uv_tty_t* tty, int mode) {
  DWORD flags = 0;
  unsigned char was_reading;
  uv_alloc_cb alloc_cb;
  uv_read_cb read_cb;

  if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) {
    return 0;
  }

  if (tty->original_console_mode & ENABLE_QUICK_EDIT_MODE) {
    flags = ENABLE_QUICK_EDIT_MODE | ENABLE_EXTENDED_FLAGS;
  }

  if (mode) {
    /* Raw input */
    flags |= ENABLE_WINDOW_INPUT;
  } else {
    /* Line-buffered mode. */
    flags |= ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT |
        ENABLE_EXTENDED_FLAGS | ENABLE_PROCESSED_INPUT;
  }

  if (!SetConsoleMode(tty->handle, flags)) {
    uv_set_sys_error(tty->loop, GetLastError());
    return -1;
  }

  /* If currently reading, stop, and restart reading. */
  if (tty->flags & UV_HANDLE_READING) {
    was_reading = 1;
    alloc_cb = tty->alloc_cb;
    read_cb = tty->read_cb;

    if (was_reading && uv_tty_read_stop(tty) != 0) {
      return -1;
    }
  } else {
    was_reading = 0;
  }

  /* Update flag. */
  tty->flags &= ~UV_HANDLE_TTY_RAW;
  tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0;

  /* If we just stopped reading, restart. */
  if (was_reading && uv_tty_read_start(tty, alloc_cb, read_cb) != 0) {
    return -1;
  }

  return 0;
}
예제 #25
0
파일: pipe.c 프로젝트: diffidentDude/node
int uv_pipe_write(uv_write_t* req, uv_pipe_t* handle, uv_buf_t bufs[], int bufcnt,
    uv_write_cb cb) {
  int result;

  if (bufcnt != 1) {
    uv_set_error(UV_ENOTSUP, 0);
    return -1;
  }

  assert(handle->handle != INVALID_HANDLE_VALUE);

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

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

  uv_req_init((uv_req_t*) req);
  req->type = UV_WRITE;
  req->handle = (uv_stream_t*) handle;
  req->cb = cb;
  memset(&req->overlapped, 0, sizeof(req->overlapped));

  result = WriteFile(handle->handle,
                     bufs[0].base,
                     bufs[0].len,
                     NULL,
                     &req->overlapped);

  if (!result && GetLastError() != ERROR_IO_PENDING) {
    uv_set_sys_error(GetLastError());
    return -1;
  }

  if (result) {
    /* Request completed immediately. */
    req->queued_bytes = 0;
  } else {
    /* Request queued by the kernel. */
    req->queued_bytes = uv_count_bufs(bufs, bufcnt);
    handle->write_queue_size += req->queued_bytes;
  }

  handle->reqs_pending++;
  handle->write_reqs_pending++;

  return 0;
}
예제 #26
0
파일: stream.c 프로젝트: changloong/gool
int uv_write(uv_write_t* req, uv_stream_t* handle, uv_buf_t bufs[], int bufcnt,
    uv_write_cb cb) {
  switch (handle->type) {
    case UV_TCP:
      return uv_tcp_write(req, (uv_tcp_t*) handle, bufs, bufcnt, cb);
    case UV_NAMED_PIPE:
      return uv_pipe_write(req, (uv_pipe_t*) handle, bufs, bufcnt, cb);
    default:
      assert(0);
      uv_set_sys_error(WSAEINVAL);
      return -1;
  }
}
예제 #27
0
파일: handle.c 프로젝트: dakatsuka/node
int uv_getsockname(uv_handle_t* handle, struct sockaddr* name, int* namelen) {
  switch (handle->type) {
    case UV_TCP:
      return uv_tcp_getsockname((uv_tcp_t*) handle, name, namelen);

    case UV_UDP:
      return uv_udp_getsockname((uv_udp_t*) handle, name, namelen);

    default:
      uv_set_sys_error(WSAENOTSOCK);
      return -1;
  }
}
예제 #28
0
파일: tcp.c 프로젝트: DrPizza/node
int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) {
  uv_loop_t* loop = server->loop;
  int rv = 0;

  uv_tcp_accept_t* req = server->pending_accepts;

  if (!req) {
    /* No valid connections found, so we error out. */
    uv_set_sys_error(loop, WSAEWOULDBLOCK);
    return -1;
  }

  if (req->accept_socket == INVALID_SOCKET) {
    uv_set_sys_error(loop, WSAENOTCONN);
    return -1;
  }

  if (uv_tcp_set_socket(client->loop, client, req->accept_socket) == -1) {
    closesocket(req->accept_socket);
    rv = -1;
  } else {
    uv_connection_init((uv_stream_t*) client);
  }

  /* Prepare the req to pick up a new connection */
  server->pending_accepts = req->next_pending;
  req->next_pending = NULL;
  req->accept_socket = INVALID_SOCKET;

  if (!(server->flags & UV_HANDLE_CLOSING)) {
    uv_tcp_queue_accept(server, req);
  }

  active_tcp_streams++;

  return rv;
}
예제 #29
0
파일: tcp.c 프로젝트: DrPizza/node
static int uv__bind(uv_loop_t* loop, uv_tcp_t* handle, int domain,
    struct sockaddr* addr, int addrsize) {
  DWORD err;
  int r;
  SOCKET sock;

  if (handle->socket == INVALID_SOCKET) {
    sock = socket(domain, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET) {
      uv_set_sys_error(loop, WSAGetLastError());
      return -1;
    }

    if (uv_tcp_set_socket(loop, handle, sock) == -1) {
      closesocket(sock);
      return -1;
    }
  }

  r = bind(handle->socket, addr, addrsize);

  if (r == SOCKET_ERROR) {
    err = WSAGetLastError();
    if (err == WSAEADDRINUSE) {
      /* Some errors are not to be reported until connect() or listen() */
      handle->bind_error = uv_new_sys_error(err);
      handle->flags |= UV_HANDLE_BIND_ERROR;
    } else {
      uv_set_sys_error(loop, err);
      return -1;
    }
  }

  handle->flags |= UV_HANDLE_BOUND;

  return 0;
}
예제 #30
0
파일: udp.c 프로젝트: DrPizza/node
int uv_udp_bind(uv_udp_t* handle, struct sockaddr_in addr,
    unsigned int flags) {
  uv_loop_t* loop = handle->loop;

  if (addr.sin_family != AF_INET) {
    uv_set_sys_error(loop, WSAEFAULT);
    return -1;
  }

  return uv__bind(handle,
                  AF_INET,
                  (struct sockaddr*) &addr,
                  sizeof(struct sockaddr_in),
                  flags);
}