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:
parent
bd16e44f1b
commit
debdfb8bb6
|
@ -1003,10 +1003,11 @@ class fhandler_socket_unix : public fhandler_socket
|
||||||
PUNICODE_STRING pipe_name);
|
PUNICODE_STRING pipe_name);
|
||||||
static HANDLE create_reparse_point (const sun_name_t *sun,
|
static HANDLE create_reparse_point (const sun_name_t *sun,
|
||||||
PUNICODE_STRING pipe_name);
|
PUNICODE_STRING pipe_name);
|
||||||
HANDLE create_file (const sun_name_t *sun);
|
HANDLE create_socket (const sun_name_t *sun);
|
||||||
static int open_abstract_link (sun_name_t *sun, PUNICODE_STRING pipe_name);
|
static HANDLE 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 HANDLE 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);
|
static HANDLE open_socket (sun_name_t *sun, int &type,
|
||||||
|
PUNICODE_STRING pipe_name);
|
||||||
HANDLE autobind (sun_name_t *sun);
|
HANDLE autobind (sun_name_t *sun);
|
||||||
wchar_t get_type_char ();
|
wchar_t get_type_char ();
|
||||||
void set_pipe_non_blocking (bool nonblocking);
|
void set_pipe_non_blocking (bool nonblocking);
|
||||||
|
@ -1016,7 +1017,8 @@ class fhandler_socket_unix : public fhandler_socket
|
||||||
static NTSTATUS npfs_handle (HANDLE &nph);
|
static NTSTATUS npfs_handle (HANDLE &nph);
|
||||||
HANDLE create_pipe (bool single_instance);
|
HANDLE create_pipe (bool single_instance);
|
||||||
HANDLE create_pipe_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 wait_pipe (PUNICODE_STRING pipe_name);
|
||||||
int connect_pipe (PUNICODE_STRING pipe_name);
|
int connect_pipe (PUNICODE_STRING pipe_name);
|
||||||
int listen_pipe ();
|
int listen_pipe ();
|
||||||
|
|
|
@ -404,7 +404,7 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
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)
|
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'))
|
||||||
|
@ -417,7 +417,7 @@ fhandler_socket_unix::create_file (const sun_name_t *sun)
|
||||||
return create_reparse_point (sun, pc.get_nt_native_path ());
|
return create_reparse_point (sun, pc.get_nt_native_path ());
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
HANDLE
|
||||||
fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
|
fhandler_socket_unix::open_abstract_link (sun_name_t *sun,
|
||||||
PUNICODE_STRING pipe_name)
|
PUNICODE_STRING pipe_name)
|
||||||
{
|
{
|
||||||
|
@ -437,25 +437,25 @@ 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 (pipe_name)
|
if (pipe_name)
|
||||||
status = NtQuerySymbolicLinkObject (fh, pipe_name, NULL);
|
status = NtQuerySymbolicLinkObject (fh, pipe_name, NULL);
|
||||||
NtClose (fh);
|
|
||||||
if (pipe_name)
|
if (pipe_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;
|
||||||
}
|
}
|
||||||
/* Enforce NUL-terminated pipe name. */
|
/* Enforce NUL-terminated pipe name. */
|
||||||
pipe_name->Buffer[pipe_name->Length / sizeof (WCHAR)] = L'\0';
|
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,
|
fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
|
||||||
PUNICODE_STRING pipe_name)
|
PUNICODE_STRING pipe_name)
|
||||||
{
|
{
|
||||||
|
@ -470,12 +470,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
|
||||||
|
@ -497,21 +497,20 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -524,25 +523,28 @@ fhandler_socket_unix::open_reparse_point (sun_name_t *sun,
|
||||||
memcpy (pipe_name->Buffer, rep_pipe_name->PipeName,
|
memcpy (pipe_name->Buffer, rep_pipe_name->PipeName,
|
||||||
rep_pipe_name->Length + sizeof (WCHAR));
|
rep_pipe_name->Length + sizeof (WCHAR));
|
||||||
}
|
}
|
||||||
return 0;
|
return fh;
|
||||||
}
|
}
|
||||||
return -1;
|
NtClose (fh);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
HANDLE
|
||||||
fhandler_socket_unix::open_file (sun_name_t *sun, int &type,
|
fhandler_socket_unix::open_socket (sun_name_t *sun, int &type,
|
||||||
PUNICODE_STRING pipe_name)
|
PUNICODE_STRING pipe_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, pipe_name);
|
fh = open_abstract_link (sun, pipe_name);
|
||||||
else
|
else
|
||||||
ret = open_reparse_point (sun, pipe_name);
|
fh = open_reparse_point (sun, pipe_name);
|
||||||
if (!ret)
|
if (fh)
|
||||||
switch (pipe_name->Buffer[CYGWIN_PIPE_SOCKET_TYPE_POS])
|
switch (pipe_name->Buffer[CYGWIN_PIPE_SOCKET_TYPE_POS])
|
||||||
{
|
{
|
||||||
case 'd':
|
case 'd':
|
||||||
|
@ -553,10 +555,11 @@ fhandler_socket_unix::open_file (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
|
||||||
|
@ -919,7 +922,8 @@ fhandler_socket_unix::create_pipe_instance ()
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
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;
|
NTSTATUS status;
|
||||||
HANDLE npfsh;
|
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);
|
status = NtOpenFile (&ph, access, &attr, &io, sharing, 0);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
set_handle (ph);
|
pipe = ph;
|
||||||
if (xchg_sock_info)
|
if (xchg_sock_info)
|
||||||
send_sock_info (false);
|
send_sock_info (false);
|
||||||
}
|
}
|
||||||
|
@ -1040,10 +1044,11 @@ int
|
||||||
fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name)
|
fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name)
|
||||||
{
|
{
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
|
HANDLE ph;
|
||||||
|
|
||||||
/* Try connecting first. If it doesn't work, wait for the pipe
|
/* Try connecting first. If it doesn't work, wait for the pipe
|
||||||
to become available. */
|
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))
|
if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
|
||||||
return wait_pipe (pipe_name);
|
return wait_pipe (pipe_name);
|
||||||
if (!NT_SUCCESS (status))
|
if (!NT_SUCCESS (status))
|
||||||
|
@ -1052,6 +1057,7 @@ fhandler_socket_unix::connect_pipe (PUNICODE_STRING pipe_name)
|
||||||
so_error (get_errno ());
|
so_error (get_errno ());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
set_handle (ph);
|
||||||
so_error (0);
|
so_error (0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1297,10 @@ fhandler_socket_unix::wait_pipe_thread (PUNICODE_STRING pipe_name)
|
||||||
{
|
{
|
||||||
case STATUS_SUCCESS:
|
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))
|
if (STATUS_PIPE_NO_INSTANCE_AVAILABLE (status))
|
||||||
{
|
{
|
||||||
/* Another concurrent connect grabbed the pipe instance
|
/* 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))
|
else if (!NT_SUCCESS (status))
|
||||||
error = geterrno_from_nt_status (status);
|
error = geterrno_from_nt_status (status);
|
||||||
|
else
|
||||||
|
set_handle (ph);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case STATUS_OBJECT_NAME_NOT_FOUND:
|
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_unix::socketpair (int af, int type, int protocol, int flags,
|
||||||
fhandler_socket *fh_out)
|
fhandler_socket *fh_out)
|
||||||
{
|
{
|
||||||
HANDLE pipe;
|
HANDLE ph, ph2;
|
||||||
sun_name_t sun;
|
sun_name_t sun;
|
||||||
fhandler_socket_unix *fh = (fhandler_socket_unix *) fh_out;
|
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 ());
|
set_ino (get_unique_id ());
|
||||||
/* bind/listen 1st socket */
|
/* bind/listen 1st socket */
|
||||||
gen_pipe_name ();
|
gen_pipe_name ();
|
||||||
pipe = create_pipe (true);
|
ph = create_pipe (true);
|
||||||
if (!pipe)
|
if (!ph)
|
||||||
goto create_pipe_failed;
|
goto create_pipe_failed;
|
||||||
set_handle (pipe);
|
set_handle (ph);
|
||||||
sun_path (&sun);
|
sun_path (&sun);
|
||||||
fh->peer_sun_path (&sun);
|
fh->peer_sun_path (&sun);
|
||||||
connect_state (listener);
|
connect_state (listener);
|
||||||
/* connect 2nd socket, even for DGRAM. There's no difference as far
|
/* connect 2nd socket, even for DGRAM. There's no difference as far
|
||||||
as socketpairs are concerned. */
|
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;
|
goto fh_open_pipe_failed;
|
||||||
|
fh->set_handle (ph2);
|
||||||
fh->connect_state (connected);
|
fh->connect_state (connected);
|
||||||
if (flags & SOCK_NONBLOCK)
|
if (flags & SOCK_NONBLOCK)
|
||||||
{
|
{
|
||||||
|
@ -1434,7 +1446,7 @@ fhandler_socket_unix::socketpair (int af, int type, int protocol, int flags,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fh_open_pipe_failed:
|
fh_open_pipe_failed:
|
||||||
NtClose (pipe);
|
NtClose (ph);
|
||||||
create_pipe_failed:
|
create_pipe_failed:
|
||||||
NtUnmapViewOfSection (GetCurrentProcess (), fh->shmem);
|
NtUnmapViewOfSection (GetCurrentProcess (), fh->shmem);
|
||||||
NtClose (fh->shmem_handle);
|
NtClose (fh->shmem_handle);
|
||||||
|
@ -1485,7 +1497,7 @@ fhandler_socket_unix::bind (const struct sockaddr *name, int namelen)
|
||||||
}
|
}
|
||||||
set_handle (pipe);
|
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)
|
if (!backing_file_handle)
|
||||||
{
|
{
|
||||||
set_handle (NULL);
|
set_handle (NULL);
|
||||||
|
@ -1656,6 +1668,7 @@ fhandler_socket_unix::connect (const struct sockaddr *name, int namelen)
|
||||||
int peer_type;
|
int peer_type;
|
||||||
WCHAR pipe_name_buf[CYGWIN_PIPE_SOCKET_NAME_LEN + 1];
|
WCHAR pipe_name_buf[CYGWIN_PIPE_SOCKET_NAME_LEN + 1];
|
||||||
UNICODE_STRING pipe_name;
|
UNICODE_STRING pipe_name;
|
||||||
|
HANDLE fh = NULL;
|
||||||
|
|
||||||
/* Test and set connection state. */
|
/* Test and set connection state. */
|
||||||
conn_lock ();
|
conn_lock ();
|
||||||
|
@ -1679,28 +1692,10 @@ 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. */
|
||||||
RtlInitEmptyUnicodeString (&pipe_name, pipe_name_buf, sizeof pipe_name_buf);
|
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);
|
connect_state (unconnected);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1708,22 +1703,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_pipe (&pipe_name) < 0)
|
||||||
{
|
{
|
||||||
if (connect_pipe (&pipe_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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue