* 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:
Corinna Vinschen 2013-03-07 15:39:35 +00:00
parent b5545a7b7e
commit 8981489bec
3 changed files with 48 additions and 12 deletions

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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. */