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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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); }
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; }
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; }
/* 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; }
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)); }
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); }
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); }
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; }
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; }
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; }
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; } }
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; }
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; }
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; } }
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; } }
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; }
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; }
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); }