4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-02-28 03:27:46 +08:00

Cygwin: AF_UNIX: rework some internal methods

- open_abstract_link, open_reparse_point, and open_socket now return
  HANDLEs

- connect no longer checks the validity of the sockaddr structure.
  It's done in open_socket.
This commit is contained in:
Ken Brown 2021-05-07 11:19:51 -04:00
parent 700c140ba6
commit 83b2ac199d
2 changed files with 37 additions and 51 deletions

View File

@ -1086,9 +1086,9 @@ class fhandler_socket_unix : public fhandler_socket
static HANDLE create_reparse_point (const sun_name_t *sun, static HANDLE create_reparse_point (const sun_name_t *sun,
const char *mqueue_name); const char *mqueue_name);
HANDLE create_socket (const sun_name_t *sun); HANDLE create_socket (const sun_name_t *sun);
static int open_abstract_link (sun_name_t *sun, char *mqueue_name); static HANDLE open_abstract_link (sun_name_t *sun, char *mqueue_name);
static int open_reparse_point (sun_name_t *sun, char *mqueue_name); static HANDLE open_reparse_point (sun_name_t *sun, char *mqueue_name);
static int open_socket (sun_name_t *sun, int &type, char *mqueue_name); static HANDLE open_socket (sun_name_t *sun, int &type, char *mqueue_name);
HANDLE autobind (sun_name_t *sun); HANDLE autobind (sun_name_t *sun);
char get_type_char (); char get_type_char ();
void set_pipe_non_blocking (bool nonblocking); void set_pipe_non_blocking (bool nonblocking);

View File

@ -419,7 +419,7 @@ fhandler_socket_unix::create_socket (const sun_name_t *sun)
return create_reparse_point (sun, get_mqueue_name ()); return create_reparse_point (sun, get_mqueue_name ());
} }
int HANDLE
fhandler_socket_unix::open_abstract_link (sun_name_t *sun, fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
char *mqueue_name) char *mqueue_name)
{ {
@ -439,7 +439,7 @@ fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
{ {
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return NULL;
} }
if (mqueue_name) if (mqueue_name)
{ {
@ -447,20 +447,20 @@ fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
MAX_PATH * sizeof (WCHAR)); MAX_PATH * sizeof (WCHAR));
status = NtQuerySymbolicLinkObject (fh, &umqueue_name, NULL); status = NtQuerySymbolicLinkObject (fh, &umqueue_name, NULL);
} }
NtClose (fh);
if (mqueue_name) if (mqueue_name)
{ {
if (!NT_SUCCESS (status)) if (!NT_SUCCESS (status))
{ {
NtClose (fh);
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return NULL;
} }
sys_wcstombs (mqueue_name, MAX_PATH, wmqueue_name); sys_wcstombs (mqueue_name, MAX_PATH, wmqueue_name);
} }
return 0; return fh;
} }
int HANDLE
fhandler_socket_unix::open_reparse_point (sun_name_t *sun, fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
char *mqueue_name) char *mqueue_name)
{ {
@ -475,12 +475,12 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
if (pc.error) if (pc.error)
{ {
set_errno (pc.error); set_errno (pc.error);
return -1; return NULL;
} }
if (!pc.exists ()) if (!pc.exists ())
{ {
set_errno (ENOENT); set_errno (ENOENT);
return -1; return NULL;
} }
pc.get_object_attr (attr, sec_none_nih); pc.get_object_attr (attr, sec_none_nih);
do do
@ -502,45 +502,47 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
&& !_my_tls.call_signal_handler ()) && !_my_tls.call_signal_handler ())
{ {
set_errno (EINTR); set_errno (EINTR);
return -1; return NULL;
} }
yield (); yield ();
} }
else if (!NT_SUCCESS (status)) else if (!NT_SUCCESS (status))
{ {
__seterrno_from_nt_status (status); __seterrno_from_nt_status (status);
return -1; return NULL;
} }
} }
while (status == STATUS_SHARING_VIOLATION); while (status == STATUS_SHARING_VIOLATION);
rp = (PREPARSE_GUID_DATA_BUFFER) tp.c_get (); rp = (PREPARSE_GUID_DATA_BUFFER) tp.c_get ();
status = NtFsControlFile (fh, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT, status = NtFsControlFile (fh, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT,
NULL, 0, rp, MAXIMUM_REPARSE_DATA_BUFFER_SIZE); NULL, 0, rp, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
NtClose (fh);
if (rp->ReparseTag == IO_REPARSE_TAG_CYGUNIX if (rp->ReparseTag == IO_REPARSE_TAG_CYGUNIX
&& memcmp (CYGWIN_SOCKET_GUID, &rp->ReparseGuid, sizeof (GUID)) == 0) && memcmp (CYGWIN_SOCKET_GUID, &rp->ReparseGuid, sizeof (GUID)) == 0)
{ {
if (mqueue_name) if (mqueue_name)
strcpy (mqueue_name, (char *) rp->GenericReparseBuffer.DataBuffer); strcpy (mqueue_name, (char *) rp->GenericReparseBuffer.DataBuffer);
return 0; return fh;
} }
return -1; NtClose (fh);
return NULL;
} }
int HANDLE
fhandler_socket_unix::open_socket (sun_name_t *sun, int &type, fhandler_socket_unix::open_socket (sun_name_t *sun, int &type,
char *mqueue_name) char *mqueue_name)
{ {
int ret = -1; HANDLE fh = NULL;
if (sun->un_len <= (socklen_t) sizeof (sa_family_t) if (sun->un_len <= (socklen_t) sizeof (sa_family_t)
|| (sun->un_len == 3 && sun->un.sun_path[0] == '\0')) || (sun->un_len == 3 && sun->un.sun_path[0] == '\0'))
set_errno (EINVAL); set_errno (EINVAL);
else if (sun->un.sun_family != AF_UNIX)
set_errno (EAFNOSUPPORT);
else if (sun->un.sun_path[0] == '\0') else if (sun->un.sun_path[0] == '\0')
ret = open_abstract_link (sun, mqueue_name); fh = open_abstract_link (sun, mqueue_name);
else else
ret = open_reparse_point (sun, mqueue_name); fh = open_reparse_point (sun, mqueue_name);
if (!ret) if (fh)
switch (mqueue_name[CYGWIN_MQUEUE_SOCKET_TYPE_POS]) switch (mqueue_name[CYGWIN_MQUEUE_SOCKET_TYPE_POS])
{ {
case 'd': case 'd':
@ -551,10 +553,11 @@ fhandler_socket_unix::open_socket (sun_name_t *sun, int &type,
break; break;
default: default:
set_errno (EINVAL); set_errno (EINVAL);
ret = -1; NtClose (fh);
fh = NULL;
break; break;
} }
return ret; return fh;
} }
HANDLE HANDLE
@ -1681,6 +1684,7 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
sun_name_t sun (name, namelen); sun_name_t sun (name, namelen);
int peer_type; int peer_type;
char mqueue_name[CYGWIN_MQUEUE_SOCKET_NAME_LEN + 1]; char mqueue_name[CYGWIN_MQUEUE_SOCKET_NAME_LEN + 1];
HANDLE fh = NULL;
/* Test and set connection state. */ /* Test and set connection state. */
conn_lock (); conn_lock ();
@ -1711,27 +1715,9 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
} }
connect_state (connect_pending); connect_state (connect_pending);
conn_unlock (); conn_unlock ();
/* Check validity of name */
if (sun.un_len <= (int) sizeof (sa_family_t))
{
set_errno (EINVAL);
connect_state (unconnected);
return -1;
}
if (sun.un.sun_family != AF_UNIX)
{
set_errno (EAFNOSUPPORT);
connect_state (unconnected);
return -1;
}
if (sun.un_len == 3 && sun.un.sun_path[0] == '\0')
{
set_errno (EINVAL);
connect_state (unconnected);
return -1;
}
/* Check if peer address exists. */ /* Check if peer address exists. */
if (open_socket (&sun, peer_type, mqueue_name) < 0) fh = open_socket (&sun, peer_type, mqueue_name);
if (!fh)
{ {
connect_state (unconnected); connect_state (unconnected);
return -1; return -1;
@ -1739,22 +1725,22 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
if (peer_type != get_socket_type ()) if (peer_type != get_socket_type ())
{ {
set_errno (EINVAL); set_errno (EINVAL);
NtClose (fh);
connect_state (unconnected); connect_state (unconnected);
return -1; return -1;
} }
peer_sun_path (&sun); peer_sun_path (&sun);
if (get_socket_type () != SOCK_DGRAM) if (get_socket_type () != SOCK_DGRAM && connect_mqueue (mqueue_name) < 0)
{ {
if (connect_mqueue (mqueue_name) < 0) NtClose (fh);
if (get_errno () != EINPROGRESS)
{ {
if (get_errno () != EINPROGRESS) peer_sun_path (NULL);
{ connect_state (connect_failed);
peer_sun_path (NULL);
connect_state (connect_failed);
}
return -1;
} }
return -1;
} }
NtClose (fh);
connect_state (connected); connect_state (connected);
return 0; return 0;
} }