aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Brown <kbrown@cornell.edu>2021-04-06 17:56:45 -0400
committerKen Brown <kbrown@cornell.edu>2021-04-07 10:43:09 -0400
commit5a1b11bd7d7bd0a992ac49f6d272715a3df68b73 (patch)
tree93fe872c95afe7ee8c0dc5025aae7b0620cd8988
parentdd99a62277bbf565f7aca3be43d161e38dac4d93 (diff)
downloadnewlib-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.h2
-rw-r--r--winsup/cygwin/fhandler_socket_unix.cc20
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. */