diff --git a/src/unix/tcp.c b/src/unix/tcp.c index 749a5131..fb402e7e 100644 --- a/src/unix/tcp.c +++ b/src/unix/tcp.c @@ -131,6 +131,18 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, /* Don't clobber errno. */ saved_errno = errno; + if (handle->delayed_error) { + uv_err_new(handle->loop, handle->delayed_error); + rv = -1; + goto out; + } + + if (handle->fd < 0) { + uv_err_new(handle->loop, EINVAL); + rv = -1; + goto out; + } + /* sizeof(socklen_t) != sizeof(int) on some systems. */ socklen = (socklen_t)*namelen; @@ -141,6 +153,7 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, *namelen = (int)socklen; } +out: errno = saved_errno; return rv; } @@ -155,6 +168,18 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, /* Don't clobber errno. */ saved_errno = errno; + if (handle->delayed_error) { + uv_err_new(handle->loop, handle->delayed_error); + rv = -1; + goto out; + } + + if (handle->fd < 0) { + uv_err_new(handle->loop, EINVAL); + rv = -1; + goto out; + } + /* sizeof(socklen_t) != sizeof(int) on some systems. */ socklen = (socklen_t)*namelen; @@ -165,6 +190,7 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, *namelen = (int)socklen; } +out: errno = saved_errno; return rv; } diff --git a/src/unix/udp.c b/src/unix/udp.c index 5f9040ae..20e5f379 100644 --- a/src/unix/udp.c +++ b/src/unix/udp.c @@ -469,6 +469,12 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, /* Don't clobber errno. */ saved_errno = errno; + if (handle->fd < 0) { + uv_err_new(handle->loop, EINVAL); + rv = -1; + goto out; + } + /* sizeof(socklen_t) != sizeof(int) on some systems. */ socklen = (socklen_t)*namelen; @@ -479,6 +485,7 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, *namelen = (int)socklen; } +out: errno = saved_errno; return rv; } diff --git a/src/win/tcp.c b/src/win/tcp.c index 1633d10d..ebd83534 100644 --- a/src/win/tcp.c +++ b/src/win/tcp.c @@ -419,6 +419,8 @@ int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { rv = -1; } else { uv_connection_init((uv_stream_t*) client); + /* AcceptEx() implicitly binds the accepted socket. */ + client->flags |= UV_HANDLE_BOUND; } /* Prepare the req to pick up a new connection */ @@ -578,8 +580,13 @@ int uv_tcp_getsockname(uv_tcp_t* handle, struct sockaddr* name, uv_loop_t* loop = handle->loop; int result; - if (handle->flags & UV_HANDLE_SHUTTING) { - uv_set_sys_error(loop, WSAESHUTDOWN); + if (!(handle->flags & UV_HANDLE_BOUND)) { + uv_set_sys_error(loop, WSAEINVAL); + return -1; + } + + if (handle->flags & UV_HANDLE_BIND_ERROR) { + loop->last_error = handle->bind_error; return -1; } @@ -598,8 +605,13 @@ int uv_tcp_getpeername(uv_tcp_t* handle, struct sockaddr* name, uv_loop_t* loop = handle->loop; int result; - if (handle->flags & UV_HANDLE_SHUTTING) { - uv_set_sys_error(loop, WSAESHUTDOWN); + if (!(handle->flags & UV_HANDLE_BOUND)) { + uv_set_sys_error(loop, WSAEINVAL); + return -1; + } + + if (handle->flags & UV_HANDLE_BIND_ERROR) { + loop->last_error = handle->bind_error; return -1; } diff --git a/src/win/udp.c b/src/win/udp.c index 7a63c52f..3a2ab6bc 100644 --- a/src/win/udp.c +++ b/src/win/udp.c @@ -45,6 +45,11 @@ int uv_udp_getsockname(uv_udp_t* handle, struct sockaddr* name, uv_loop_t* loop = handle->loop; int result; + if (!(handle->flags & UV_HANDLE_BOUND)) { + uv_set_sys_error(loop, WSAEINVAL); + return -1; + } + result = getsockname(handle->socket, name, namelen); if (result != 0) { uv_set_sys_error(loop, WSAGetLastError());