diff --git a/src/unix/core.c b/src/unix/core.c index 4860ebbc..c2e7bd73 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -927,6 +927,11 @@ int uv__io_active(const uv__io_t* w, unsigned int events) { } +int uv__fd_exists(uv_loop_t* loop, int fd) { + return (unsigned) fd < loop->nwatchers && loop->watchers[fd] != NULL; +} + + int uv_getrusage(uv_rusage_t* rusage) { struct rusage usage; diff --git a/src/unix/internal.h b/src/unix/internal.h index 63e478fd..b0c5dcad 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -219,6 +219,7 @@ int uv__io_active(const uv__io_t* w, unsigned int events); int uv__io_check_fd(uv_loop_t* loop, int fd); void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */ int uv__io_fork(uv_loop_t* loop); +int uv__fd_exists(uv_loop_t* loop, int fd); /* async */ void uv__async_stop(uv_loop_t* loop); diff --git a/src/unix/pipe.c b/src/unix/pipe.c index 2c578dcb..91114db6 100644 --- a/src/unix/pipe.c +++ b/src/unix/pipe.c @@ -134,6 +134,9 @@ void uv__pipe_close(uv_pipe_t* handle) { int uv_pipe_open(uv_pipe_t* handle, uv_file fd) { int err; + if (uv__fd_exists(handle->loop, fd)) + return UV_EEXIST; + err = uv__nonblock(fd, 1); if (err) return err; diff --git a/src/unix/poll.c b/src/unix/poll.c index f3b0bf4e..3d5022b2 100644 --- a/src/unix/poll.c +++ b/src/unix/poll.c @@ -68,6 +68,9 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { int err; + if (uv__fd_exists(loop, fd)) + return UV_EEXIST; + err = uv__io_check_fd(loop, fd); if (err) return err; diff --git a/src/unix/tcp.c b/src/unix/tcp.c index 9a46793f..27a2a613 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -263,6 +263,9 @@ int uv__tcp_connect(uv_connect_t* req, int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { int err; + if (uv__fd_exists(handle->loop, sock)) + return UV_EEXIST; + err = uv__nonblock(sock, 1); if (err) return err; diff --git a/src/unix/udp.c b/src/unix/udp.c index 74d613b6..15da047a 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -624,6 +624,9 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { if (handle->io_watcher.fd != -1) return UV_EBUSY; + if (uv__fd_exists(handle->loop, sock)) + return UV_EEXIST; + err = uv__nonblock(sock, 1); if (err) return err; diff --git a/test/test-tcp-open.c b/test/test-tcp-open.c index cb74c50e..f5d8f136 100644 --- a/test/test-tcp-open.c +++ b/test/test-tcp-open.c @@ -181,6 +181,20 @@ TEST_IMPL(tcp_open) { connect_cb); ASSERT(r == 0); +#ifndef _WIN32 + { + uv_tcp_t client2; + + r = uv_tcp_init(uv_default_loop(), &client2); + ASSERT(r == 0); + + r = uv_tcp_open(&client2, sock); + ASSERT(r == UV_EEXIST); + + uv_close((uv_handle_t*) &client2, NULL); + } +#endif /* !_WIN32 */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(shutdown_cb_called == 1); diff --git a/test/test-udp-open.c b/test/test-udp-open.c index e14b808e..ee04c99f 100644 --- a/test/test-udp-open.c +++ b/test/test-udp-open.c @@ -164,6 +164,20 @@ TEST_IMPL(udp_open) { send_cb); ASSERT(r == 0); +#ifndef _WIN32 + { + uv_udp_t client2; + + r = uv_udp_init(uv_default_loop(), &client2); + ASSERT(r == 0); + + r = uv_udp_open(&client2, sock); + ASSERT(r == UV_EEXIST); + + uv_close((uv_handle_t*) &client2, NULL); + } +#endif /* !_WIN32 */ + uv_run(uv_default_loop(), UV_RUN_DEFAULT); ASSERT(send_cb_called == 1);