unix, win: prevent replacing fd in uv_{udp,tcp,pipe}_t

PR-URL: https://github.com/libuv/libuv/pull/400
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
Saúl Ibarra Corretgé 2015-06-18 00:41:44 +02:00
parent 70bbfa0e00
commit fb5df542ac
8 changed files with 91 additions and 3 deletions

View File

@ -391,6 +391,9 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
int enable;
#endif
if (!(stream->io_watcher.fd == -1 || stream->io_watcher.fd == fd))
return -EBUSY;
assert(fd >= 0);
stream->flags |= flags;

View File

@ -569,7 +569,7 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
/* Check for already active socket. */
if (handle->io_watcher.fd != -1)
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
return -EBUSY;
err = uv__nonblock(sock, 1);
if (err)

View File

@ -254,6 +254,9 @@ static int uv_set_pipe_handle(uv_loop_t* loop,
DWORD current_mode = 0;
DWORD err = 0;
if (handle->handle != INVALID_HANDLE_VALUE)
return UV_EBUSY;
if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) {
err = GetLastError();
if (err == ERROR_ACCESS_DENIED) {

View File

@ -84,7 +84,8 @@ static int uv_tcp_set_socket(uv_loop_t* loop, uv_tcp_t* handle,
int non_ifs_lsp;
int err;
assert(handle->socket == INVALID_SOCKET);
if (handle->socket != INVALID_SOCKET)
return UV_EBUSY;
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {

View File

@ -61,7 +61,8 @@ static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket,
WSAPROTOCOL_INFOW info;
int opt_len;
assert(handle->socket == INVALID_SOCKET);
if (handle->socket != INVALID_SOCKET)
return UV_EBUSY;
/* Set the socket to nonblocking mode */
if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) {

View File

@ -66,6 +66,7 @@ TEST_DECLARE (tcp_write_fail)
TEST_DECLARE (tcp_try_write)
TEST_DECLARE (tcp_write_queue_order)
TEST_DECLARE (tcp_open)
TEST_DECLARE (tcp_open_twice)
TEST_DECLARE (tcp_connect_error_after_write)
TEST_DECLARE (tcp_shutdown_after_write)
TEST_DECLARE (tcp_bind_error_addrinuse)
@ -110,6 +111,7 @@ TEST_DECLARE (udp_options)
TEST_DECLARE (udp_options6)
TEST_DECLARE (udp_no_autobind)
TEST_DECLARE (udp_open)
TEST_DECLARE (udp_open_twice)
TEST_DECLARE (udp_try_send)
TEST_DECLARE (pipe_bind_error_addrinuse)
TEST_DECLARE (pipe_bind_error_addrnotavail)
@ -393,6 +395,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_open)
TEST_HELPER (tcp_open, tcp4_echo_server)
TEST_ENTRY (tcp_open_twice)
TEST_ENTRY (tcp_shutdown_after_write)
TEST_HELPER (tcp_shutdown_after_write, tcp4_echo_server)
@ -447,6 +450,7 @@ TASK_LIST_START
TEST_ENTRY (udp_open)
TEST_HELPER (udp_open, udp4_echo_server)
TEST_ENTRY (udp_open_twice)
TEST_ENTRY (pipe_bind_error_addrinuse)
TEST_ENTRY (pipe_bind_error_addrnotavail)

View File

@ -71,6 +71,17 @@ static uv_os_sock_t create_tcp_socket(void) {
}
static void close_socket(uv_os_sock_t sock) {
int r;
#ifdef _WIN32
r = closesocket(sock);
#else
r = close(sock);
#endif
ASSERT(r == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
@ -180,3 +191,30 @@ TEST_IMPL(tcp_open) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(tcp_open_twice) {
uv_tcp_t client;
uv_os_sock_t sock1, sock2;
int r;
startup();
sock1 = create_tcp_socket();
sock2 = create_tcp_socket();
r = uv_tcp_init(uv_default_loop(), &client);
ASSERT(r == 0);
r = uv_tcp_open(&client, sock1);
ASSERT(r == 0);
r = uv_tcp_open(&client, sock2);
ASSERT(r == UV_EBUSY);
close_socket(sock2);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}

View File

@ -67,6 +67,17 @@ static uv_os_sock_t create_udp_socket(void) {
}
static void close_socket(uv_os_sock_t sock) {
int r;
#ifdef _WIN32
r = closesocket(sock);
#else
r = close(sock);
#endif
ASSERT(r == 0);
}
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
@ -164,3 +175,30 @@ TEST_IMPL(udp_open) {
MAKE_VALGRIND_HAPPY();
return 0;
}
TEST_IMPL(udp_open_twice) {
uv_udp_t client;
uv_os_sock_t sock1, sock2;
int r;
startup();
sock1 = create_udp_socket();
sock2 = create_udp_socket();
r = uv_udp_init(uv_default_loop(), &client);
ASSERT(r == 0);
r = uv_udp_open(&client, sock1);
ASSERT(r == 0);
r = uv_udp_open(&client, sock2);
ASSERT(r == UV_EBUSY);
close_socket(sock2);
uv_close((uv_handle_t*) &client, NULL);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
MAKE_VALGRIND_HAPPY();
return 0;
}