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:
parent
70bbfa0e00
commit
fb5df542ac
@ -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;
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user