unix: set non-block mode in uv_{pipe,tcp,udp}_open

The contract specifies that the file descriptor should already be in
non-blocking mode before passing it to libuv.

However, node users don't really have an opportunity to do so, never
mind the fact that the call to uv_pipe_open() or uv_tcp_open() is an
implementation detail that most users won't be aware of.

Let's be nice and set the non-blocking flag explicitly.  It's a cheap
operation anyway.

Fixes: https://github.com/libuv/libuv/issues/124

PR: https://github.com/libuv/libuv/pull/134
Reviewed-by: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
Ben Noordhuis 2015-01-13 17:33:50 +01:00 committed by Saúl Ibarra Corretgé
parent bb5f5d107e
commit 393c1c59a2
8 changed files with 19 additions and 8 deletions

View File

@ -38,8 +38,7 @@ API
Open an existing file descriptor or HANDLE as a pipe.
.. note::
The user is responsible for setting the file descriptor in non-blocking mode.
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. c:function:: int uv_pipe_bind(uv_pipe_t* handle, const char* name)

View File

@ -36,9 +36,7 @@ API
Open an existing file descriptor or SOCKET as a TCP handle.
.. note::
The user is responsible for setting the file descriptor in
non-blocking mode.
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. c:function:: int uv_tcp_nodelay(uv_tcp_t* handle, int enable)

View File

@ -120,6 +120,8 @@ API
In other words, other datagram-type sockets like raw sockets or netlink
sockets can also be passed to this function.
.. versionchanged:: 1.2.1 the file descriptor is set to non-blocking mode.
.. c:function:: int uv_udp_bind(uv_udp_t* handle, const struct sockaddr* addr, unsigned int flags)
Bind the UDP handle to an IP address and port.

View File

@ -125,9 +125,13 @@ void uv__pipe_close(uv_pipe_t* handle) {
int uv_pipe_open(uv_pipe_t* handle, uv_file fd) {
#if defined(__APPLE__)
int err;
err = uv__nonblock(fd, 1);
if (err)
return err;
#if defined(__APPLE__)
err = uv__stream_try_select((uv_stream_t*) handle, &fd);
if (err)
return err;

View File

@ -156,6 +156,12 @@ int uv__tcp_connect(uv_connect_t* req,
int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) {
int err;
err = uv__nonblock(sock, 1);
if (err)
return err;
return uv__stream_open((uv_stream_t*)handle,
sock,
UV_STREAM_READABLE | UV_STREAM_WRITABLE);

View File

@ -565,6 +565,10 @@ int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) {
if (handle->io_watcher.fd != -1)
return -EALREADY; /* FIXME(bnoordhuis) Should be -EBUSY. */
err = uv__nonblock(sock, 1);
if (err)
return err;
err = uv__set_reuse(sock);
if (err)
return err;

View File

@ -54,7 +54,6 @@ TEST_IMPL(close_fd) {
int fd[2];
ASSERT(0 == pipe(fd));
ASSERT(0 == fcntl(fd[0], F_SETFL, O_NONBLOCK));
ASSERT(0 == uv_pipe_init(uv_default_loop(), &pipe_handle, 0));
ASSERT(0 == uv_pipe_open(&pipe_handle, fd[0]));
fd[0] = -1; /* uv_pipe_open() takes ownership of the file descriptor. */

View File

@ -1243,7 +1243,6 @@ TEST_IMPL(closed_fd_events) {
/* create a pipe and share it with a child process */
ASSERT(0 == pipe(fd));
ASSERT(0 == fcntl(fd[0], F_SETFL, O_NONBLOCK));
/* spawn_helper4 blocks indefinitely. */
init_process_options("spawn_helper4", exit_cb);