Cygwin: AF_UNIX: adapt grab_admin_pkt to mqueues
Use peek_mqueue instead of peek_pipe, and remove the latter. Use mq_receive instead of NtReadFile.
This commit is contained in:
parent
92a7d6b532
commit
9e3a04efb6
|
@ -1095,7 +1095,7 @@ class fhandler_socket_unix : public fhandler_socket
|
||||||
char get_type_char ();
|
char get_type_char ();
|
||||||
void set_pipe_non_blocking (bool nonblocking);
|
void set_pipe_non_blocking (bool nonblocking);
|
||||||
int send_sock_info (bool from_bind);
|
int send_sock_info (bool from_bind);
|
||||||
int grab_admin_pkt ();
|
int grab_admin_pkt (bool peek = true);
|
||||||
int recv_peer_info ();
|
int recv_peer_info ();
|
||||||
static NTSTATUS npfs_handle (HANDLE &nph);
|
static NTSTATUS npfs_handle (HANDLE &nph);
|
||||||
int create_mqueue (bool listener = false);
|
int create_mqueue (bool listener = false);
|
||||||
|
@ -1107,7 +1107,6 @@ class fhandler_socket_unix : public fhandler_socket
|
||||||
int connect_pipe (PUNICODE_STRING pipe_name);
|
int connect_pipe (PUNICODE_STRING pipe_name);
|
||||||
int listen_pipe ();
|
int listen_pipe ();
|
||||||
ssize_t peek_mqueue (char *buf, size_t buflen, bool nonblocking = true);
|
ssize_t peek_mqueue (char *buf, size_t buflen, bool nonblocking = true);
|
||||||
ULONG peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize, HANDLE evt);
|
|
||||||
int disconnect_pipe (HANDLE ph);
|
int disconnect_pipe (HANDLE ph);
|
||||||
/* The NULL pointer check is required for FS methods like fstat. When
|
/* The NULL pointer check is required for FS methods like fstat. When
|
||||||
called via stat or lstat, there's no shared memory, just a path in pc. */
|
called via stat or lstat, there's no shared memory, just a path in pc. */
|
||||||
|
|
|
@ -673,72 +673,63 @@ fhandler_socket_unix::send_sock_info (bool from_bind)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Checks if the next packet in the pipe is an administrative packet.
|
/* Reads an administrative packet from the pipe and handles it. If
|
||||||
If so, it reads it from the pipe, handles it. Returns an error code. */
|
PEEK is true, checks first to see if the next packet in the pipe is
|
||||||
|
an administrative packet; otherwise the caller must set io_lock and
|
||||||
|
check this. Returns an error code, but callers ignore it. */
|
||||||
int
|
int
|
||||||
fhandler_socket_unix::grab_admin_pkt ()
|
fhandler_socket_unix::grab_admin_pkt (bool peek)
|
||||||
{
|
{
|
||||||
HANDLE evt;
|
|
||||||
NTSTATUS status;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
/* MAX_PATH is more than sufficient for admin packets. */
|
/* MAX_PATH is more than sufficient for admin packets. */
|
||||||
PFILE_PIPE_PEEK_BUFFER pbuf = (PFILE_PIPE_PEEK_BUFFER) alloca (MAX_PATH);
|
af_unix_pkt_hdr_t *packet = (af_unix_pkt_hdr_t *) alloca (MAX_PATH);
|
||||||
if (!(evt = create_event ()))
|
ssize_t nr;
|
||||||
return 0;
|
|
||||||
io_lock ();
|
if (peek)
|
||||||
ULONG ret_len = peek_pipe (pbuf, MAX_PATH, evt);
|
|
||||||
if (pbuf->NumberOfMessages == 0 || ret_len < sizeof (af_unix_pkt_hdr_t))
|
|
||||||
{
|
{
|
||||||
io_unlock ();
|
io_lock ();
|
||||||
NtClose (evt);
|
nr = peek_mqueue ((char *) packet, MAX_PATH);
|
||||||
return 0;
|
if (nr < 0)
|
||||||
}
|
|
||||||
af_unix_pkt_hdr_t *packet = (af_unix_pkt_hdr_t *) pbuf->Data;
|
|
||||||
if (!packet->admin_pkt)
|
|
||||||
io_unlock ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
packet = (af_unix_pkt_hdr_t *) pbuf;
|
|
||||||
status = NtReadFile (get_handle (), evt, NULL, NULL, &io, packet,
|
|
||||||
MAX_PATH, NULL, NULL);
|
|
||||||
if (status == STATUS_PENDING)
|
|
||||||
{
|
{
|
||||||
/* Very short-lived */
|
io_unlock ();
|
||||||
status = NtWaitForSingleObject (evt, FALSE, NULL);
|
if (get_errno () == EAGAIN)
|
||||||
if (NT_SUCCESS (status))
|
return 0;
|
||||||
status = io.Status;
|
return get_errno ();
|
||||||
}
|
}
|
||||||
io_unlock ();
|
if (!packet->admin_pkt)
|
||||||
if (NT_SUCCESS (status))
|
|
||||||
{
|
{
|
||||||
state_lock ();
|
io_unlock ();
|
||||||
if (packet->shut_info)
|
return 0;
|
||||||
{
|
|
||||||
/* Peer's shutdown sends the SHUT flags as used by the peer.
|
|
||||||
They have to be reversed for our side. */
|
|
||||||
int shut_info = saw_shutdown ();
|
|
||||||
if (packet->shut_info & _SHUT_RECV)
|
|
||||||
shut_info |= _SHUT_SEND;
|
|
||||||
if (packet->shut_info & _SHUT_SEND)
|
|
||||||
shut_info |= _SHUT_RECV;
|
|
||||||
saw_shutdown (shut_info);
|
|
||||||
/* FIXME: anything else here? */
|
|
||||||
}
|
|
||||||
if (packet->name_len > 0)
|
|
||||||
peer_sun_path (AF_UNIX_PKT_NAME (packet), packet->name_len);
|
|
||||||
if (packet->cmsg_len > 0)
|
|
||||||
{
|
|
||||||
struct cmsghdr *cmsg = (struct cmsghdr *)
|
|
||||||
alloca (packet->cmsg_len);
|
|
||||||
memcpy (cmsg, AF_UNIX_PKT_CMSG (packet), packet->cmsg_len);
|
|
||||||
if (cmsg->cmsg_level == SOL_SOCKET
|
|
||||||
&& cmsg->cmsg_type == SCM_CREDENTIALS)
|
|
||||||
peer_cred ((struct ucred *) CMSG_DATA(cmsg));
|
|
||||||
}
|
|
||||||
state_unlock ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NtClose (evt);
|
nr = _mq_recv (get_mqd_in (), (char *) packet, MAX_PATH, 0);
|
||||||
|
io_unlock ();
|
||||||
|
if (nr < 0)
|
||||||
|
return get_errno ();
|
||||||
|
state_lock ();
|
||||||
|
if (packet->shut_info)
|
||||||
|
{
|
||||||
|
/* Peer's shutdown sends the SHUT flags as used by the peer.
|
||||||
|
They have to be reversed for our side. */
|
||||||
|
int shut_info = saw_shutdown ();
|
||||||
|
if (packet->shut_info & _SHUT_RECV)
|
||||||
|
shut_info |= _SHUT_SEND;
|
||||||
|
if (packet->shut_info & _SHUT_SEND)
|
||||||
|
shut_info |= _SHUT_RECV;
|
||||||
|
saw_shutdown (shut_info);
|
||||||
|
/* FIXME: anything else here? */
|
||||||
|
}
|
||||||
|
if (packet->name_len > 0)
|
||||||
|
peer_sun_path (AF_UNIX_PKT_NAME (packet), packet->name_len);
|
||||||
|
if (packet->cmsg_len > 0)
|
||||||
|
{
|
||||||
|
struct cmsghdr *cmsg = (struct cmsghdr *)
|
||||||
|
alloca (packet->cmsg_len);
|
||||||
|
memcpy (cmsg, AF_UNIX_PKT_CMSG (packet), packet->cmsg_len);
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET
|
||||||
|
&& cmsg->cmsg_type == SCM_CREDENTIALS)
|
||||||
|
peer_cred ((struct ucred *) CMSG_DATA(cmsg));
|
||||||
|
}
|
||||||
|
state_unlock ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1116,27 +1107,6 @@ fhandler_socket_unix::peek_mqueue (char *buf, size_t buflen, bool nonblocking)
|
||||||
return _mq_peek (get_mqd_in (), buf, buflen, nonblocking);
|
return _mq_peek (get_mqd_in (), buf, buflen, nonblocking);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
|
||||||
fhandler_socket_unix::peek_pipe (PFILE_PIPE_PEEK_BUFFER pbuf, ULONG psize,
|
|
||||||
HANDLE evt)
|
|
||||||
{
|
|
||||||
NTSTATUS status;
|
|
||||||
IO_STATUS_BLOCK io;
|
|
||||||
|
|
||||||
status = NtFsControlFile (get_handle (), evt, NULL, NULL, &io,
|
|
||||||
FSCTL_PIPE_PEEK, NULL, 0, pbuf, psize);
|
|
||||||
if (status == STATUS_PENDING)
|
|
||||||
{
|
|
||||||
/* Very short-lived */
|
|
||||||
status = NtWaitForSingleObject (evt ?: get_handle (), FALSE, NULL);
|
|
||||||
if (NT_SUCCESS (status))
|
|
||||||
status = io.Status;
|
|
||||||
}
|
|
||||||
return NT_SUCCESS (status) ? (io.Information
|
|
||||||
- offsetof (FILE_PIPE_PEEK_BUFFER, Data))
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fhandler_socket_unix::disconnect_pipe (HANDLE ph)
|
fhandler_socket_unix::disconnect_pipe (HANDLE ph)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue