* 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:
		| @@ -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. */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user