Skip to content

Commit

Permalink
unix: set non-block mode in uv_{pipe,tcp,udp}_open
Browse files Browse the repository at this point in the history
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: libuv#124

PR: libuv#134
Reviewed-by: Saúl Ibarra Corretgé <saghul@gmail.com>
  • Loading branch information
bnoordhuis authored and saghul committed Jan 14, 2015
1 parent bb5f5d1 commit 393c1c5
Show file tree
Hide file tree
Showing 8 changed files with 19 additions and 8 deletions.
3 changes: 1 addition & 2 deletions docs/src/pipe.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 1 addition & 3 deletions docs/src/tcp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions docs/src/udp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 5 additions & 1 deletion src/unix/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
6 changes: 6 additions & 0 deletions src/unix/tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions src/unix/udp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion test/test-close-fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
1 change: 0 additions & 1 deletion test/test-spawn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 393c1c5

Please sign in to comment.