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