unix,tcp: avoid marking server sockets connected

It shouldn't be setting READABLE and WRITABLE on the socket server,
since they aren't, and this could confuse the client.

PR-URL: https://github.com/libuv/libuv/pull/1655
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
This commit is contained in:
Jameson Nash 2013-02-12 16:53:37 -05:00 committed by Santiago Gimeno
parent b01de7341f
commit fd049399aa
No known key found for this signature in database
GPG Key ID: F28C3C8DA33C03BE
4 changed files with 53 additions and 5 deletions

View File

@ -1411,6 +1411,9 @@ int uv_write2(uv_write_t* req,
if (uv__stream_fd(stream) < 0) if (uv__stream_fd(stream) < 0)
return -EBADF; return -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 -EINVAL; return -EINVAL;
@ -1562,6 +1565,9 @@ int uv_read_start(uv_stream_t* stream,
if (stream->flags & UV_CLOSING) if (stream->flags & UV_CLOSING)
return -EINVAL; return -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 -EINVAL; return -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

@ -93,6 +93,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)
@ -530,6 +531,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;
}