Revert "Revert "unix,tcp: avoid marking server sockets connected""

This reverts commit 2098773243.

PR-URL: https://github.com/libuv/libuv/pull/1741
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
Jameson Nash 2018-02-13 14:21:09 -05:00 committed by Santiago Gimeno
parent c409b3fcff
commit 8f9ba2a597
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
4 changed files with 53 additions and 5 deletions

View File

@ -1417,6 +1417,9 @@ int uv_write2(uv_write_t* req,
if (uv__stream_fd(stream) < 0) if (uv__stream_fd(stream) < 0)
return UV_EBADF; return UV_EBADF;
if (!(stream->flags & UV_STREAM_WRITABLE))
return -EPIPE;
if (send_handle) { if (send_handle) {
if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc) if (stream->type != UV_NAMED_PIPE || !((uv_pipe_t*)stream)->ipc)
return UV_EINVAL; return UV_EINVAL;
@ -1568,6 +1571,9 @@ int uv_read_start(uv_stream_t* stream,
if (stream->flags & UV_CLOSING) if (stream->flags & UV_CLOSING)
return UV_EINVAL; return UV_EINVAL;
if (!(stream->flags & UV_STREAM_READABLE))
return -ENOTCONN;
/* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just /* The UV_STREAM_READING flag is irrelevant of the state of the tcp - it just
* expresses the desired state of the user. * expresses the desired state of the user.
*/ */

View File

@ -158,9 +158,7 @@ int uv__tcp_bind(uv_tcp_t* tcp,
if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6)
return UV_EINVAL; return UV_EINVAL;
err = maybe_new_socket(tcp, err = maybe_new_socket(tcp, addr->sa_family, 0);
addr->sa_family,
UV_STREAM_READABLE | UV_STREAM_WRITABLE);
if (err) if (err)
return err; return err;
@ -335,14 +333,14 @@ int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
if (single_accept) if (single_accept)
tcp->flags |= UV_TCP_SINGLE_ACCEPT; tcp->flags |= UV_TCP_SINGLE_ACCEPT;
flags = UV_STREAM_READABLE; flags = 0;
#if defined(__MVS__) #if defined(__MVS__)
/* on zOS the listen call does not bind automatically /* on zOS the listen call does not bind automatically
if the socket is unbound. Hence the manual binding to if the socket is unbound. Hence the manual binding to
an arbitrary port is required to be done manually an arbitrary port is required to be done manually
*/ */
flags |= UV_HANDLE_BOUND; flags |= UV_HANDLE_BOUND;
#endif #endif
err = maybe_new_socket(tcp, AF_INET, flags); err = maybe_new_socket(tcp, AF_INET, flags);
if (err) if (err)
return err; return err;

View File

@ -95,6 +95,7 @@ TEST_DECLARE (tcp_bind_error_fault)
TEST_DECLARE (tcp_bind_error_inval) TEST_DECLARE (tcp_bind_error_inval)
TEST_DECLARE (tcp_bind_localhost_ok) TEST_DECLARE (tcp_bind_localhost_ok)
TEST_DECLARE (tcp_bind_invalid_flags) TEST_DECLARE (tcp_bind_invalid_flags)
TEST_DECLARE (tcp_bind_writable_flags)
TEST_DECLARE (tcp_listen_without_bind) TEST_DECLARE (tcp_listen_without_bind)
TEST_DECLARE (tcp_connect_error_fault) TEST_DECLARE (tcp_connect_error_fault)
TEST_DECLARE (tcp_connect_timeout) TEST_DECLARE (tcp_connect_timeout)
@ -535,6 +536,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_bind_error_inval) TEST_ENTRY (tcp_bind_error_inval)
TEST_ENTRY (tcp_bind_localhost_ok) TEST_ENTRY (tcp_bind_localhost_ok)
TEST_ENTRY (tcp_bind_invalid_flags) TEST_ENTRY (tcp_bind_invalid_flags)
TEST_ENTRY (tcp_bind_writable_flags)
TEST_ENTRY (tcp_listen_without_bind) TEST_ENTRY (tcp_listen_without_bind)
TEST_ENTRY (tcp_connect_error_fault) TEST_ENTRY (tcp_connect_error_fault)
TEST_ENTRY (tcp_connect_timeout) TEST_ENTRY (tcp_connect_timeout)

View File

@ -214,3 +214,45 @@ TEST_IMPL(tcp_listen_without_bind) {
MAKE_VALGRIND_HAPPY(); MAKE_VALGRIND_HAPPY();
return 0; return 0;
} }
TEST_IMPL(tcp_bind_writable_flags) {
struct sockaddr_in addr;
uv_tcp_t server;
uv_buf_t buf;
uv_write_t write_req;
uv_shutdown_t shutdown_req;
int r;
ASSERT(0 == uv_ip4_addr("0.0.0.0", TEST_PORT, &addr));
r = uv_tcp_init(uv_default_loop(), &server);
ASSERT(r == 0);
r = uv_tcp_bind(&server, (const struct sockaddr*) &addr, 0);
ASSERT(r == 0);
r = uv_listen((uv_stream_t*)&server, 128, NULL);
ASSERT(r == 0);
ASSERT(0 == uv_is_writable((uv_stream_t*) &server));
ASSERT(0 == uv_is_readable((uv_stream_t*) &server));
buf = uv_buf_init("PING", 4);
r = uv_write(&write_req, (uv_stream_t*) &server, &buf, 1, NULL);
ASSERT(r == UV_EPIPE);
r = uv_shutdown(&shutdown_req, (uv_stream_t*) &server, NULL);
#ifdef _WIN32
ASSERT(r == UV_EPIPE);
#else
ASSERT(r == UV_ENOTCONN);
#endif
r = uv_read_start((uv_stream_t*) &server, NULL, NULL);
ASSERT(r == UV_ENOTCONN);
uv_close((uv_handle_t*)&server, close_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
ASSERT(close_cb_called == 1);
MAKE_VALGRIND_HAPPY();
return 0;
}