* include/sys/un.h (UNIX_PATH_MAX): Rename from UNIX_PATH_LEN to
follow Linux. * fhandler_socket.cc: Change UNIX_PATH_LEN to UNIX_PATH_MAX throughout. (fhandler_socket::recv_internal): Don't return prematurely in case of successful return. For AF_LOCAL sockets, overwrite returned AF_INET name with AF_LOCAL name.
This commit is contained in:
parent
b5545a7b7e
commit
8981489bec
@ -1,3 +1,12 @@
|
||||
2013-03-07 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* include/sys/un.h (UNIX_PATH_MAX): Rename from UNIX_PATH_LEN to
|
||||
follow Linux.
|
||||
* fhandler_socket.cc: Change UNIX_PATH_LEN to UNIX_PATH_MAX throughout.
|
||||
(fhandler_socket::recv_internal): Don't return prematurely in case of
|
||||
successful return. For AF_LOCAL sockets, overwrite returned AF_INET
|
||||
name with AF_LOCAL name.
|
||||
|
||||
2013-03-07 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_socket.cc (fhandler_socket::bind): Fix check for AF_LOCAL
|
||||
|
@ -905,7 +905,7 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
|
||||
/* Check that name is within bounds. Don't check if the string is
|
||||
NUL-terminated, because there are projects out there which set
|
||||
namelen to a value which doesn't cover the trailing NUL. */
|
||||
if (len <= 1 || (len = strnlen (un_addr->sun_path, len)) > UNIX_PATH_LEN)
|
||||
if (len <= 1 || (len = strnlen (un_addr->sun_path, len)) > UNIX_PATH_MAX)
|
||||
{
|
||||
set_errno (len <= 1 ? (len == 1 ? ENOENT : EINVAL) : ENAMETOOLONG);
|
||||
goto out;
|
||||
@ -1253,7 +1253,7 @@ fhandler_socket::getsockname (struct sockaddr *name, int *namelen)
|
||||
sun.sun_family = AF_LOCAL;
|
||||
sun.sun_path[0] = '\0';
|
||||
if (get_sun_path ())
|
||||
strncat (sun.sun_path, get_sun_path (), UNIX_PATH_LEN - 1);
|
||||
strncat (sun.sun_path, get_sun_path (), UNIX_PATH_MAX - 1);
|
||||
memcpy (name, &sun, MIN (*namelen, (int) SUN_LEN (&sun) + 1));
|
||||
*namelen = (int) SUN_LEN (&sun) + (get_sun_path () ? 1 : 0);
|
||||
res = 0;
|
||||
@ -1327,7 +1327,7 @@ fhandler_socket::getpeername (struct sockaddr *name, int *namelen)
|
||||
sun.sun_family = AF_LOCAL;
|
||||
sun.sun_path[0] = '\0';
|
||||
if (get_peer_sun_path ())
|
||||
strncat (sun.sun_path, get_peer_sun_path (), UNIX_PATH_LEN - 1);
|
||||
strncat (sun.sun_path, get_peer_sun_path (), UNIX_PATH_MAX - 1);
|
||||
memcpy (name, &sun, MIN (*namelen, (int) SUN_LEN (&sun) + 1));
|
||||
*namelen = (int) SUN_LEN (&sun) + (get_peer_sun_path () ? 1 : 0);
|
||||
}
|
||||
@ -1387,6 +1387,7 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
LPWSABUF &wsabuf = wsamsg->lpBuffers;
|
||||
ULONG &wsacnt = wsamsg->dwBufferCount;
|
||||
static NO_COPY LPFN_WSARECVMSG WSARecvMsg;
|
||||
int orig_namelen = wsamsg->namelen;
|
||||
|
||||
DWORD wait_flags = wsamsg->dwFlags;
|
||||
bool waitall = !!(wait_flags & MSG_WAITALL);
|
||||
@ -1483,17 +1484,43 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg)
|
||||
/* According to SUSv3, errno isn't set in that case and no error
|
||||
condition is returned. */
|
||||
if (WSAGetLastError () == WSAEMSGSIZE)
|
||||
return ret + wret;
|
||||
|
||||
if (!ret)
|
||||
ret += wret;
|
||||
else if (!ret)
|
||||
{
|
||||
/* ESHUTDOWN isn't defined for recv in SUSv3. Simply EOF is returned
|
||||
in this case. */
|
||||
if (WSAGetLastError () == WSAESHUTDOWN)
|
||||
return 0;
|
||||
ret = 0;
|
||||
else
|
||||
{
|
||||
set_winsock_errno ();
|
||||
return SOCKET_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_winsock_errno ();
|
||||
return SOCKET_ERROR;
|
||||
if (get_addr_family () == AF_LOCAL && wsamsg->name != NULL
|
||||
&& orig_namelen >= (int) sizeof (sa_family_t))
|
||||
{
|
||||
/* WSARecvFrom copied the sockaddr_in block to wsamsg->name.
|
||||
We have to overwrite it with a sockaddr_un block. */
|
||||
sockaddr_un *un = (sockaddr_un *) wsamsg->name;
|
||||
un->sun_family = AF_LOCAL;
|
||||
int len = orig_namelen - offsetof (struct sockaddr_un, sun_path);
|
||||
if (len > 0)
|
||||
{
|
||||
if (!get_peer_sun_path ())
|
||||
wsamsg->namelen = sizeof (sa_family_t);
|
||||
else
|
||||
{
|
||||
memset (un->sun_path, 0, len);
|
||||
strncpy (un->sun_path, get_peer_sun_path (), len);
|
||||
if (un->sun_path[len - 1] == '\0')
|
||||
len = strlen (un->sun_path) + 1;
|
||||
if (len > UNIX_PATH_MAX)
|
||||
len = UNIX_PATH_MAX;
|
||||
wsamsg->namelen = offsetof (struct sockaddr_un, sun_path) + len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* sys/un.h
|
||||
|
||||
Copyright 1999, 2000, 2001, 2005, 2009 Red Hat, Inc.
|
||||
Copyright 1999, 2000, 2001, 2005, 2009, 2013 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
@ -15,11 +15,11 @@ details. */
|
||||
#include <cygwin/socket.h>
|
||||
|
||||
/* POSIX requires only at least 100 bytes */
|
||||
#define UNIX_PATH_LEN 108
|
||||
#define UNIX_PATH_MAX 108
|
||||
|
||||
struct sockaddr_un {
|
||||
sa_family_t sun_family; /* address family AF_LOCAL/AF_UNIX */
|
||||
char sun_path[UNIX_PATH_LEN]; /* 108 bytes of socket address */
|
||||
char sun_path[UNIX_PATH_MAX]; /* 108 bytes of socket address */
|
||||
};
|
||||
|
||||
/* Evaluates the actual length of `sockaddr_un' structure. */
|
||||
|
Loading…
Reference in New Issue
Block a user