GCC 4.4 produces more warnings relating to type-punning:
http://gcc.gnu.org/gcc-4.4/porting_to.html
which now causes Classpath builds with -Werror to fail.
This patch fixes the issues by replacing the use of a shared
pointer for the IPv4 and IPv6 socket types with a union.
It's not ideal either, but fixes the typing of these pointers.
Ok for HEAD?
--
Andrew :)
Free Java Software Engineer
Red Hat, Inc. (http://www.redhat.com)
Support Free Java!
Contribute to GNU Classpath and the OpenJDK
http://www.gnu.org/software/classpath
http://openjdk.java.net
PGP Key: 94EFD9D8 (http://subkeys.pgp.net)
Fingerprint = F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8
Index: native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c
===================================================================
RCS file:
/sources/classpath/classpath/native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c,v
retrieving revision 1.16
diff -u -u -r1.16 gnu_java_net_VMPlainSocketImpl.c
--- native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c 28 Dec 2007
17:49:56 -0000 1.16
+++ native/jni/java-net/gnu_java_net_VMPlainSocketImpl.c 18 Jun 2009
19:44:42 -0000
@@ -399,7 +399,7 @@
return;
result = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF,
- (struct sockaddr *) cpaddr->data, cpaddr->len);
+ (struct sockaddr *) &(cpaddr->data.ipv4), cpaddr->len);
cpnet_freeAddress (env, cpaddr);
Index: native/jni/java-nio/gnu_java_nio_VMChannel.c
===================================================================
RCS file:
/sources/classpath/classpath/native/jni/java-nio/gnu_java_nio_VMChannel.c,v
retrieving revision 1.22
diff -u -u -r1.22 gnu_java_nio_VMChannel.c
--- native/jni/java-nio/gnu_java_nio_VMChannel.c 28 Dec 2007 17:49:56
-0000 1.22
+++ native/jni/java-nio/gnu_java_nio_VMChannel.c 18 Jun 2009 19:44:43
-0000
@@ -757,16 +757,15 @@
#ifdef HAVE_RECVFROM
char *addrPortPtr = (*env)->GetDirectBufferAddress (env, addrPort);
struct JCL_buffer buf;
+union sockets
+{
#ifdef HAVE_INET6
- struct sockaddr_in6 sock_storage;
- struct sockaddr_in6 *sock6;
- socklen_t slen = sizeof (struct sockaddr_in6);
-#else
- struct sockaddr_in sock_storage;
- socklen_t slen = sizeof (struct sockaddr_in);
+ struct sockaddr_in6 sock6;
#endif /* HAVE_INET6 */
- struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
- struct sockaddr_in *sock4;
+ struct sockaddr_in sock4;
+} sock_storage;
+
+ socklen_t slen = sizeof (union sockets);
int ret;
jint result = -1;
@@ -779,7 +778,7 @@
ret = cpnio_recvfrom (fd, &(buf.ptr[buf.position + buf.offset]),
buf.limit - buf.position, MSG_WAITALL,
- sockaddr, &slen);
+ (struct sockaddr *) &sock_storage, &slen);
if (-1 == ret)
{
@@ -801,19 +800,17 @@
return 0;
}
- if (sockaddr->sa_family == AF_INET)
+ if (sock_storage.sock4.sin_family == AF_INET)
{
- sock4 = (struct sockaddr_in *) sockaddr;
- memcpy (addrPortPtr, &(sock4->sin_addr.s_addr), 4);
- ;memcpy (addrPortPtr + 4, &(sock4->sin_port), 2);
+ memcpy (addrPortPtr, &(sock_storage.sock4.sin_addr.s_addr), 4);
+ ;memcpy (addrPortPtr + 4, &(sock_storage.sock4.sin_port), 2);
result = 4;
}
#ifdef HAVE_INET6
- else if (sockaddr->sa_family == AF_INET6)
+ else if (sock_storage.sock6.sin6_family == AF_INET6)
{
- sock6 = (struct sockaddr_in6 *) sockaddr;
- memcpy (addrPortPtr, &(sock6->sin6_addr.s6_addr), 16);
- memcpy (addrPortPtr + 16, &(sock6->sin6_port), 2);
+ memcpy (addrPortPtr, &(sock_storage.sock6.sin6_addr.s6_addr), 16);
+ memcpy (addrPortPtr + 16, &(sock_storage.sock6.sin6_port), 2);
result = 16;
}
#endif /* HAVE_INET6 */
@@ -1358,42 +1355,38 @@
jint fd, jobject name)
{
#ifdef HAVE_GETSOCKNAME
+union sockets
+{
#ifdef HAVE_INET6
- struct sockaddr_in6 *addr6;
- struct sockaddr_in6 sock_storage;
- socklen_t socklen = sizeof (struct sockaddr_in6);
-#else
- struct sockaddr_in sock_storage;
- socklen_t socklen = sizeof (struct sockaddr_in);
+ struct sockaddr_in6 ipv6;
#endif /* HAVE_INET6 */
+ struct sockaddr_in ipv4;
+} sock_storage;
- struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
- struct sockaddr_in *addr4;
+ socklen_t socklen = sizeof (union sockets);
int ret;
char *nameptr = (*env)->GetDirectBufferAddress (env, name);
- ret = getsockname (fd, sockaddr, &socklen);
+ ret = getsockname (fd, (struct sockaddr *) &sock_storage, &socklen);
if (ret == -1)
{
JCL_ThrowException (env, "java/net/SocketException", strerror (errno));
return 0;
}
- if (sockaddr->sa_family == AF_INET)
+ if (sock_storage.ipv4.sin_family == AF_INET)
{
- addr4 = (struct sockaddr_in *) sockaddr;
- memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
- memcpy (nameptr + 4, &(addr4->sin_port), 2);
+ memcpy (nameptr, &(sock_storage.ipv4.sin_addr.s_addr), 4);
+ memcpy (nameptr + 4, &(sock_storage.ipv4.sin_port), 2);
return 4;
}
#ifdef HAVE_INET6
/* IPv6 */
- if (sockaddr->sa_family == AF_INET6)
+ if (sock_storage.ipv6.sin6_family == AF_INET6)
{
- addr6 = (struct sockaddr_in6 *) sockaddr;
- memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
- memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+ memcpy (nameptr, &(sock_storage.ipv6.sin6_addr.s6_addr), 16);
+ memcpy (nameptr + 16, &(sock_storage.ipv6.sin6_port), 2);
return 16;
}
#endif /* HAVE_INET6 */
@@ -1418,21 +1411,19 @@
jint fd, jobject name)
{
#ifdef HAVE_GETPEERNAME
+union sockets
+{
#ifdef HAVE_INET6
- struct sockaddr_in6 *addr6;
- struct sockaddr_in6 sock_storage;
- socklen_t socklen = sizeof (struct sockaddr_in6);
-#else
- struct sockaddr_in sock_storage;
- socklen_t socklen = sizeof (struct sockaddr_in);
+ struct sockaddr_in6 ipv6;
#endif /* HAVE_INET6 */
+ struct sockaddr_in ipv4;
+} sock_storage;
- struct sockaddr *sockaddr = (struct sockaddr *) &sock_storage;
- struct sockaddr_in *addr4;
int ret;
char *nameptr = (*env)->GetDirectBufferAddress (env, name);
- ret = getpeername (fd, sockaddr, &socklen);
+ socklen_t size = sizeof (union sockets);
+ ret = getpeername (fd, (struct sockaddr *) &sock_storage, &size);
if (ret == -1)
{
if (ENOTCONN != errno)
@@ -1440,19 +1431,17 @@
return 0;
}
- if (sockaddr->sa_family == AF_INET)
+ if (sock_storage.ipv4.sin_family == AF_INET)
{
- addr4 = (struct sockaddr_in *) sockaddr;
- memcpy (nameptr, &(addr4->sin_addr.s_addr), 4);
- memcpy (nameptr + 4, &(addr4->sin_port), 2);
+ memcpy (nameptr, &(sock_storage.ipv4.sin_addr.s_addr), 4);
+ memcpy (nameptr + 4, &(sock_storage.ipv4.sin_port), 2);
return 4;
}
#ifdef HAVE_INET6
- else if (sockaddr->sa_family == AF_INET6)
+ else if (sock_storage.ipv6.sin6_family == AF_INET6)
{
- addr6 = (struct sockaddr_in6 *) sockaddr;
- memcpy (nameptr, &(addr6->sin6_addr.s6_addr), 16);
- memcpy (nameptr + 16, &(addr6->sin6_port), 2);
+ memcpy (nameptr, &(sock_storage.ipv6.sin6_addr.s6_addr), 16);
+ memcpy (nameptr + 16, &(sock_storage.ipv6.sin6_port), 2);
return 16;
}
#endif /* HAVE_INET6 */
Index: native/jni/native-lib/cpnet.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/native-lib/cpnet.c,v
retrieving revision 1.10
diff -u -u -r1.10 cpnet.c
--- native/jni/native-lib/cpnet.c 25 Jun 2007 09:44:36 -0000 1.10
+++ native/jni/native-lib/cpnet.c 18 Jun 2009 19:44:44 -0000
@@ -1,5 +1,5 @@
/* cpnet.c -
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -176,7 +176,7 @@
{
int ret;
- ret = bind(fd, (struct sockaddr *)addr->data, addr->len);
+ ret = bind(fd, (struct sockaddr *) &(addr->data.ipv4), addr->len);
if (ret != 0)
return errno;
@@ -188,7 +188,7 @@
int ret;
/* TODO: implement socket time out */
- ret = connect(fd, (struct sockaddr *)addr->data, addr->len);
+ ret = connect(fd, (struct sockaddr *) &(addr->data.ipv4), addr->len);
if (ret != 0)
return errno;
@@ -203,7 +203,7 @@
*addr = JCL_malloc(env, slen);
slen -= sizeof(jint);
- ret = getsockname(fd, (struct sockaddr *)(*addr)->data, &slen );
+ ret = getsockname(fd, (struct sockaddr *) &((*addr)->data.ipv4), &slen );
if (ret != 0)
{
int err = errno;
@@ -224,7 +224,7 @@
*addr = JCL_malloc(env, slen);
slen -= sizeof(jint);
- ret = getpeername(fd, (struct sockaddr *)(*addr)->data, &slen );
+ ret = getpeername(fd, (struct sockaddr *) &((*addr)->data.ipv4), &slen );
if (ret != 0)
{
int err = errno;
@@ -291,20 +291,20 @@
return ETIMEDOUT;
#if defined (HAVE_MSG_NOSIGNAL)
- ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *)addr->data,
+ ret = sendto(fd, data, len, MSG_NOSIGNAL, (struct sockaddr *)
&(addr->data.ipv4),
addr->len);
#elif defined (HAVE_SO_NOSIGPIPE)
ret = setsockopt_NOSIGPIPE(fd);
if (ret == 0)
{
- ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
+ ret = sendto(fd, data, len, 0, addr->data.ipv4,
addr->len);
}
#else
/* We want SIGPIPE to be omitted. But this configuration does not have an
* option for that.
*/
- ret = sendto(fd, data, len, 0, (struct sockaddr *)addr->data,
+ ret = sendto(fd, data, len, 0, addr->data.ipv4,
addr->len);
#endif
@@ -342,7 +342,7 @@
*addr = JCL_malloc(env, slen);
slen -= sizeof(jint);
- ret = recvfrom(fd, data, len, 0, (struct sockaddr *) (*addr)->data, &slen);
+ ret = recvfrom(fd, data, len, 0, (struct sockaddr *) &((*addr)->data.ipv4),
&slen);
if (ret < 0)
{
int err = errno;
@@ -504,7 +504,7 @@
{
int ret;
- ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr
*)addr->data, addr->len);
+ ret = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &(addr->data.ipv4),
addr->len);
if (ret != 0)
return errno;
@@ -519,7 +519,7 @@
*addr = JCL_malloc(env, slen);
slen -= sizeof(jint);
- ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, (struct sockaddr
*)(*addr)->data, &slen);
+ ret = getsockopt(fd, IPPROTO_IP, IP_MULTICAST_IF, &((*addr)->data.ipv4),
&slen);
(*addr)->len = slen;
if (ret != 0)
@@ -580,7 +580,7 @@
int ret;
memset(&req, 0, sizeof(req));
- req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+ req.imr_multiaddr = addr->data.ipv4.sin_addr;
req.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &req, sizeof(req));
if (ret != 0)
@@ -595,7 +595,7 @@
int ret;
memset(&req, 0, sizeof(req));
- req.imr_multiaddr = ((struct sockaddr_in *)addr->data)->sin_addr;
+ req.imr_multiaddr = addr->data.ipv4.sin_addr;
req.imr_interface.s_addr = INADDR_ANY;
ret = setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, &req, sizeof(req));
if (ret != 0)
@@ -715,31 +715,23 @@
jint cpnet_getHostByAddr (JNIEnv *env UNUSED, cpnet_address *addr, char
*hostname, jint hostname_len)
{
- union
- {
- struct sockaddr_in *addr_v4;
- struct sockaddr_in6 *addr_v6;
- char *data;
- } haddr;
void *raw_addr;
int addr_type;
struct hostent *ret;
int addr_len;
- haddr.data = addr->data;
-
- if (haddr.addr_v4->sin_family == AF_INET)
+ if (addr->data.ipv4.sin_family == AF_INET)
{
- raw_addr = &haddr.addr_v4->sin_addr;
- addr_len = sizeof(haddr.addr_v4->sin_addr);
+ raw_addr = &addr->data.ipv4.sin_addr;
+ addr_len = sizeof(addr->data.ipv4.sin_addr);
addr_type = AF_INET;
}
#ifdef HAVE_INET6
- else if (haddr.addr_v6->sin6_family == AF_INET6)
+ else if (addr->data.ipv6.sin6_family == AF_INET6)
{
- raw_addr = &haddr.addr_v6->sin6_addr;
+ raw_addr = &addr->data.ipv6.sin6_addr;
addr_type = AF_INET6;
- addr_len = sizeof(haddr.addr_v6->sin6_addr);
+ addr_len = sizeof(addr->data.ipv6.sin6_addr);
}
#endif
else
Index: native/jni/native-lib/cpnet.h
===================================================================
RCS file: /sources/classpath/classpath/native/jni/native-lib/cpnet.h,v
retrieving revision 1.6
diff -u -u -r1.6 cpnet.h
--- native/jni/native-lib/cpnet.h 28 Dec 2007 17:49:56 -0000 1.6
+++ native/jni/native-lib/cpnet.h 18 Jun 2009 19:44:44 -0000
@@ -1,5 +1,5 @@
/* cpnet.h -
- Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -52,9 +52,14 @@
#include <netinet/ip.h>
#endif /* HAVE_NETINET_IP_H */
-typedef struct {
+typedef struct
+{
jint len;
- char data[1];
+ union
+ {
+ struct sockaddr_in ipv4;
+ struct sockaddr_in6 ipv6;
+ } data;
} cpnet_address;
#define CPNET_SHUTDOWN_READ 1
@@ -105,8 +110,8 @@
static inline cpnet_address *cpnet_newIPV4Address(JNIEnv * env)
{
- cpnet_address *addr = (cpnet_address *)JCL_malloc(env, sizeof(cpnet_address)
+ sizeof(struct sockaddr_in));
- struct sockaddr_in *netaddr = (struct sockaddr_in *)&(addr->data[0]);
+ cpnet_address *addr = (cpnet_address *)JCL_malloc(env,
sizeof(cpnet_address));
+ struct sockaddr_in *netaddr = &(addr->data.ipv4);
addr->len = sizeof(struct sockaddr_in);
memset(netaddr, 0, addr->len);
@@ -116,7 +121,7 @@
static inline void cpnet_setIPV4Any(cpnet_address *addr)
{
- struct sockaddr_in *netaddr = (struct sockaddr_in *)&(addr->data[0]);
+ struct sockaddr_in *netaddr = &(addr->data.ipv4);
netaddr->sin_addr.s_addr = INADDR_ANY;
}
@@ -124,8 +129,8 @@
#ifdef HAVE_INET6
static inline cpnet_address *cpnet_newIPV6Address(JNIEnv * env)
{
- cpnet_address * addr = (cpnet_address *)JCL_malloc(env,
sizeof(cpnet_address) + sizeof(struct sockaddr_in6));
- struct sockaddr_in6 *netaddr = (struct sockaddr_in6 *)&(addr->data[0]);
+ cpnet_address * addr = (cpnet_address *)JCL_malloc(env,
sizeof(cpnet_address));
+ struct sockaddr_in6 *netaddr = &(addr->data.ipv6);
addr->len = sizeof(struct sockaddr_in6);
memset(netaddr, 0, addr->len);
@@ -142,14 +147,14 @@
static inline void cpnet_addressSetPort(cpnet_address *addr, jint port)
{
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+ struct sockaddr_in *ipaddr = &(addr->data.ipv4);
ipaddr->sin_port = htons(port);
}
static inline jint cpnet_addressGetPort(cpnet_address *addr)
{
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+ struct sockaddr_in *ipaddr = &(addr->data.ipv4);
return ntohs(ipaddr->sin_port);
}
@@ -159,13 +164,13 @@
if (addr1->len != addr2->len)
return JNI_FALSE;
- return memcmp(addr1->data, addr2->data, addr1->len) == 0;
+ return memcmp(&addr1->data, &addr2->data, addr1->len) == 0;
}
#ifdef HAVE_INET6
static inline jboolean cpnet_isIPV6Address(cpnet_address *addr)
{
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+ struct sockaddr_in *ipaddr = &(addr->data.ipv4);
return ipaddr->sin_family == AF_INET6;
}
@@ -173,14 +178,14 @@
static inline jboolean cpnet_isIPV4Address(cpnet_address *addr)
{
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(addr->data[0]);
+ struct sockaddr_in *ipaddr = &(addr->data.ipv4);
return ipaddr->sin_family == AF_INET;
}
static inline void cpnet_IPV4AddressToBytes(cpnet_address *netaddr, jbyte
*octets)
{
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(netaddr->data[0]);
+ struct sockaddr_in *ipaddr = &(netaddr->data.ipv4);
unsigned long sysaddr = ntohl(ipaddr->sin_addr.s_addr);
octets[0] = ((sysaddr >> 24) & 0xff);
@@ -192,7 +197,7 @@
static inline void cpnet_bytesToIPV4Address(cpnet_address *netaddr, jbyte
*octets)
{
jint sysaddr;
- struct sockaddr_in *ipaddr = (struct sockaddr_in *)&(netaddr->data[0]);
+ struct sockaddr_in *ipaddr = &(netaddr->data.ipv4);
sysaddr = ((jint)(unsigned char)octets[0]) << 24;
sysaddr |= ((jint)(unsigned char)octets[1]) << 16;
@@ -205,14 +210,14 @@
#ifdef HAVE_INET6
static inline void cpnet_IPV6AddressToBytes(cpnet_address *netaddr, jbyte
*octets)
{
- struct sockaddr_in6 *ipaddr = (struct sockaddr_in6 *)&(netaddr->data[0]);
+ struct sockaddr_in6 *ipaddr = &(netaddr->data.ipv6);
memcpy(octets, &ipaddr->sin6_addr, 16);
}
static inline void cpnet_bytesToIPV6Address(cpnet_address *netaddr, jbyte
*octets)
{
- struct sockaddr_in6 *ipaddr = (struct sockaddr_in6 *)&(netaddr->data[0]);
+ struct sockaddr_in6 *ipaddr = &(netaddr->data.ipv6);
memcpy(&ipaddr->sin6_addr, octets, 16);
}