diff options
author | Ken Brown <kbrown@cornell.edu> | 2021-04-06 17:56:45 -0400 |
---|---|---|
committer | Ken Brown <kbrown@cornell.edu> | 2021-04-07 10:43:09 -0400 |
commit | 5a1b11bd7d7bd0a992ac49f6d272715a3df68b73 (patch) | |
tree | 93fe872c95afe7ee8c0dc5025aae7b0620cd8988 | |
parent | dd99a62277bbf565f7aca3be43d161e38dac4d93 (diff) | |
download | newlib-5a1b11bd7d7bd0a992ac49f6d272715a3df68b73.zip newlib-5a1b11bd7d7bd0a992ac49f6d272715a3df68b73.tar.gz newlib-5a1b11bd7d7bd0a992ac49f6d272715a3df68b73.tar.bz2 |
Cygwin: AF_UNIX: recvmsg: fix the MSG_DONTWAIT handling for datagrams
A bound datagram socket has to wait for a pipe connection before it
can try to read. It does this by calling listen_pipe. If the socket
is in nonblocking mode and no connection is immediately available,
then listen_pipe will fail with EAGAIN, as it should. This commit
makes sure that the same thing happens in blocking mode if
MSG_DONTWAIT is set.
To help with this, add a parameter "nonblocking" to listen_pipe.
-rw-r--r-- | winsup/cygwin/fhandler.h | 2 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_socket_unix.cc | 20 |
2 files changed, 16 insertions, 6 deletions
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 932f535..e1241de 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -1190,7 +1190,7 @@ class fhandler_socket_unix : public fhandler_socket void xchg_sock_info (); int wait_pipe (PUNICODE_STRING pipe_name); int connect_pipe (PUNICODE_STRING pipe_name); - int listen_pipe (); + int listen_pipe (bool nonblocking); int disconnect_pipe (HANDLE ph); pipe_end get_pipe_end () const { return _pipe_end; } diff --git a/winsup/cygwin/fhandler_socket_unix.cc b/winsup/cygwin/fhandler_socket_unix.cc index 61cd438..b1ad1c0 100644 --- a/winsup/cygwin/fhandler_socket_unix.cc +++ b/winsup/cygwin/fhandler_socket_unix.cc @@ -1114,7 +1114,7 @@ fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name) } int -fhandler_socket_unix::listen_pipe () +fhandler_socket_unix::listen_pipe (bool nonblocking) { NTSTATUS status; IO_STATUS_BLOCK io; @@ -1123,7 +1123,7 @@ fhandler_socket_unix::listen_pipe () int ret = -1; io.Status = STATUS_PENDING; - if (!is_nonblocking () && !(evt = create_event ())) + if (!nonblocking && !(evt = create_event ())) return -1; status = NtFsControlFile (get_handle (), evt, NULL, NULL, &io, FSCTL_PIPE_LISTEN, NULL, 0, NULL, 0); @@ -1784,7 +1784,7 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, int *len, int flags) set_errno (EINVAL); return -1; } - if (listen_pipe () == 0) + if (listen_pipe (is_nonblocking ()) == 0) { /* Our handle is now connected with a client. This handle is used for the accepted socket. Our handle has to be replaced with a @@ -2516,8 +2516,18 @@ fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags) /* We've created the pipe and we need to wait for a sender to connect to it. */ { - /* FIXME: What about nonblocking case? */ - if (listen_pipe () < 0) + /* Handle MSG_DONTWAIT in blocking mode. */ + bool nonblocking = is_nonblocking (); + + if (!is_nonblocking () && (flags & MSG_DONTWAIT)) + { + nonblocking = true; + set_pipe_non_blocking (true); + } + int ret = listen_pipe (nonblocking); + if (!is_nonblocking () && (flags & MSG_DONTWAIT)) + set_pipe_non_blocking (false); + if (ret < 0) __leave; /* We'll need to disconnect at the end so that we can accept another connection later. */ |