4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-08 18:19:08 +08:00

Cygwin: AF_UNIX: recvmsg: fix MSG_PEEK support for datagrams

Add a new HANDLE argument to peek_pipe and peek_pipe_poll so that the
caller can specify a pipe handle to use in lieu of get_handle().  Use
this in recvmsg to make the MSG_PEEK flag work for unbound datagram
sockets.

Untested.
This commit is contained in:
Ken Brown 2020-10-29 12:17:28 -04:00
parent d68d091944
commit a55b1a60c5
2 changed files with 11 additions and 10 deletions

View File

@ -1146,9 +1146,9 @@ class fhandler_socket_unix : public fhandler_socket
void set_unread (bool val) { shmem->set_unread (val); } void set_unread (bool val) { shmem->set_unread (val); }
bool get_unread () const { return shmem->get_unread (); } bool get_unread () const { return shmem->get_unread (); }
NTSTATUS peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize, HANDLE evt, NTSTATUS peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize, HANDLE evt,
ULONG &ret_len); ULONG &ret_len, HANDLE ph = NULL);
NTSTATUS peek_pipe_poll (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize, NTSTATUS peek_pipe_poll (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize,
HANDLE evt, ULONG &ret_len); HANDLE evt, ULONG &ret_len, HANDLE ph = NULL);
int grab_admin_pkt (bool peek = true); int grab_admin_pkt (bool peek = true);
bool create_cmsg_data (af_unix_pkt_hdr_t *packet, const struct msghdr *msg); bool create_cmsg_data (af_unix_pkt_hdr_t *packet, const struct msghdr *msg);

View File

@ -1138,12 +1138,12 @@ fhandler_socket_unix::listen_pipe ()
NTSTATUS NTSTATUS
fhandler_socket_unix::peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize, fhandler_socket_unix::peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize,
HANDLE evt, ULONG &ret_len) HANDLE evt, ULONG &ret_len, HANDLE ph)
{ {
NTSTATUS status; NTSTATUS status;
IO_STATUS_BLOCK io; IO_STATUS_BLOCK io;
status = NtFsControlFile (get_handle (), evt, NULL, NULL, &io, status = NtFsControlFile (ph ?: get_handle (), evt, NULL, NULL, &io,
FSCTL_PIPE_PEEK, NULL, 0, pbuf, psize); FSCTL_PIPE_PEEK, NULL, 0, pbuf, psize);
if (status == STATUS_PENDING) if (status == STATUS_PENDING)
{ {
@ -1164,7 +1164,8 @@ fhandler_socket_unix::peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize,
/* Like peek_pipe, but poll until there's data, an error, or a signal. */ /* Like peek_pipe, but poll until there's data, an error, or a signal. */
NTSTATUS NTSTATUS
fhandler_socket_unix::peek_pipe_poll (PFILE_PIPE_PEEK_BUFFER pbuf, fhandler_socket_unix::peek_pipe_poll (PFILE_PIPE_PEEK_BUFFER pbuf,
ULONG psize, HANDLE evt, ULONG &ret_len) ULONG psize, HANDLE evt, ULONG &ret_len,
HANDLE ph)
{ {
NTSTATUS status; NTSTATUS status;
@ -1174,7 +1175,7 @@ fhandler_socket_unix::peek_pipe_poll (PFILE_PIPE_PEEK_BUFFER pbuf,
DWORD waitret; DWORD waitret;
io_lock (); io_lock ();
status = peek_pipe (pbuf, psize, evt, ret_len); status = peek_pipe (pbuf, psize, evt, ret_len, ph);
io_unlock (); io_unlock ();
if (ret_len || !NT_SUCCESS (status)) if (ret_len || !NT_SUCCESS (status))
break; break;
@ -2094,8 +2095,6 @@ fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
__leave; __leave;
} }
} }
/* FIXME: This currently doesn't work for unbound datagram
sockets because peek_pipe calls get_handle. */
if (flags & MSG_PEEK) if (flags & MSG_PEEK)
while (1) while (1)
{ {
@ -2114,7 +2113,8 @@ fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
if (is_nonblocking () || (flags & MSG_DONTWAIT)) if (is_nonblocking () || (flags & MSG_DONTWAIT))
{ {
io_lock (); io_lock ();
status = peek_pipe (pbuf, psize, evt, ret_len); status = peek_pipe (pbuf, psize, evt, ret_len,
ph ?: get_handle ());
io_unlock (); io_unlock ();
if (!ret_len) if (!ret_len)
{ {
@ -2125,7 +2125,8 @@ fhandler_socket_unix::recvmsg (struct msghdr *msg, int flags)
else else
{ {
restart: restart:
status = peek_pipe_poll (pbuf, MAX_PATH, evt, ret_len); status = peek_pipe_poll (pbuf, MAX_PATH, evt, ret_len,
ph ?: get_handle ());
switch (status) switch (status)
{ {
case STATUS_SUCCESS: case STATUS_SUCCESS: