Cygwin: AF_UNIX: Rework internal methods to return HANDLEs

- Return HANDLE value of just opened/created objects

- open_pipe does not set the fhandler io_handle.  The caller
  is now resonsible how to use the handle.

- Rename create_file/open_file to create_socket/open_socket

- Drop sockaddr_in validity check from connect.  It's performed
  in open_socket anyway.
This commit is contained in:
Corinna Vinschen 2019-02-09 19:52:40 +01:00
parent bd16e44f1b
commit debdfb8bb6
2 changed files with 64 additions and 67 deletions

View File

@ -1003,10 +1003,11 @@ class fhandler_socket_unix : public fhandler_socket
PUNICODE_STRING pipe_name);
static HANDLE create_reparse_point (const sun_name_t *sun,
PUNICODE_STRING pipe_name);
HANDLE create_file (const sun_name_t *sun);
static int open_abstract_link (sun_name_t *sun, PUNICODE_STRING pipe_name);
static int open_reparse_point (sun_name_t *sun, PUNICODE_STRING pipe_name);
static int open_file (sun_name_t *sun, int &type, PUNICODE_STRING pipe_name);
HANDLE create_socket (const sun_name_t *sun);
static HANDLE open_abstract_link (sun_name_t *sun, PUNICODE_STRING pipe_name);
static HANDLE open_reparse_point (sun_name_t *sun, PUNICODE_STRING pipe_name);
static HANDLE open_socket (sun_name_t *sun, int &type,
PUNICODE_STRING pipe_name);
HANDLE autobind (sun_name_t *sun);
wchar_t get_type_char ();
void set_pipe_non_blocking (bool nonblocking);
@ -1016,7 +1017,8 @@ class fhandler_socket_unix : public fhandler_socket
static NTSTATUS npfs_handle (HANDLE &nph);
HANDLE create_pipe (bool single_instance);
HANDLE create_pipe_instance ();
NTSTATUS open_pipe (PUNICODE_STRING pipe_name, bool xchg_sock_info);
NTSTATUS open_pipe (HANDLE &ph, PUNICODE_STRING pipe_name,
bool xchg_sock_info);
int wait_pipe (PUNICODE_STRING pipe_name);
int connect_pipe (PUNICODE_STRING pipe_name);
int listen_pipe ();

View File

@ -404,7 +404,7 @@ out:
}
HANDLE
fhandler_socket_unix::create_file (const sun_name_t *sun)
fhandler_socket_unix::create_socket (const sun_name_t *sun)
{
if (sun->un_len <= (socklen_t) sizeof (sa_family_t)
|| (sun->un_len == 3 && sun->un.sun_path[0] == '\0'))
@ -417,7 +417,7 @@ fhandler_socket_unix::create_file (const sun_name_t *sun)
return create_reparse_point (sun, pc.get_nt_native_path ());
}
int
HANDLE
fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
PUNICODE_STRING pipe_name)
{
@ -437,25 +437,25 @@ fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
return NULL;
}
if (pipe_name)
status = NtQuerySymbolicLinkObject (fh, pipe_name, NULL);
NtClose (fh);
if (pipe_name)
{
if (!NT_SUCCESS (status))
{
NtClose (fh);
__seterrno_from_nt_status (status);
return -1;
return NULL;
}
/* Enforce NUL-terminated pipe name. */
pipe_name->Buffer[pipe_name->Length / sizeof (WCHAR)] = L'\0';
}
return 0;
return fh;
}
int
HANDLE
fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
PUNICODE_STRING pipe_name)
{
@ -470,12 +470,12 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
if (pc.error)
{
set_errno (pc.error);
return -1;
return NULL;
}
if (!pc.exists ())
{
set_errno (ENOENT);
return -1;
return NULL;
}
pc.get_object_attr (attr, sec_none_nih);
do
@ -497,21 +497,20 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
&& !_my_tls.call_signal_handler ())
{
set_errno (EINTR);
return -1;
return NULL;
}
yield ();
}
else if (!NT_SUCCESS (status))
{
__seterrno_from_nt_status (status);
return -1;
return NULL;
}
}
while (status == STATUS_SHARING_VIOLATION);
rp = (PREPARSE_GUID_DATA_BUFFER) tp.c_get ();
status = NtFsControlFile (fh, NULL, NULL, NULL, &io, FSCTL_GET_REPARSE_POINT,
NULL, 0, rp, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
NtClose (fh);
if (rp->ReparseTag == IO_REPARSE_TAG_CYGUNIX
&& memcmp (CYGWIN_SOCKET_GUID, &rp->ReparseGuid, sizeof (GUID)) == 0)
{
@ -524,25 +523,28 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
memcpy (pipe_name->Buffer, rep_pipe_name->PipeName,
rep_pipe_name->Length + sizeof (WCHAR));
}
return 0;
return fh;
}
return -1;
NtClose (fh);
return NULL;
}
int
fhandler_socket_unix::open_file (sun_name_t *sun, int &type,
HANDLE
fhandler_socket_unix::open_socket (sun_name_t *sun, int &type,
PUNICODE_STRING pipe_name)
{
int ret = -1;
HANDLE fh = NULL;
if (sun->un_len <= (socklen_t) sizeof (sa_family_t)
|| (sun->un_len == 3 && sun->un.sun_path[0] == '\0'))
set_errno (EINVAL);
else if (sun->un.sun_family != AF_UNIX)
set_errno (EAFNOSUPPORT);
else if (sun->un.sun_path[0] == '\0')
ret = open_abstract_link (sun, pipe_name);
fh = open_abstract_link (sun, pipe_name);
else
ret = open_reparse_point (sun, pipe_name);
if (!ret)
fh = open_reparse_point (sun, pipe_name);
if (fh)
switch (pipe_name->Buffer[CYGWIN_PIPE_SOCKET_TYPE_POS])
{
case 'd':
@ -553,10 +555,11 @@ fhandler_socket_unix::open_file (sun_name_t *sun, int &type,
break;
default:
set_errno (EINVAL);
ret = -1;
NtClose (fh);
fh = NULL;
break;
}
return ret;
return fh;
}
HANDLE
@ -919,7 +922,8 @@ fhandler_socket_unix::create_pipe_instance ()
}
NTSTATUS
fhandler_socket_unix::open_pipe (PUNICODE_STRING pipe_name, bool xchg_sock_info)
fhandler_socket_unix::open_pipe (HANDLE &pipe, PUNICODE_STRING pipe_name,
bool xchg_sock_info)
{
NTSTATUS status;
HANDLE npfsh;
@ -938,7 +942,7 @@ fhandler_socket_unix::open_pipe (PUNICODE_STRING pipe_name, bool xchg_sock_info)
status = NtOpenFile (&ph, access, &attr, &io, sharing, 0);
if (NT_SUCCESS (status))
{
set_handle (ph);
pipe = ph;
if (xchg_sock_info)
send_sock_info (false);
}
@ -1040,10 +1044,11 @@ int
fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name)
{
NTSTATUS status;
HANDLE ph;
/* Try connecting first. If it doesn't work, wait for the pipe
to become available. */
status = open_pipe (pipe_name, get_socket_type () != SOCK_DGRAM);
status = open_pipe (ph, pipe_name, get_socket_type () != SOCK_DGRAM);
if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
return wait_pipe (pipe_name);
if (!NT_SUCCESS (status))
@ -1052,6 +1057,7 @@ fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name)
so_error (get_errno ());
return -1;
}
set_handle (ph);
so_error (0);
return 0;
}
@ -1291,7 +1297,10 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name)
{
case STATUS_SUCCESS:
{
status = open_pipe (pipe_name, get_socket_type () != SOCK_DGRAM);
HANDLE ph;
status = open_pipe (ph, pipe_name,
get_socket_type () != SOCK_DGRAM);
if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
{
/* Another concurrent connect grabbed the pipe instance
@ -1307,6 +1316,8 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name)
}
else if (!NT_SUCCESS (status))
error = geterrno_from_nt_status (status);
else
set_handle (ph);
}
break;
case STATUS_OBJECT_NAME_NOT_FOUND:
@ -1375,7 +1386,7 @@ int
fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
fhandler_socket *fh_out)
{
HANDLE pipe;
HANDLE ph, ph2;
sun_name_t sun;
fhandler_socket_unix *fh = (fhandler_socket_unix *) fh_out;
@ -1409,17 +1420,18 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
set_ino (get_unique_id ());
/* bind/listen 1st socket */
gen_pipe_name ();
pipe = create_pipe (true);
if (!pipe)
ph = create_pipe (true);
if (!ph)
goto create_pipe_failed;
set_handle (pipe);
set_handle (ph);
sun_path (&sun);
fh->peer_sun_path (&sun);
connect_state (listener);
/* connect 2nd socket, even for DGRAM. There's no difference as far
as socketpairs are concerned. */
if (fh->open_pipe (pc.get_nt_native_path (), false) < 0)
if (fh->open_pipe (ph2, pc.get_nt_native_path (), false) < 0)
goto fh_open_pipe_failed;
fh->set_handle (ph2);
fh->connect_state (connected);
if (flags & SOCK_NONBLOCK)
{
@ -1434,7 +1446,7 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
return 0;
fh_open_pipe_failed:
NtClose (pipe);
NtClose (ph);
create_pipe_failed:
NtUnmapViewOfSection (GetCurrentProcess (), fh->shmem);
NtClose (fh->shmem_handle);
@ -1485,7 +1497,7 @@ fhandler_socket_unix::bind (const struct sockaddr *name, int namelen)
}
set_handle (pipe);
}
backing_file_handle = unnamed ? autobind (&sun) : create_file (&sun);
backing_file_handle = unnamed ? autobind (&sun) : create_socket (&sun);
if (!backing_file_handle)
{
set_handle (NULL);
@ -1656,6 +1668,7 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
int peer_type;
WCHAR pipe_name_buf[CYGWIN_PIPE_SOCKET_NAME_LEN + 1];
UNICODE_STRING pipe_name;
HANDLE fh = NULL;
/* Test and set connection state. */
conn_lock ();
@ -1679,28 +1692,10 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
}
connect_state (connect_pending);
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. */
RtlInitEmptyUnicodeString (&pipe_name, pipe_name_buf, sizeof pipe_name_buf);
if (open_file (&sun, peer_type, &pipe_name) < 0)
fh = open_socket (&sun, peer_type, &pipe_name);
if (!fh)
{
connect_state (unconnected);
return -1;
@ -1708,14 +1703,14 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
if (peer_type != get_socket_type ())
{
set_errno (EINVAL);
NtClose (fh);
connect_state (unconnected);
return -1;
}
peer_sun_path (&sun);
if (get_socket_type () != SOCK_DGRAM)
{
if (connect_pipe (&pipe_name) < 0)
if (get_socket_type () != SOCK_DGRAM && connect_pipe (&pipe_name) < 0)
{
NtClose (fh);
if (get_errno () != EINPROGRESS)
{
peer_sun_path (NULL);
@ -1723,7 +1718,7 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
}
return -1;
}
}
NtClose (fh);
connect_state (connected);
return 0;
}